Bug 7150 - Samba returns dfree info for wrong device
Summary: Samba returns dfree info for wrong device
Status: RESOLVED WONTFIX
Alias: None
Product: Samba 3.4
Classification: Unclassified
Component: File services (show other bugs)
Version: 3.4.4
Hardware: x86 Windows XP
: P3 normal
Target Milestone: ---
Assignee: Guenther Deschner
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-02-18 04:39 UTC by Mathijs Brands
Modified: 2010-02-28 08:05 UTC (History)
0 users

See Also:


Attachments
Test program that shows device for all mounted file systems (539 bytes, application/octet-stream)
2010-02-18 04:41 UTC, Mathijs Brands
no flags Details
Test program with the sys_path_to_bdev from the Samba source (1.51 KB, application/octet-stream)
2010-02-18 04:42 UTC, Mathijs Brands
no flags Details
Work-around that works for us (879 bytes, patch)
2010-02-18 05:04 UTC, Mathijs Brands
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mathijs Brands 2010-02-18 04:39:59 UTC
On our Red Hat 5.4 servers, Samba often returns disk-free info for devices other than what a user is requesting it for.

This seems to be caused by the assumption that a device is uniquely identifying. With NFS shares, at least on RHEL 5, this is not the case.

Starting with line 63 in source3/lib/sysquotas.c we have the following:

        if ( sys_stat(path, &S) == -1 )
                return (-1);

        devno = S.st_dev ;

        fp = setmntent(MOUNTED,"r");
        if (fp == NULL) {
                return -1;
        }

        while ((mnt = getmntent(fp))) {
                if ( sys_stat(mnt->mnt_dir,&S) == -1 )
                        continue ;

                if (S.st_dev == devno) {
                        (*mntpath) = SMB_STRDUP(mnt->mnt_dir);
                        (*bdev) = SMB_STRDUP(mnt->mnt_fsname);
                        (*fs)   = SMB_STRDUP(mnt->mnt_type);

First, a stat call is executed for the path (normally '.'). The code then loops through all mounted file systems (executing a stat call on them) looking for a file system which has the same device as the path statted earlier.

Since the device is not unique, there is a chance this routine returns mntpath/bdev/fs data for the wrong mount.

Below is the output of a small test program which shows a list of file systems with the same device:

[root@inv0107 ~]# /home/nxp21031/test.pl
0 - /sys
3 - /proc
11 - /dev/pts
17 - /dev/shm
18 - /proc/sys/fs/binfmt_misc
22 - /var/lib/nfs/rpc_pipefs
23 - /home/cdspip_workareas
24 - /home/gbr02444, /home/nlv06125, /home/nlv07939, /home/nlv08101, /home/nlv09275
25 - /home/nlv04455, /home/nlv07734, /home/nlv07749, /home/nlv07758, /home/nlv07785, /home/nlv14969, /home/nlv18676
26 - /home/beq03355, /home/dep08656, /home/nlv03675, /home/nlv03832, /home/nlv07317, /home/nlv07782, /home/nlv08789, /home/nlv11908, /home/nlv17216, /home/nxp09456
27 - /home/dep08620, /home/gbr02432, /home/nlv04130, /home/nlv06623, /home/nlv07776, /home/nlv07807, /home/nlv07836, /home/nlv14900, /home/nlv14944, /home/nxp09555, /home/nxp21031, /home/nxp25299
28 - /home/dep05228, /home/gbr02242, /home/nlv04120, /home/nlv04830, /home/nlv06090, /home/nlv07779, /home/nlv07824, /home/nlv08034, /home/nlv08131, /home/nlv08346, /home/nlv08964, /home/nlv14963, /home/nlv15815, /home/nlv20797
29 - /home/cdspip_cache
30 - /home/iosrc
31 - /home/keylink_scratch
32 - /home/hvsoilib
33 - /sysmnt/mail
34 - /home/cadmos34
35 - /home/hazelgrove
37 - /home/keylink
39 - /home/nlv05904, /home/nlv07031, /home/nlv07825, /home/nlv08120, /home/nlv08318, /home/nxp16612
44 - /sysmnt/cadappl_sde
47 - /home/audiopwr, /home/fagroup
51 - /home/ntas
51713 - /boot
64768 - /
64769 - /var
64770 - /mnt/spool, /tmp

I have tested this with Samba 3.0.8, 3.3.8 and 3.4.4 - all contain the same code and have the same issue.
Comment 1 Mathijs Brands 2010-02-18 04:41:17 UTC
Created attachment 5375 [details]
Test program that shows device for all mounted file systems
Comment 2 Mathijs Brands 2010-02-18 04:42:32 UTC
Created attachment 5376 [details]
Test program with the sys_path_to_bdev from the Samba source

Output:

[root@inv0107 ~]# /home/nxp21031/test /home/nxp21031
st_dev = 27 (/home/nxp21031)
--------------
st_dev = 64768 (/)
st_dev = 3 (/proc)
st_dev = 0 (/sys)
st_dev = 11 (/dev/pts)
st_dev = 64769 (/var)
st_dev = 64770 (/mnt/spool)
st_dev = 51713 (/boot)
st_dev = 17 (/dev/shm)
st_dev = 64770 (/tmp)
st_dev = 18 (/proc/sys/fs/binfmt_misc)
st_dev = 22 (/var/lib/nfs/rpc_pipefs)
st_dev = 24 (/home/nlv07939)
st_dev = 39 (/home/nlv05904)
st_dev = 28 (/home/nlv08034)
st_dev = 26 (/home/dep08656)
st_dev = 27 (/home/nlv04130)
Result: 0
mntpath: /home/nlv04130
bdev: nlnafvnxp34:/vol/fc_nxp34_b_us01/nxp01/nlv04130
fs: nfs
Comment 3 Mathijs Brands 2010-02-18 05:04:39 UTC
Created attachment 5377 [details]
Work-around that works for us

nxp21031@inv0107.nxdi.nl-cdc01$ ./test2 .
st_dev = 23 (.)
--------------
st_dev = 64768 (/)
st_dev = 3 (/proc)
st_dev = 0 (/sys)
st_dev = 11 (/dev/pts)
st_dev = 64769 (/var)
st_dev = 64770 (/mnt/spool)
st_dev = 51713 (/boot)
st_dev = 17 (/dev/shm)
st_dev = 64770 (/tmp)
st_dev = 18 (/proc/sys/fs/binfmt_misc)
st_dev = 22 (/var/lib/nfs/rpc_pipefs)
st_dev = 24 (/home/nlv07939)
st_dev = 30 (/home/iosrc)
st_dev = 25 (/home/beq03399)
st_dev = 39 (/home/dep08691)
st_dev = 26 (/home/beq03355)
st_dev = 29 (/home/keylink)
st_dev = 28 (/home/nlv08034)
st_dev = 39 (/home/nlv19952)
st_dev = 23 (/home/nlv04130)
st_dev = 23 (/home/nlv07776)
st_dev = 23 (/home/nlv07807)
st_dev = 23 (/home/nlv05948)
st_dev = 25 (/home/nlv08193)
st_dev = 26 (/home/nlv03832)
st_dev = 37 (/home/amsnip_cache)
st_dev = 39 (/home/nlv07748)
st_dev = 28 (/home/nlv07762)
st_dev = 23 (/home/nlv07657)
st_dev = 27 (/home/ntas)
st_dev = 24 (/home/nlv08101)
st_dev = 39 (/home/nlv05904)
st_dev = 28 (/home/nlv07779)
st_dev = 23 (/home/nlv14944)
st_dev = 25 (/home/nlv04156)
st_dev = 39 (/home/nlv06099)
st_dev = 24 (/home/nlv16740)
st_dev = 26 (/home/nlv07317)
st_dev = 23 (/home/nlv07836)
st_dev = 39 (/home/nxp09459)
st_dev = 24 (/home/nxp26812)
st_dev = 39 (/home/nlv06088)
st_dev = 28 (/home/nlv08955)
st_dev = 23 (/home/nlv07805)
st_dev = 26 (/home/nlv07016)
st_dev = 40 (/home/hazelgrove)
st_dev = 23 (/home/gbr01944)
st_dev = 26 (/home/dep08656)
st_dev = 28 (/home/dep05228)
st_dev = 23 (/home/nlv06623)
st_dev = 28 (/home/nlv04830)
st_dev = 23 (/home/gbr03948)
st_dev = 25 (/home/nlv07777)
st_dev = 28 (/home/gbr02242)
st_dev = 23 (/home/nxp25299)
st_dev = 25 (/home/nlv07758)
st_dev = 39 (/home/nlv04796)
st_dev = 25 (/home/nlv08932)
st_dev = 39 (/home/dep08637)
st_dev = 39 (/home/nlv07991)
st_dev = 28 (/home/nlv20797)
st_dev = 23 (/home/nlv07349)
st_dev = 39 (/home/nlv07825)
st_dev = 39 (/home/nlv05901)
st_dev = 44 (/home/devicephysics)
st_dev = 28 (/home/nlv03935)
st_dev = 25 (/home/nlv18676)
st_dev = 26 (/home/nlv08789)
st_dev = 23 (/home/nlv08127)
st_dev = 23 (/home/nxp21031)
Result: 0
mntpath: /home/nxp21031
bdev: nlnafvnxp34:/vol/fc_nxp34_b_us01/nxp01/nxp21031
fs: nfs
nxp21031@inv0107.nxdi.nl-cdc01$ pwd
/home/nxp21031
Comment 4 Jeremy Allison 2010-02-18 14:24:47 UTC
This seems to me to be a broken system. Samba *depends* on dev_t/inode pairs being unique for most of our functionality.

I don't think this is a Samba bug, but an NFS server one.

Re-assigning to Guenther for Red Hat avaluation.

Jeremy.
Comment 5 Volker Lendecke 2010-02-18 14:28:56 UTC
I would say that's exactly the situation we have the "dfree command" parameter for.

Volker
Comment 6 Jeremy Allison 2010-02-18 14:32:10 UTC
Yeah, but I think RH still needs to fix this with the NFS server. Non-unique dev/ino pairs will break all file serving functionality of Samba. User is just lucks so far that they haven't completely corrupted files :-).

Jeremy.
Comment 7 Volker Lendecke 2010-02-18 14:34:47 UTC
I would guess that inodes are unique. I think the NFS server just passes through what it sees on disk.

Volker
Comment 8 Mathijs Brands 2010-02-22 04:32:03 UTC
https://now.netapp.com/Knowledgebase/solutionarea.asp?id=kb9120

"An inode is a data structure that defines a file, except for the filename which is stored in the directory entry. Note that a directory is just another file. The inode number is an integer unique to the volume upon which it is stored. Inodes point to blocks that make up a file, and inodes also contain the metadata of the file."

So: The inode number is an integer unique to the -volume- upon which it is stored.

As far as I can tell, only NFS mounts on the -same- volume seem to have the same dev_t on RHEL 5. So the combination of dev_t:ino_t would be uniquely identifying for a file (at least for files on the same physical filer).
Comment 9 Mathijs Brands 2010-02-25 06:14:04 UTC
RHEL 4 seems to allocate devices more or less sequentially.

nxp21031@inv0107$ cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 5.2 (Tikanga)
nxp21031@inv0107$ ls /home/nxp21031/.bashrc /home/nxp25299/.bashrc
ls: /home/nxp25299/.bashrc: Permission denied
/home/nxp21031/.bashrc
nxp21031@inv0107$ ./test.pl|egrep '(nxp21031|nxp25299)'
27 - /home/atp01670, /home/dep08635, /home/gbr02432, /home/nlv04130, /home/nlv05948, /home/nlv05950, /home/nlv06565, /home/nlv06623, /home/nlv06869, /home/nlv07657, /home/nlv07711, /home/nlv07776, /home/nlv07786, /home/nlv07805, /home/nlv07836, /home/nlv08335, /home/nlv14944, /home/nxp21031, /home/nxp25299

nxp21031@acc3001$ cat /etc/redhat-release 
Red Hat Enterprise Linux AS release 4 (Nahant Update 6)
nxp21031@acc3001$ ls /home/nxp21031/.bashrc /home/nxp25299/.bashrc
ls: /home/nxp25299/.bashrc: Permission denied
/home/nxp21031/.bashrc
nxp21031@acc3001$ ./test.pl|egrep '(nxp21031|nxp25299)'
24 - /home/nxp21031
30 - /home/nxp25299

test.pl is the script attached to this bug report.
Comment 10 Volker Lendecke 2010-02-28 08:05:33 UTC
Please use the "dfree command" (possibly together with "dfree cache time") workaround to hook into the query. This operation is pretty frequent, and to be fast for the normal case with statfs info being correct per device number, we don't want to fall back to string handling here. As we have a workaround for your situation already in place, closing this bug as "wontfix".

Volker