Author: Sergio Gonzalez Duran
A combination of Linux utilities can help you determine who on your network is using which of your shared filesystems at any given time, allowing you to ask those users to log off while you update the system.
One of my clients has many multiple small Visual Basic 6 and Access-based applications running directly on Linux via Samba through network shares on Windows XP clients. Whenever he needs to update the application or database, he asks the users to log off the application so he can upload the new binary application or Access file to the server. However, his mid-sized network has about 100 clients using the apps, so even if only one user is logged on, my client has to get on the phone and go extension by extension until he finds the user who is using the application, ask the user to log off, and perform the upload.
I created a script to solve this problem using a combination of lsof
, netstat
, gawk
, grep
, uniq
, and other utilities. All of the applications’ binaries are stored in /usr/apps, in subfolders named payroll, accounting, sales, invoice, and so on. Assuming, for example, that the client needs to know the IP addresses of all the users who are using the payroll system, you can use the lsof
utility, which lists all the open files:
lsof | grep /usr/apps/payroll smbd 16258 systems cwd DIR 8,5 4096 2191586 /usr/apps/payroll smbd 16258 systems 27rR REG 8,5 2449408 2191760 /usr/apps/payroll/payroll.exe smbd 16258 systems 28u REG 8,5 37883904 1684790 /usr/apps/payroll/dbpayroll.mdb smbd 16258 systems 29uw REG 8,5 256 1684290 /usr/apps/payroll/dbpayroll.ldb smbd 19237 systems cwd DIR 8,5 4096 2191586 /usr/apps/payroll smbd 19237 systems 25rR REG 8,5 2449408 2191760 /usr/apps/payroll/payroll.exe smbd 19237 systems 27u REG 8,5 37883904 1684790 /usr/apps/payroll/dbpayroll.mdb smbd 19237 systems 28uw REG 8,5 256 1684290 /usr/apps/payroll/dbpayroll.ldb smbd 19237 systems 29rW REG 8,5 45056 1684863 /usr/apps/payroll/report1.rpt
The output shows that smbd (Samba) has several files open, from process IDs (PID) 16258 through 19237. You know that two users are using the payroll.exe application, for example. The last line shows that the report1.rpt file is being used. This is a typical Crystal Reports extension, so you can figure out that this application is also busy. However, this doesn’t show the users, so you need to extract only the necessary information (the PID numbers) from the previous output:
lsof | grep /usr/apps/payroll | gawk '{ print $2 }' 16258 16258 16258 16258 19237 19237 19237 19237 19237
With gawk
, you can extract the second field, but you don’t need all those repetitions. Use uniq
, which removes duplicate lines from a sorted listing:
lsof | grep /usr/apps/payroll | gawk '{ print $2 }' | uniq 16258 19237
Send the results to a temporary file:
lsof | grep /usr/apps/payroll | gawk '{ print $2 }' | uniq > tmp
Next, relate those PID numbers with a network socket using the netstat
command. With the –p
option, netstat
shows the PID and the name of the program to which each socket belongs:
netstat -p | grep 16258 tcp 0 0 192.168.100.250:netbios-ssn 192.168.100.32:1028 ESTABLISHED 16258/smbd
The fourth column (192.168.100.250:netbios-ssn
) is the server machine, and the fifth column (168.100.32:1028
) is the IP address and port number of the client machine, which is what you need.
Now you can put everything together by using a script that reads the PIDs in the tmp file:
lsof | grep /usr/apps/payroll | gawk '{ print $2 }' | uniq > tmp echo "PCs USING THE APPLICATION:" while read row ; do netstat -p | grep $row | gawk '{ print $5 }' | cut -d":" -f1 doneThe line
netstat -p | grep $row | gawk '{ print $5 }' | cut -d":" -f1
first executesnetstat
, then callsgrep
with the variable $row, which comes from each row of the tmp file. Extract the fifth column withgawk
, then withcut
and the ":" delimiter, extract the first field, which is the IP address.Give the script a name, and run
chmod 700 script.sh
to make it executable. When you run it, the result should look something like this:./script.sh PCs USING THE APPLICATION 192.168.100.32 192.168.100.78Now you just have to tie the IP address to a user name. To do that, add to /etc/hosts lines like this:
192.168.100.32 Lindsay_Hayek 192.168.100.78 Salma_Lohan 192.168.100.145 Tom_Norton 192.168.100.193 Edward_CruiseAnd add an additional
grep
the script to read from /etc/hosts, in the netstat line:
grep `netstat -p | grep $row | gawk '{ print $5 }' | cut -d":" -f1` /etc/hosts
Now, however, if the script finds an IP address that is not listed in /etc/hosts, it will send an error rather than simply print the IP address. We can solve that problem with an if statment. If the above instruction is correct (returns 0 through the variable $?) then the script should go on to the next row of the tmp file, while anything besides 0 means that the IP address wasn't found in /etc/hosts, so just print the IP address. You may be able to find out who it belongs to from a network administrator. The final script would look something like this:
lsof | grep /usr/apps/payroll | gawk '{ print $2 }' | uniq > tmp echo "PCs USING THE APPLICATION:" while read row ; do grep `netstat -p | grep $row | gawk '{ print $5 }' | cut -d":" -f1` /etc/hosts if [ $? -ne 0 ]; then netstat -p | grep $row | gawk '{ print $5 }' | cut -d":" -f1 end if doneAnd when run, the result would look like:
./script.sh PCs USING THE APPLICATION 192.168.100.32 Lindsay_Hayek 192.168.100.78 Salma_Lohan 192.168.100.90You could enhance this script. For example, instead of using payroll in the line
lsof | grep /usr/apps/payroll | gawk '{ print $2 }' | uniq > tmp
and then having to edit it every time you want to look for another application, you could use something like this:lsof | grep /usr/apps/$1 | gawk '{ print $2 }' | uniq > tmp echo "PCs USING THE APPLICATION: $1"Here, $1 is an argument read from the command line:
./script.sh accounting PCs USING THE APPLICATION accounting 192.168.100.145 Tom_Norton 192.168.100.178 192.168.100.193 Edward_CruiseYou could also create a menu of applications, or use Zenity to interact with the script in an X Window environment.
Category:
- System Administration