netdev-dpdk: fix mbuf leaks
[cascardo/ovs.git] / utilities / ovs-check-dead-ifs.in
1 #! @PYTHON@
2
3 import os
4 import re
5 import stat
6 import sys
7
8 if "--help" in sys.argv:
9     sys.stdout.write("""\
10 ovs-check-dead-ifs: Check for packet sockets for nonexistent network devices.
11
12 One side effect of the "force-reload-kmod" command that reloads the
13 Open vSwitch kernel module is that all the network devices that the
14 Open vSwitch kernel module implemented get destroyed and then replaced
15 by new instances with the same names.  Unfortunately, programs that
16 are listening for packets on the original network devices will not
17 receive packets that arrive on the new instances.  This causes some
18 services, such as DHCP, to silently fail.  This program looks for such
19 problems and, if it finds any, prints information about programs that
20 are in such a state.  The system administrator should then take some
21 action to fix the problem, such as restarting these programs.
22 """)
23     sys.exit(0)
24 elif len(sys.argv) > 1:
25     sys.stderr.write("ovs-check-dead-ifs: no arguments or options accepted "
26                      "(use --help for help)\n")
27     sys.exit(1)
28
29 # Get the set of all valid ifindexes.
30 #
31 # 0 is always valid for our purposes because it means "any interface".
32 valid_ifindexes = set([])
33 for ifname in os.listdir("/sys/class/net"):
34     fn = "/sys/class/net/%s/ifindex" % ifname
35     try:
36         valid_ifindexes.add(int(open(fn).readline()))
37     except IOError:
38         pass
39     except ValueError:
40         print "%s: unexpected format\n" % fn
41
42 # Get inodes for all packet sockets whose ifindexes don't exist.
43 invalid_inodes = set()
44 f = open("/proc/net/packet")
45 f.readline()                    # Skip header line.
46 for line in f:
47     fields = line.split()
48     ifindex = int(fields[4])
49     if ifindex not in valid_ifindexes:
50         invalid_inodes.add(int(fields[8]))
51 f.close()
52
53 if not invalid_inodes:
54     sys.exit(0)
55
56 # Now find the processes that are using those packet sockets.
57 inode_re = re.compile(r'socket:\[([0-9]+)\]$')
58 bad_pids = set()
59 for pid in os.listdir("/proc"):
60     try:
61         pid = int(pid)
62     except ValueError:
63         continue
64
65     try:
66         fds = os.listdir("/proc/%d/fd" % pid)
67     except OSError:
68         continue
69
70     for fd in fds:
71         try:
72             fd = int(fd)
73         except ValueError:
74             continue
75
76         try:
77             s = os.stat("/proc/%d/fd/%d" % (pid, fd))
78         except OSError:
79             continue
80
81         if not stat.S_ISSOCK(s.st_mode):
82             continue
83
84         try:
85             linkname = os.readlink("/proc/%d/fd/%d" % (pid, fd))
86         except OSError:
87             continue
88
89         m = inode_re.match(linkname)
90         if not m:
91             continue
92
93         inode = int(m.group(1))
94         if inode in invalid_inodes:
95             bad_pids.add(pid)
96
97 if bad_pids:
98     print """
99 The following processes are listening for packets to arrive on network devices
100 that no longer exist. You may want to restart them."""
101     sys.stdout.flush()
102     os.execvp("ps", ["ps"] + ["%s" % pid for pid in bad_pids])