Sindbad~EG File Manager
#!/bin/bash
# Socktop systemtap script
# Copyright (C) 2006 IBM Corp.
#
# This file is part of systemtap, and is free software. You can
# redistribute it and/or modify it under the terms of the GNU General
# Public License (GPL); either version 2, or (at your option) any
# later version.
###
### socktop - Combination shell/systemtap script to track reads and writes
### on sockets by process. Can be filtered by process IDs and
### names, protocols, protocol families, users and socket type.
###
ITER_COUNT=-1 # number of iterations (no iteration limit default)
MOD_GEN=""; # Generate a instrumentation module option
# Filter options
F_PROTSTR=""; F_PROT=0 # Filter by protocol
F_FAMSTR=""; F_FAM=0 # Filter by protocol family
F_TYPESTR=""; F_TYPE=0 # Filter by socket type
F_PIDSTR=""; F_PID=0 # Filter by process ID
F_NAMESTR=""; F_NAME=0 # Filter by process name
F_UIDSTR=""; F_UID=0 # Filter by user
FILTER=0 # Any filters specified?
# Print options
P_INTERVAL=5 # default interval between output
P_DEVICES=0 # default is don't display network device traffic
P_NUMTOP=10 # default number of processes and network devices to print
DELIM=","
function usage {
echo "USAGE: socktop [-d] [-i interval] [-N num] [-P protocol]... [-f family]..."
echo " [-t stype]... [-n pname]... [-p pid]... [-u username]... [-h]"
echo " -d # print network device traffic (default: off)"
echo " -i interval # interval in seconds between printing (default: $P_INTERVAL)"
echo " -N num # number of top processes and devices to print (default: $P_NUMTOP)"
echo " -f family # this protocol family only (default: all)"
echo " -P protocol # this protocol only (default: all)"
echo " -t stype # this socket type only (default: all)"
echo " -n pname # this process name only (default: all)"
echo " -p pid # this process ID only (default: all)"
echo " -u username # this user only (default: all)"
echo " -c count # number of iteration"
echo " -D # dry run (generate instrumentation but do not run)"
echo " -h # print this help text"
echo ""
echo "Protocol Families:"
echo " LOCAL, INET, INET6, IPX, NETLINK, X25, AX25, ATMPVC, APPLETALK, PACKET"
echo ""
echo "Protocols:"
echo " TCP, UDP, SCTP, IP, FC, ... (see /etc/protocols for complete list)"
echo ""
echo "Socket Types:"
echo " STREAM, DGRAM, RAW, RDM, SEQPACKET, DCCP, PACKET"
}
# Process options
while getopts df:i:n:N:P:p:t:u:c:Dh option; do
case $option in
d) P_DEVICES=1 ;;
i) P_INTERVAL=$OPTARG ;;
N) P_NUMTOP=$OPTARG ;;
f) let "F_FAM++"
F_FAMSTR=$OPTARG$DELIM$F_FAMSTR ;;
n) let "F_NAME++"
F_NAMESTR=$OPTARG$DELIM$F_NAMESTR ;;
p) let "F_PID++"
F_PIDSTR=$OPTARG$DELIM$F_PIDSTR ;;
P) let "F_PROT++"
F_PROTSTR=$OPTARG$DELIM$F_PROTSTR ;;
t) let "F_TYPE++"
F_TYPESTR=$OPTARG$DELIM$F_TYPESTR ;;
u) uid=`awk -F: '$1 == name {print $3}' name=$OPTARG /etc/passwd`
if [[ $uid != "" ]]; then
let "F_UID++"
F_UIDSTR=$uid$DELIM$F_UIDSTR
else
echo "ERROR: Unknown user:" $OPTARG
let "ERROR++"
fi ;;
c) ITER_COUNT=$OPTARG ;;
D) MOD_GEN="-p4" ;;
h|?|*) usage
exit 1 ;;
esac
done
if [[ $ERROR > 0 ]]; then
exit 1
fi
if [[ $F_FAM > 0 || $F_NAME > 0 || $F_PID > 0 ||
$F_PROT > 0 || $F_TYPE > 0 || $F_UID > 0 ]]; then
FILTER=1
fi
#
# Pass a timezone adjustment value to the stap script
#
TZ=`date "+%z"`
TZ_SIGN=`echo $TZ | cut -c1`
TZ_HOURS=`echo $TZ | cut -c2-3`
TZ_MINS=`echo $TZ | cut -c4-5`
TZ_ADJUST=$TZ_SIGN$((10#$TZ_HOURS*60*60+10#$TZ_MINS*60))
#
# Start the systemtap script
#
stap $MOD_GEN -w -e '
global iter
global execname, user, if_tx, if_rx, if_dev
global sk_tx, sk_rx, sk_pid
global f_name_str, f_pid_str, f_prot_str, f_fam_str, f_type_str, f_uid_str
global f_name, f_pid, f_prot, f_fam, f_type, f_uid
probe never {
#workaround to avoid outputing filtering strings
log(f_name_str);
log(f_pid_str);
log(f_prot_str);
log(f_fam_str);
log(f_type_str);
log(f_uid_str);
#workaround to make sure that systemtap gets correct types for arrays
if_rx["junk"] <<< 0
if_tx["junk"] <<< 0
if_dev["junk"] ++
delete if_rx
delete if_tx
delete if_dev
}
probe begin
{
# set number of iterations
iter = '$ITER_COUNT'
# If no filters specified, skip filter processing
if ('$FILTER' == 0) next
f_name_str = "'$F_NAMESTR'"
f_pid_str = "'$F_PIDSTR'"
f_prot_str = "'$F_PROTSTR'"
f_fam_str = "'$F_FAMSTR'"
f_type_str = "'$F_TYPESTR'"
f_uid_str = "'$F_UIDSTR'"
delim = "'$DELIM'"
error = 0
# Protocols
if ('$F_PROT') {
prot = tokenize(f_prot_str, delim)
while (prot != "") {
p = sock_prot_str2num(prot)
if (p < 0) {
printf("ERROR: Unknown protocol: %s\n", prot)
error++
} else
f_prot[p] = 1
prot = tokenize("", delim)
}
}
# Protocol families
if ('$F_FAM') {
fam = tokenize(f_fam_str, delim)
while (fam != "") {
f = sock_fam_str2num(fam)
if (f < 0) {
printf("ERROR: Unknown protocol family: %s\n", fam)
error++
} else
f_fam[f] = 1
fam = tokenize("", delim)
}
}
# Process names
if ('$F_NAME') {
pname = tokenize(f_name_str, delim)
while (pname != "") {
f_name[pname] = 1
pname = tokenize("", delim)
}
}
# Process IDs
if ('$F_PID') {
pid = tokenize(f_pid_str, delim)
while (pid != "") {
f_pid[strtol(pid, 10)] = 1
pid = tokenize("", delim)
}
}
# Socket types
if ('$F_TYPE') {
stype = tokenize(f_type_str, delim)
while (stype != "") {
t = sock_type_str2num(stype)
if (t < 0) {
printf("ERROR: Unknown socket type: %s\n", stype)
error++
} else
f_type[t] = 1
stype = tokenize("", delim)
}
}
# User IDs
if ('$F_UID') {
uid = tokenize(f_uid_str, delim)
while (uid != "") {
f_uid[strtol(uid, 10)] = 1
uid = tokenize("", delim)
}
}
if (error) exit()
}
probe netdev.transmit
{
if ('$P_DEVICES') {
if_tx[dev_name] <<< length
if_dev[dev_name] ++
}
}
probe netdev.receive
{
if ('$P_DEVICES') {
if_rx[dev_name] <<< length
if_dev[dev_name] ++
}
}
probe socket.send
{
if (!success) next
# Check filters
if ('$FILTER') {
if ('$F_PROT' && !(protocol in f_prot)) next
if ('$F_FAM' && !(family in f_fam)) next
if ('$F_PID' && !(pid() in f_pid)) next
if ('$F_NAME' && !(execname() in f_name)) next
if ('$F_UID' && !(uid() in f_uid)) next
if ('$F_TYPE' && !(type in f_type)) next
}
execname[pid()] = execname()
user[pid()] = uid()
sk_tx[pid(), protocol, family] <<< size
sk_pid[pid(), protocol, family] += size
}
probe socket.receive
{
if (!success) next
# Check filters
if ('$FILTER') {
if ('$F_PROT' && !(protocol in f_prot)) next
if ('$F_FAM' && !(family in f_fam)) next
if ('$F_PID' && !(pid() in f_pid)) next
if ('$F_NAME' && !(execname() in f_name)) next
if ('$F_UID' && !(uid() in f_uid)) next
if ('$F_TYPE' && !(type in f_type)) next
}
execname[pid()] = execname()
user[pid()] = uid()
sk_rx[pid(), protocol, family] <<< size
sk_pid[pid(), protocol, family] += size
}
function print_activity()
{
# Print top processes
max = '$P_NUMTOP'
time = gettimeofday_s() + '$TZ_ADJUST'
printf("======================= %s ========================\n", ctime(time))
printf("------------------------------- PROCESSES -------------------------------\n")
printf("%-5s %-5s %7s %7s %7s %7s %-4s %-8s %-15s\n",
"PID", "UID", "#SEND", "#RECV", "SEND_KB",
"RECV_KB", "PROT", "FAMILY", "COMMAND")
foreach ([pid, prot, fam] in sk_pid- limit max) {
n_sk_tx = @count(sk_tx[pid, prot, fam])
n_sk_rx = @count(sk_rx[pid, prot, fam])
printf("%-5d %-5d %7d %7d %7d %7d %-4s %-8s %-15s\n",
pid, user[pid], n_sk_tx, n_sk_rx,
n_sk_tx ? @sum(sk_tx[pid, prot, fam])/1024 : 0,
n_sk_rx ? @sum(sk_rx[pid, prot, fam])/1024 : 0,
sock_prot_num2str(prot), sock_fam_num2str(fam),
execname[pid])
}
# Print top network devices
if ('$P_DEVICES') {
max = '$P_NUMTOP'
printf("-------------------------------- DEVICES --------------------------------\n")
printf("%-7s %13s %13s %15s %15s\n",
"DEV", "#XMIT", "#RECV", "XMIT_KB", "RECV_KB")
foreach ([dev] in if_dev- limit max) {
n_if_tx = @count(if_tx[dev])
n_if_rx = @count(if_rx[dev])
printf("%-7s %13d %13d %15d %15d\n", dev, n_if_tx, n_if_rx,
n_if_tx ? @sum(if_tx[dev])/1024 : 0,
n_if_rx ? @sum(if_rx[dev])/1024 : 0)
}
}
printf("=========================================================================\n\n")
delete execname
delete user
delete sk_tx
delete sk_rx
delete sk_pid
delete if_tx
delete if_rx
delete if_dev
}
probe timer.s('$P_INTERVAL')
{
print_activity();
--iter;
if (iter == 0) exit();
}
'
saved_status=$?
# Cleanup
test -n "$MOD_GEN" && rm -f ${MOD_NAME}.ko
# Exit with the status of 'stap', not the cleanup commands.
exit $saved_status
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists