Dragon_Krome
asked on
procfs detection
Hi,
I need a reliable method of detecting a proc filesystem mounted under an directory (not necessarily /proc) which would work under Linux, *BSD and Solaris (and eventually other UNIX-like systems).
This is more like a programming issue, but i'm only interested in a method, a system call (even platform specific) or something, but *reliable*. It also needs to detect a procfs if mounted via --bind (on linux).
The methods i've thought of are: parsing /etc/mtab and using statfs(), both of them not so reliable..
Does anybody else know other methods?
Thank you
I need a reliable method of detecting a proc filesystem mounted under an directory (not necessarily /proc) which would work under Linux, *BSD and Solaris (and eventually other UNIX-like systems).
This is more like a programming issue, but i'm only interested in a method, a system call (even platform specific) or something, but *reliable*. It also needs to detect a procfs if mounted via --bind (on linux).
The methods i've thought of are: parsing /etc/mtab and using statfs(), both of them not so reliable..
Does anybody else know other methods?
Thank you
There is no reliable way as you noticed. There is no standard purpose for procfs either.
agree with gheist -- there's no standard...
You may as well have seperate conditional stanzas for each system -- then use the right stanza
for each system...the information is different, and common information is presented differently...
You may as well have seperate conditional stanzas for each system -- then use the right stanza
for each system...the information is different, and common information is presented differently...
What do you want to accomplish?
ASKER
I'm trying to do something like a file integrity checker and i need to skip over procfs, sysfs etc.. stuff like that.
oh, look how gnu find and df work...df can identify file systems -- see how df handles the -T
option to detect file systems...but you'll have to do system calls on each directory to
see if its a mount point (I think stat) and there's an fstype for proc file systems...
(I'm on a windows system right now and don't have a linux system I can go to right now...)
If you have any quesitons about the source, feel free to ask...
locate also has a syntax where you can specify what types of file systems to skip -- look at updatedb
to see how they do it...
option to detect file systems...but you'll have to do system calls on each directory to
see if its a mount point (I think stat) and there's an fstype for proc file systems...
(I'm on a windows system right now and don't have a linux system I can go to right now...)
If you have any quesitons about the source, feel free to ask...
locate also has a syntax where you can specify what types of file systems to skip -- look at updatedb
to see how they do it...
ASKER
nor find nor df open the files... the problem i'm afraid of is getting stuck in a file like /proc/kcore and/or checksumming useless files (like the others in /proc).
Of course, i could create an exclusion list, but this will be kinda hard to mantain and useless if a procfs is mounted in a non-standard place...
I'm going to take a look at find and df though, to see if i find something useful. But i have a hunch that df uses /etc/mtab.
Of course, i could create an exclusion list, but this will be kinda hard to mantain and useless if a procfs is mounted in a non-standard place...
I'm going to take a look at find and df though, to see if i find something useful. But i have a hunch that df uses /etc/mtab.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
You know /dev is even not always a filesystem, but better avoid it anyway.
So the question may be reformulated: is there a relyable way to detect local disk based file systems?
gheist righ, there is no reliable and portable way to detect memory based or 'generated' filesystems.
One 'hack' soltion however exists.
It may be based on that fact, that 'procfs' driver _typically_ doesn't support 'mmap' functionality. And mmap() syscall is portable.
You just need to find first file below the mounted point in question, open it RD_ONLY and try to mmap().
If you will get an error like 'ENOSYS' then you are probably on wrong FS (this may be not procfs, but any other no mmap() support).
gheist righ, there is no reliable and portable way to detect memory based or 'generated' filesystems.
One 'hack' soltion however exists.
It may be based on that fact, that 'procfs' driver _typically_ doesn't support 'mmap' functionality. And mmap() syscall is portable.
You just need to find first file below the mounted point in question, open it RD_ONLY and try to mmap().
If you will get an error like 'ENOSYS' then you are probably on wrong FS (this may be not procfs, but any other no mmap() support).
ASKER
Interesting idea that mmap() thing, but also unreliable.
I could try to use statfs(), but the filesystem id-s are not standardized in any way, afaik, so i can't rely on those values not changing (i'm kinda trying to build a closed source solution, so compiling on the specific platform from source code would be out of the question :-s ).
I could try to use statfs(), but the filesystem id-s are not standardized in any way, afaik, so i can't rely on those values not changing (i'm kinda trying to build a closed source solution, so compiling on the specific platform from source code would be out of the question :-s ).
You cannot have that all in single source file without #IFDEF.
ASKER
i'm aware of that... i think i'm going to #ifdef even if I use statfs or getmntent or such...
i was just hoping that these things would be standardised by now and it wouldn't be such a problem. :-s
i was just hoping that these things would be standardised by now and it wouldn't be such a problem. :-s
One is called PASC thet makes POSIX standard, another is LSB - Linux Standard Base. Newer Linuces obey "Filesystem Hirearchy Standard", ask google, maybe you dig up least common denominator of some function that gives you what you need.
1 #!/bin/bash
2 # pid-identifier.sh: Gives complete path name to process associated with pid.
3
4 ARGNO=1 # Number of arguments the script expects.
5 E_WRONGARGS=65
6 E_BADPID=66
7 E_NOSUCHPROCESS=67
8 E_NOPERMISSION=68
9 PROCFILE=exe
10
11 if [ $# -ne $ARGNO ]
12 then
13 echo "Usage: `basename $0` PID-number" >&2 # Error message >stderr.
14 exit $E_WRONGARGS
15 fi
16
17 pidno=$( ps ax | grep $1 | awk '{ print $1 }' | grep $1 )
18 # Checks for pid in "ps" listing, field #1.
19 # Then makes sure it is the actual process, not the process invoked by this script.
20 # The last "grep $1" filters out this possibility.
21 if [ -z "$pidno" ] # If, after all the filtering, the result is a zero-length string,
22 then # no running process corresponds to the pid given.
23 echo "No such process running."
24 exit $E_NOSUCHPROCESS
25 fi
26
27 # Alternatively:
28 # if ! ps $1 > /dev/null 2>&1
29 # then # no running process corresponds to the pid given.
30 # echo "No such process running."
31 # exit $E_NOSUCHPROCESS
32 # fi
33
34 # To simplify the entire process, use "pidof".
35
36
37 if [ ! -r "/proc/$1/$PROCFILE" ] # Check for read permission.
38 then
39 echo "Process $1 running, but..."
40 echo "Can't get read permission on /proc/$1/$PROCFILE."
41 exit $E_NOPERMISSION # Ordinary user can't access some files in /proc.
42 fi
43
44 # The last two tests may be replaced by:
45 # if ! kill -0 $1 > /dev/null 2>&1 # '0' is not a signal, but
46 # this will test whether it is possible
47 # to send a signal to the process.
48 # then echo "PID doesn't exist or you're not its owner" >&2
49 # exit $E_BADPID
50 # fi
51
52
53
54 exe_file=$( ls -l /proc/$1 | grep "exe" | awk '{ print $11 }' )
55 # Or exe_file=$( ls -l /proc/$1/exe | awk '{print $11}' )
56 #
57 # /proc/pid-number/exe is a symbolic link
58 # to the complete path name of the invoking process.
59
60 if [ -e "$exe_file" ] # If /proc/pid-number/exe exists...
61 then # the corresponding process exists.
62 echo "Process #$1 invoked by $exe_file."
63 else
64 echo "No such process running."
65 fi
66
67
68 # This elaborate script can *almost* be replaced by
69 # ps ax | grep $1 | awk '{ print $5 }'
70 # However, this will not work...
71 # because the fifth field of 'ps' is argv[0] of the process,
72 # not the executable file path.
73 #
74 # However, either of the following would work.
75 # find /proc/$1/exe -printf '%l\n'
76 # lsof -aFn -p $1 -d txt | sed -ne 's/^n//p'
77
78 # Additional commentary by Stephane Chazelas.
79
80 exit 0
2 # pid-identifier.sh: Gives complete path name to process associated with pid.
3
4 ARGNO=1 # Number of arguments the script expects.
5 E_WRONGARGS=65
6 E_BADPID=66
7 E_NOSUCHPROCESS=67
8 E_NOPERMISSION=68
9 PROCFILE=exe
10
11 if [ $# -ne $ARGNO ]
12 then
13 echo "Usage: `basename $0` PID-number" >&2 # Error message >stderr.
14 exit $E_WRONGARGS
15 fi
16
17 pidno=$( ps ax | grep $1 | awk '{ print $1 }' | grep $1 )
18 # Checks for pid in "ps" listing, field #1.
19 # Then makes sure it is the actual process, not the process invoked by this script.
20 # The last "grep $1" filters out this possibility.
21 if [ -z "$pidno" ] # If, after all the filtering, the result is a zero-length string,
22 then # no running process corresponds to the pid given.
23 echo "No such process running."
24 exit $E_NOSUCHPROCESS
25 fi
26
27 # Alternatively:
28 # if ! ps $1 > /dev/null 2>&1
29 # then # no running process corresponds to the pid given.
30 # echo "No such process running."
31 # exit $E_NOSUCHPROCESS
32 # fi
33
34 # To simplify the entire process, use "pidof".
35
36
37 if [ ! -r "/proc/$1/$PROCFILE" ] # Check for read permission.
38 then
39 echo "Process $1 running, but..."
40 echo "Can't get read permission on /proc/$1/$PROCFILE."
41 exit $E_NOPERMISSION # Ordinary user can't access some files in /proc.
42 fi
43
44 # The last two tests may be replaced by:
45 # if ! kill -0 $1 > /dev/null 2>&1 # '0' is not a signal, but
46 # this will test whether it is possible
47 # to send a signal to the process.
48 # then echo "PID doesn't exist or you're not its owner" >&2
49 # exit $E_BADPID
50 # fi
51
52
53
54 exe_file=$( ls -l /proc/$1 | grep "exe" | awk '{ print $11 }' )
55 # Or exe_file=$( ls -l /proc/$1/exe | awk '{print $11}' )
56 #
57 # /proc/pid-number/exe is a symbolic link
58 # to the complete path name of the invoking process.
59
60 if [ -e "$exe_file" ] # If /proc/pid-number/exe exists...
61 then # the corresponding process exists.
62 echo "Process #$1 invoked by $exe_file."
63 else
64 echo "No such process running."
65 fi
66
67
68 # This elaborate script can *almost* be replaced by
69 # ps ax | grep $1 | awk '{ print $5 }'
70 # However, this will not work...
71 # because the fifth field of 'ps' is argv[0] of the process,
72 # not the executable file path.
73 #
74 # However, either of the following would work.
75 # find /proc/$1/exe -printf '%l\n'
76 # lsof -aFn -p $1 -d txt | sed -ne 's/^n//p'
77
78 # Additional commentary by Stephane Chazelas.
79
80 exit 0
ASKER
sorry, but i fail to see how this would help me
Dragon_Krome, gheist give the best answer - no reliable and portable way. It's better to ask user which FS to exclude and use /proc by default
ASKER
:)
Wouldn't be funny for a "security" tool to ask the user where he has mounted his proc? :)
In the mean while, since i haven't found a reliable way, i'm using getmntent() (and similar on other OS) and with a little bit of parsing tricks i managed to detect even --bind ed procfs'
Wouldn't be funny for a "security" tool to ask the user where he has mounted his proc? :)
In the mean while, since i haven't found a reliable way, i'm using getmntent() (and similar on other OS) and with a little bit of parsing tricks i managed to detect even --bind ed procfs'
No comment has been added to this question in more than 21 days, so it is now classified as abandoned.
I will leave the following recommendation for this question in the Cleanup topic area:
Accept leisner http:#16295106
Any objections should be posted here in the next 4 days. After that time, the question will be closed.
gheist
EE Cleanup Volunteer
I will leave the following recommendation for this question in the Cleanup topic area:
Accept leisner http:#16295106
Any objections should be posted here in the next 4 days. After that time, the question will be closed.
gheist
EE Cleanup Volunteer
Closest to your described solution.