RFS/NFS file detection - possible solution
Chris Lewis
clewis at eci386.uucp
Fri Feb 23 09:28:46 AEST 1990
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 at 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 at 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
More information about the Comp.unix.wizards
mailing list