Bug 1889822 - creating file base backing store does not create sparse files when requested
Summary: creating file base backing store does not create sparse files when requested
Keywords:
Status: ON_QA
Alias: None
Product: Red Hat Enterprise Linux 8
Classification: Red Hat
Component: targetcli
Version: 8.2
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: rc
: 8.0
Assignee: Maurizio Lombardi
QA Contact: Filip Suba
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2020-10-20 16:26 UTC by Ken Green
Modified: 2020-12-01 16:17 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed:
Type: Bug
Target Upstream Version:


Attachments (Terms of Use)

Description Ken Green 2020-10-20 16:26:18 UTC
Description of problem: When you use targetcli to create a backing store file the default behaviour is supposed to be to create sparse files and this what used to happen at RHEL7. The version of targetcli supplied with RHEL8 calls fallocate to make the file, but this does not make sparse files. On XFS and ext4 fallocate allocates to the space to the file without writing to it. I tried to see what happens with ext3 and there is seems to write zeros out, at least it took a long enough time to have done so.


Version-Release number of selected component (if applicable):
2.1.51-1.el8
[root@fs1 ~]# rpm -qa "targetcli*"
targetcli-2.1.51-1.el8.noarch
[root@fs1 ~]#


How reproducible:
Always

Steps to Reproduce:
1. make a directory with at least 16GB of free space (or change the numbers in the command)
2. targetcli <<< "/backstores/fileio create test1 /iscsi/test1 16G write_back=false sparse=true"
3. check the size of the file /iscsi/test1

Actual results:

[root@fs1 ~]#
[root@fs1 ~]# targetcli <<< "/backstores/fileio create test1 /iscsi/test1 16G write_back=false sparse=true"
targetcli shell version 2.1.51
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.

/backstores/fileio> Created fileio test1 with size 17179869184
/backstores/fileio> exit
Global pref auto_save_on_exit=true
Configuration saved to /etc/target/saveconfig.json
[root@fs1 ~]#
[root@fs1 ~]# ls -ls /iscsi/test1
16777216 -rw-r--r--. 1 root root 17179869184 Oct 20 12:09 /iscsi/test1
[root@fs1 ~]#
[root@fs1 ~]#
[root@fs1 ~]# du -h /iscsi/test1
16G     /iscsi/test1



Expected results:

The size of the file should be zero

On a 7 system 

[root@microg82 ~]#
[root@microg82 ~]# targetcli <<< "/backstores/fileio create test1 /iscsi/test1 16G write_back=false sparse=true"
Warning: Could not load preferences file /root/.targetcli/prefs.bin.
targetcli shell version 2.1.fb49
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.

/> Created fileio test1 with size 17179869184
/> exit
Global pref auto_save_on_exit=true
Configuration saved to /etc/target/saveconfig.json
[root@microg82 ~]# ls -ls /iscsi/
total 0
0 -rw-r--r--. 1 root root 17179869184 Oct 20 17:20 test1
[root@microg82 ~]#
[root@microg82 ~]#



Additional info:

I checked on https://github.com/open-iscsi/targetcli-fb/search?q=sparse and looked at the code, while I'm not a python programmer it's easy enough to read that it is calling fallocate 

if sparse:
                try:
                    os.posix_fallocate(f.fileno(), 0, size)

but fallocate doesn't make sparse files.

Comment 1 Maurizio Lombardi 2020-10-21 07:59:38 UTC
Thanks for reporting this bug.

I gave the code a quick look and I think this has been introduced by an old targetcli patch merged in 2013 (id 3bd4d8ef7c9b154c53e8b8dd863a570bce7f5c2c)

The commit message reads:

    Fix issue #23: use fallocate() to create fileio backstores
    
    Python 3.3 provides the fallocate() system call which is better for
    allocating disk space than ftruncate(). ftruncate() sets the file size
    to the requested size but does not reserve the blocks in the file
    system. Unlike ftruncate(), fallocate() fails if there is not enough
    free space.

             if sparse:
-                os.ftruncate(f.fileno(), size)
+                try:
+                    os.posix_fallocate(f.fileno(), 0, size)
+                except AttributeError:
+                    # Prior to version 3.3, Python does not provide fallocate
+                    os.ftruncate(f.fileno(), size)

This explains why it works correctly on RHEL7:
RHEL7 ships with Python2, so it doesn't call fallocate() and falls back to ftruncate().

Comment 2 Ken Green 2020-10-21 12:30:28 UTC
Thanks for that Maurizio

The work around from the shell is easy enough, just use dd to make a sparse file and the Linux dd allows a count=0.

[root@m10vm3 ~]#
[root@m10vm3 ~]# mkdir /iscsi
[root@m10vm3 ~]# dd if=/dev/zero of=/iscsi/test1 bs=1024k seek=16384 count=0
0+0 records in
0+0 records out
0 bytes copied, 0.000141885 s, 0.0 kB/s
[root@m10vm3 ~]# targetcli <<< "/backstores/fileio create test1 /iscsi/test1 16G write_back=false sparse=true"
targetcli shell version 2.1.51
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.

/> /iscsi/test1 exists, using its size (17179869184 bytes) instead
Created fileio test1 with size 17179869184
/> exit
Global pref auto_save_on_exit=true
Last 10 configs saved in /etc/target/backup/.
Configuration saved to /etc/target/saveconfig.json
[root@m10vm3 ~]#
[root@m10vm3 ~]# ls -ls /iscsi/test1
0 -rw-r--r--. 1 root root 17179869184 Oct 21 13:11 /iscsi/test1
[root@m10vm3 ~]#


The solution fallocate would be great for the non-sparse case. It looks like the script is writing billions of NULLs in a rather inefficient way. Besides the underlying storage probably can't do anything like thin provision it.

Cheers
Ken

Comment 3 Lynn Dixon 2020-11-12 07:22:01 UTC
This bug bit me too.  I have always used fallocate to create sparse files for fileio backstores.  Where I wanted to allocate the blocks, but not consume any space until the blocks were actually used.  I could easily do this in RHEL7, but when I upgraded to RHEL8 I found I couldnt create sparse files anymore. 

I had to use the dd trick mentioned in https://bugzilla.redhat.com/show_bug.cgi?id=1889822#c2

Comment 4 Maurizio Lombardi 2020-11-13 10:47:20 UTC
I submitted a pull request to targetcli upstream

https://github.com/open-iscsi/targetcli-fb/pull/177


Note You need to log in before you can comment on or make changes to this bug.