clewis@eci386.uucp (Chris Lewis) (02/23/90)
For those of you who've expressed some interest in detecting RFS/NFS files, I got a couple of leads by mail, plus I've discovered a few things on my own, plus I have some testcode if you're interested.... This was from Larry Wall: > I don't know that it's documented either, but everywhere I've looked the > dev of NFS is negative (treating it as a signed value). This includes > Vaxen, Suns, Masscomps and Pyramids. I suspect that anyone that uses > Sun's code will end up doing this, unless they've already reserved > negative devices for some other purpose. > If we make enough programs that rely on it, they might make it a standard. :-) > I have no idea about RFS. > Larry Wall > lwall@jpl-devvax.jpl.nasa.gov Thank you Larry! This was sort of what I expected. I also discovered on System VR3 (386/ix 1.0.6 specifically) and AIX that in /usr/include/sys/sysmacros.h (which is where major() and minor() is defined on System Vish systems), has some wierdishness that may imply similar functionality. On 386/ix major() returns a unsigned int that has bit 8 very carefully masked off: #define major(x) (int)((unsigned)((x)>>8)&0x7F) (older code (eg: SCO pre-286 days) had 0xFF) On AIX, they don't do the masking, but they define a "bmajor()" that does. (on 386/ix, bmajor and major are the same). On the system running AIX I've had access to, the following was true for files/directories on networked file systems: major(stb.st_dev) != bmajor(stb.st_dev) I have no access to a SVR3 with RFS actually running, but I suspect that the upper bit would be turned on. On HP9000, dev_t is a long, but they only use 8 bits for minor, and I believe 6 bits for major, and there are other bits that are set for NFS files. On HP9000, bmajor is defined, and I paraphrase: #define bmajor(x) major(x) /* Unsure of AT&T's intentions here, bmajor masked off bits in porting base */ I betcha that the following would be fairly universal without having to resort to individual #ifdef's for each variant of UNIX: if (makedev(major(stb.st_dev),minor(stb.st_dev)) != stb.st_dev) { aha - NFS/RFS file! } else { local disk file } Anywho, could I get a few people to try the following C program on their systems that have NFS and/or RFS partitions mounted on them and mail the results to me? This is what you would have to do: - unshar this file. - undef USG if you aren't a UNIX System V variant (if you get major or minor undefined messages from cc, you probably need to define USG) - compile the program ala: cc -o teststat teststat.c - Find the names of a couple of files on your local disks, plus a few of them on filesystems mounted from other systems, and run teststat with these file names as arguments. Eg: ./teststat / /etc <filename on NFS> To make the results perfectly clear, could you also include your teststat command line and the output of df from your system? Thank you very much #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 1)." # Contents: teststat.c # Wrapped by clewis@eci386 on Thu Feb 22 17:19:16 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'teststat.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'teststat.c'\" else echo shar: Extracting \"'teststat.c'\" \(685 characters\) sed "s/^X//" >'teststat.c' <<'END_OF_FILE' X/* %I% %E% */ X#define USG /* undef if you aren't some sort of System V */ X#include <stdio.h> X X#include <sys/types.h> X#include <sys/stat.h> X#ifdef USG X#include <sys/sysmacros.h> X#endif X Xstruct stat stb; X Xmain(argc, argv, envp) Xint argc; Xchar **argv; Xchar **envp; { Xint i = 1; X for (;argv[i]; i++) { X if (stat(argv[i], &stb) == 0) { X printf("file: %s dev: %x major: %x minor: %x\n", argv[i], X stb.st_dev, major(stb.st_dev), minor(stb.st_dev)); X if (makedev(major(stb.st_dev),minor(stb.st_dev)) != stb.st_dev) X printf("I think %s is a networked file\n", argv[i]); X else X printf("I don't think %s is a networked file\n", argv[i]); X } else X perror(argv[i]); X } X} END_OF_FILE if test 685 -ne `wc -c <'teststat.c'`; then echo shar: \"'teststat.c'\" unpacked with wrong size! fi # end of 'teststat.c' fi exit 0 -- Chris Lewis, Elegant Communications Inc, {uunet!attcan,utzoo}!lsuc!eci386!clewis Ferret mailing list: eci386!ferret-list, psroff mailing list: eci386!psroff-list
tchrist@convex.COM (Tom Christiansen) (02/23/90)
The teststat program fails to identify NFS files on Convex systems. Here's the output from a C120 OS7.1: % teststat.v7 / /usr /usr/spool/globdata/aliases/tacunix file: / dev: 500 major: 5 minor: 0 I don't think / is a networked file file: /usr dev: 702 major: 7 minor: 2 I don't think /usr is a networked file file: /usr/spool/globdata/aliases/tacunix dev: ffffff02 major: ff minor: 2 I don't think /usr/spool/globdata/aliases/tacunix is a networked file % df / /usr /usr/spool/globdata/aliases/tacunix Filesystem kbytes used avail capacity Mounted on /dev/da0a 18067 15638 622 96% / /dev/st2 244047 190252 29390 87% /usr globhost:/usr/spool/globdata 315263 232782 50954 82% /rmt/globhost/globdata And here's the output from a C220 OS8.0, where major is defined this way: #define major(x) ((int)( ( (unsigned)(x) >> 20 ) & 0xfffff) ) % teststat.v8 / /usr /usr/spool/globdata/aliases/tacunix file: / dev: 4000001 major: 40 minor: 1 I don't think / is a networked file file: /usr dev: 1c00004 major: 1c minor: 4 I don't think /usr is a networked file file: /usr/spool/globdata/aliases/tacunix dev: ff00000 major: ff minor: 0 I don't think /usr/spool/globdata/aliases/tacunix is a networked file % df / /usr /usr/spool/globdata/aliases/tacunix Filesystem kbytes used avail capacity Mounted on /dev/du0a 45978 19298 22082 47% / /dev/dd0e 122559 108944 1359 99% /usr globhost:/usr/spool/globdata 315263 232783 50953 82% /rmt/globhost/globdata You did't really want ALL the df output, did you? --tom
clewis@eci386.uucp (Chris Lewis) (02/27/90)
In article <100210@convex.convex.com> tchrist@convex.COM (Tom Christiansen) writes: > The teststat program fails to identify NFS files on Convex > systems. Here's the output from a C120 OS7.1: That's partially because my program was busted (the major should have been bmajor), and partially because I'm not really taking account of differing "major()" definitions. In your teststat output, given: > file: /usr/spool/globdata/aliases/tacunix dev: ffffff02 major: ff minor: 2 > I don't think /usr/spool/globdata/aliases/tacunix is a networked file Note that the major has bit 7 on, which it doesn't on the local filesystems. What I'm leaning towards is the following definitions: #if defined(locmajor) #undef locmajor #endif #define locmajor(x) (major(x)&0x7f) #define REMOTEFS(dev) (makedev(locmajor(dev),minor(dev)) != (dev)) Which should work on HPUX, AIX and now Convex, not to mention the other systems that Larry Wall mentioned, even where major() itself masks off the bit. Though, the 0x7f may have to be parameterized on some systems. -- Chris Lewis, Elegant Communications Inc, {uunet!attcan,utzoo}!lsuc!eci386!clewis Ferret mailing list: eci386!ferret-list, psroff mailing list: eci386!psroff-list