В поисках соединений между процессами в OC Linux (socket linux proc process debug)
Ключевые слова: socket , linux , proc , process , debug , (найти похожие документы )
From: Гордеев Александр <avgordeev@dom.raid.ru. >
Newsgroups: email
Date: Mon, 15 Jan 2007 14:31:37 +0000 (UTC)
Subject: В поисках соединений между процессами в OC Linux
Оригинал: http://www.avgordeev.dom.raid.ru/unix_socket_peer.htm
В поисках соединений между процессами в OC Linux, осуществляемых
посредством unix сокетов.
Aвтор: Гордеев Александр
Для тех кому по какой либо причине интересно узнать пары unix сокетов в
linux-e предлагаю внести изменения в файл ядра linux/net/unix/af_unix.c.
предложенные изменения дают возможность командой cat /pro/unix_peer
вывести список сокетов, аналогичный тому, что выводится командой cat
/proc/unix, но показывающий еще и сокеты, ссылка на которые в структуре
unix_socket обозначена как peer.
Хочется верить, что указанная информация поможет анализировать связь
между процессами посредством unix сокетов.
Ниже представлен листинг утилиты diff для иллюстрации предлагаемых
изменений.
af_unix.c.orig 2007-01-07 14:23:03.000000000 +0500
--- af_unix.c 2007-01-07 21:12:00.000000000 +0500
***************
1978,1983 ****
--- 1978,2007 ----
return 0;
}
+ static int unix_peer_seq_show(struct seq_file *seq, void *v)
+ {
+
+ if (v == (void *)1)
+ seq_puts(seq, "Num Inode Peer PeerInode \n");
+ else {
+ struct sock *s = v;
+ struct unix_sock *u = unix_sk(s);
+ unix_state_rlock(s);
+
+ seq_printf(seq, "%p %5lu %p %5lu ",
+ s,
+ sock_i_ino(s),
+ u->peer,
+ ( (u->peer==NULL) ? ( unsigned long ) 0 : sock_i_ino(u-
>peer) )
+ );
+
+ unix_state_runlock(s);
+ seq_putc(seq, '\n');
+ }
+
+ return 0;
+ }
+
static struct seq_operations unix_seq_ops = {
.start = unix_seq_start,
.next = unix_seq_next,
***************
1985,1990 ****
--- 2009,2020 ----
.show = unix_seq_show,
};
+ static struct seq_operations unix_peer_seq_ops = {
+ .start = unix_seq_start,
+ .next = unix_seq_next,
+ .stop = unix_seq_stop,
+ .show = unix_peer_seq_show,
+ };
static int unix_seq_open(struct inode *inode, struct file *file)
{
***************
2009,2014 ****
--- 2039,2067 ----
goto out;
}
+ static int unix_peer_seq_open(struct inode *inode, struct file *file)
+ {
+ struct seq_file *seq;
+ int rc = -ENOMEM;
+ int *iter = kmalloc(sizeof(int), GFP_KERNEL);
+
+ if (!iter)
+ goto out;
+
+ rc = seq_open(file, &unix_peer_seq_ops);
+ if (rc)
+ goto out_kfree;
+
+ seq = file->private_data;
+ seq->private = iter;
+ *iter = 0;
+ out:
+ return rc;
+ out_kfree:
+ kfree(iter);
+ goto out;
+ }
+
static struct file_operations unix_seq_fops = {
.owner = THIS_MODULE,
.open = unix_seq_open,
***************
2017,2022 ****
--- 2070,2083 ----
.release = seq_release_private,
};
+ static struct file_operations unix_peer_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = unix_peer_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
+ };
+
#endif
static struct net_proto_family unix_family_ops = {
***************
2045,2050 ****
--- 2106,2112 ----
sock_register(&unix_family_ops);
#ifdef CONFIG_PROC_FS
proc_net_fops_create("unix", 0, &unix_seq_fops);
+ proc_net_fops_create("unix_peer", 0, &unix_peer_seq_fops);
#endif
unix_sysctl_register();
out:
***************
2056,2061 ****
--- 2118,2124 ----
sock_unregister(PF_UNIX);
unix_sysctl_unregister();
proc_net_remove("unix");
+ proc_net_remove("unix_peer");
proto_unregister(&unix_proto);
}
Изменения вносились в ядро из дистрибутива Fedora Core 5. Ядро 2.6.15
пропатченное до 2.6.16.
Командная строка, представленная ниже, иллюстрирует возможность просмотра
пар связанных процессов.
perl -e 'if(open PS,"ps ax -o pid,cmd|")'\
' {while(<PS>)'\
' {$ps{$1}=$2 if /^\s*(\d+)\s(.+)$/'\
' };'\
' if(open LSOF,"/usr/sbin/lsof -UFpfi|")'\
' {while(<LSOF>)'\
' {$p=$1 if /^p(.+)$/;'\
' $d=$1 if /^f(.+)$/;'\
' $sk_pr{$1}=[$p,$d] if /^i(.+)$/'\
' };'\
' if(open PEER,"</proc/net/unix_peer" )'\
' {while(<PEER>)'\
' {@peer=split;'\
' push
@c,[$sk_pr{$peer[1]}->[0],$sk_pr{$peer[1]}->[1],$sk_pr{$peer[3]}->[0],
$sk_pr{$peer[3]}->[1]]'\
' };'\
' for $i(@c)'\
' {print $i->[0]."->".$i->[1]." ".$ps{$i->[0]}."\n
=>".$i->[2]."->".$i->[3]." ".$ps{$i->[2]}."\n"'\
' }'\
' }'\
' }'\
' }'
Вывод команды выглядит премерно так:
...
3972->5 /usr/sbin/pppd .....
=>1503->0 syslogd -m 0
...
Понаблюдать взаимодействие процессов можно с помощью командной строки:
strace -e trace=send,recv -p 1503 -p 3972
Вывод будет примерно таким:
Process 1503 attached - interrupt to quit
Process 3972 attached - interrupt to quit
[pid 1503] recv(0, <unfinished ...>
[pid 3972] --- SIGTERM (Terminated) @ 0 (0) ---
[pid 1503] <... recv resumed> "<29>Jan 8 10:21:27 adsl-stop: K"..., 1022, 0) = 43
[pid 3972] send(5, "<30>Jan 8 10:21:27 pppd[3972]: "..., 56, MSG_NOSIGNAL) = 56
[pid 3972] send(5, "<30>Jan 8 10:21:27 pppd[3972]: "..., 57, MSG_NOSIGNAL) = 57
[pid 3972] send(5, "<30>Jan 8 10:21:27 pppd[3972]: "..., 63, MSG_NOSIGNAL) = 63
[pid 1503] recv(0, "<29>Jan 8 10:21:27 adsl-stop: K"..., 1022, 0) = 51
[pid 1503] recv(0, "<30>Jan 8 10:21:27 pppd[3972]: "..., 1022, 0) = 56
[pid 1503] recv(0, "<30>Jan 8 10:21:27 pppd[3972]: "..., 1022, 0) = 57
[pid 3972] send(5, "<29>Jan 8 10:21:27 pppd[3972]: "..., 54, MSG_NOSIGNAL) = 54
[pid 1503] recv(0, "<30>Jan 8 10:21:27 pppd[3972]: "..., 1022, 0) = 63
[pid 1503] recv(0, "<29>Jan 8 10:21:27 pppd[3972]: "..., 1022, 0) = 54
[pid 3972] --- SIGCHLD (Child exited) @ 0 (0) ---
[pid 1503] recv(0, "<30>Jan 8 10:21:29 pppoe[3973]:"..., 1022, 0) = 84
[pid 1503] recv(0, "<30>Jan 8 10:21:29 pppoe[3973]:"..., 1022, 0) = 42
[pid 3972] --- SIGCHLD (Child exited) @ 0 (0) ---
[pid 3972] send(5, "<30>Jan 8 10:21:29 pppd[3972]: "..., 37, MSG_NOSIGNAL) = 37
[pid 1503] recv(0, Process 3972 detached
"<30>Jan 8 10:21:29 pppd[3972]: "..., 1022, 0) = 37
Process 1503 detached
Во время работы утилиты strace произошло отключение от интернета и
демон pppd был остановлен.