Codebase list debian-goodies / debian/0.27
Imported Debian version 0.27 Javier Fernandez-Sanguino 12 years ago
6 changed file(s) with 407 addition(s) and 30 deletion(s). Raw diff Collapse all Expand all
00 #!/usr/bin/python
11
2 # Copyright (C) 2001 Matt Zimmerman <mdz@debian.org>
3 #
4 # Further updated by Javier Fernandez-Sanguino <jfs@debian.org>
5 # - included patch from Justin Pryzby <justinpryzby_AT_users.sourceforge.net>
6 # to work with the latest Lsof - modify to reduce false positives by not
7 # complaining about deleted inodes/files under /tmp/, /var/log/ or named
8 # /SYSV.
9
10 # PENDING:
11 # - included code from 'psdel' contributed by Sam Morris <sam_AT_robots.org.uk> to
12 # make the program work even if lsof is not installed
13 # (available at http://robots.org.uk/src/psdel)
14 #
15 #
16 # This program is free software; you can redistribute it and/or modify
17 # it under the terms of the GNU General Public License as published by
18 # the Free Software Foundation; either version 2, or (at your option)
19 # any later version.
20
21 # This program is distributed in the hope that it will be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 # GNU General Public License for more details.
25
26 # You should have received a copy of the GNU General Public License
27 # along with this program; if not, write to the Free Software
28 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
29 # MA 02110-1301 USA
30 #
31 # On Debian systems, a copy of the GNU General Public License may be
32 # found in /usr/share/common-licenses/GPL.
33
234 import sys
3 import os
35 import os, errno
436 import re
37 import stat
38 import pwd
39 import sys
40 import string
541
642 if os.getuid() != 0:
743 sys.stderr.write('This program must be run as root\n')
844 sys.stderr.write('in order to collect information about all open file descriptors\n')
945 sys.exit(1)
1046
47
48 def find_cmd(cmd):
49 dirs = [ '/', '/usr/', '/usr/local/', sys.prefix ]
50 for d in dirs:
51 for sd in ('bin', 'sbin'):
52 location = os.path.join(d, sd, cmd)
53 if os.path.exists(location):
54 return location
55 return 0
56
57
1158 def main():
1259 process = None
13 processes = {}
14 for line in os.popen('lsof +L1 -F n').readlines():
15 field, data = line[0], line[1:-1]
16
17 if field == 'p':
18 process = processes.setdefault(data,Process(int(data)))
19 elif field == 'n':
20 process.files.append(data)
21
22 toRestart = filter(lambda process: process.needsRestart(),
23 processes.values())
60 toRestart = {}
61
62 toRestart = lsofcheck()
63 # Check if we have lsof, if not, use psdel
64 # if find_cmd('lsof'):
65 # toRestart = lsofcheck()
66 # else:
67 # TODO - This does not work yet:
68 # toRestart = psdelcheck()
69
2470 print "Found %d processes using old versions of upgraded files" % len(toRestart)
2571
2672 if len(toRestart) == 0:
96142 for process in package.processes:
97143 print "\t%s\t%s" % (process.pid,process.program)
98144
145 def lsofcheck():
146 processes = {}
147
148 for line in os.popen('lsof +XL -F nf').readlines():
149 field, data = line[0], line[1:-1]
150
151 if field == 'p':
152 process = processes.setdefault(data,Process(int(data)))
153 elif field == 'k':
154 process.links.append(data)
155 elif field == 'n':
156 # Remove the previous entry to check if this is something we should do
157 if data.startswith('/SYSV'):
158 last = process.descriptors.pop()
159 if not re.compile("DEL").search(last):
160 process.files.append(data)
161 else:
162 process.files.append(data)
163 elif field == 'f':
164 process.descriptors.append(data)
165
166 toRestart = filter(lambda process: process.needsRestart(),
167 processes.values())
168 return toRestart
169
170 def psdelcheck():
171 # TODO - Needs to be fixed to work here
172 # Useful for seeing which processes need to be restarted after you upgrade
173 # programs or shared libraries. Written to replace checkrestart(1) from the
174 # debian-goodies, which often misses out processes due to bugs in lsof; see
175 # <http://bugs.debian.org/264985> for more information.
176
177 numeric = re.compile(r'\d+')
178 toRestart = map (delmaps, map (string.atoi, filter (numeric.match, os.listdir('/proc'))))
179 return toRestart
180
181 def delmaps (pid):
182 processes = {}
183 process = processes.setdefault(pid,Process(int(pid)))
184 deleted = re.compile(r'(.*) \(deleted\)$')
185 boring = re.compile(r'/(dev/zero|SYSV([\da-f]{8}))')
186
187 mapline = re.compile(r'^[\da-f]{8}-[\da-f]{8} [r-][w-][x-][sp-] '
188 r'[\da-f]{8} [\da-f]{2}:[\da-f]{2} (\d+) *(.+)( \(deleted\))?\n$')
189 maps = open('/proc/%d/maps' % (pid))
190 for line in maps.readlines ():
191 m = mapline.match (line)
192 if (m):
193 inode = string.atoi (m.group (1))
194 file = m.group (2)
195 if inode == 0:
196 continue
197 # remove ' (deleted)' suffix
198 if deleted.match (file):
199 file = file [0:-10]
200 if boring.match (file):
201 continue
202 # list file names whose inode numbers do not match their on-disk
203 # values; or files that do not exist at all
204 try:
205 if os.stat (file)[stat.ST_INO] != inode:
206 process = processes.setdefault(pid,Process(int(pid)))
207 except OSError, (e, strerror):
208 if e == errno.ENOENT:
209 process = processes.setdefault(pid,Process(int(pid)))
210 else:
211 sys.stderr.write ('checkrestart (psdel): %s %s: %s\n' % (SysProcess.get(pid).info (), file, os.strerror (e)))
212 else:
213 print 'checkrestart (psdel): Error parsing "%s"' % (line [0:-1])
214 maps.close ()
215
216 return process
217
218
219 class SysProcess:
220 re_name = re.compile('Name:\t(.*)$')
221 re_uids = re.compile('Uid:\t(\d+)\t(\d+)\t(\d+)\t(\d+)$')
222 processes = {}
223 def get (pid):
224 try:
225 return Process.processes [pid]
226 except KeyError:
227 Process.processes [pid] = Process (pid)
228 return Process.get (pid)
229
230 # private
231 def __init__ (self, pid):
232 self.pid = pid
233
234 status = open ('/proc/%d/status' % (self.pid))
235 for line in status.readlines ():
236 m = self.re_name.match (line)
237 if m:
238 self.name = m.group (1)
239 continue
240 m = self.re_uids.match (line)
241 if m:
242 self.user = pwd.getpwuid (string.atoi (m.group (1)))[0]
243 continue
244 status.close ()
245
246 def info (self):
247 return '%d %s %s' % (self.pid, self.name, self.user)
248
99249 class Process:
100250 def __init__(self, pid):
101251 self.pid = pid
102252 self.files = []
253 self.descriptors = []
254 self.links = []
103255
104256 try:
105257 self.program = self.cleanFile(os.readlink('/proc/%d/exe' % self.pid))
114266 f = f[:null]
115267 return re.sub('( \(deleted\)|.dpkg-new).*$','',f)
116268
269 # Check if a process needs to be restarted, previously we would
270 # just check if it used libraries named '.dpkg-new' since that's
271 # what dpkg would do. Now we need to be more contrieved.
117272 def needsRestart(self):
118273 for f in self.files:
119 if f.endswith('.dpkg-new'):
120 return 1
274 #print "Checking %s" % f
275 # We don't care about log files
276 if f.startswith('/var/log/'):
277 continue
278 # Or about files under /tmp
279 if f.startswith('/tmp/'):
280 continue
281 # TODO: it should only care about library files (i.e. /lib, /usr/lib and the like)
282 # build that check with a regexp to exclude others
283 if f.endswith(' (deleted)'):
284 return 1
285 if re.compile("\(path inode=[0-9]+\)$").search(f):
286 return 1
287 for f in self.descriptors:
288 # If it begins with SYSV it is not a deleted file
289 if re.compile("DEL").search(f):
290 return 1
291 for f in self.links:
292 if f == 0:
293 return 1
121294 return 0
122295
123296 class Package:
128301
129302 if __name__ == '__main__':
130303 main()
304
0 .\" checkrestart.1 - provide a list of processess that need to be restarted
1 .\" Copyright (C) 2006 Javier Fernandez-Sanguino
2 .\" Everybody is allowed to distribute this manual page,
3 .\" to modify it, and to distribute modifed versions of it.
4 .TH checkrestart 1 "December 19 2006" "debian\-goodies" "debian\-goodies"
5 .SH NAME
6 checkrestart \- check which processes need to be restarted after an upgrade
7 .SH SYNOPSIS
8 .B checkrestart
9 .SH DESCRIPTION
10 The
11 .B checkrestart
12 program tries to determine if there are processes in the system
13 that need to be restarted after a system upgrade. This is necessary since an upgrade
14 will usually bring new system libraries and running processes will be still
15 using the old versions of the libraries. In \fIstable\fP Debian GNU/Linux
16 systems this is typically needed to eliminate a system exposure to a
17 vulnerability which might have been fixed by upgrading a library which that
18 process makes use of.
19
20 .P
21 Consequently,
22 .B checkrestart
23 is sometimes used as an audit tool to find outdated versions of libraries in use,
24 particularly after security upgrades. Administrators should not, however, rely
25 on its output completely (see \fBBUGS\fP below).
26
27 .P
28 This script needs to run as root in order to obtain the information it needs
29 for analysis.
30
31 .SH EXIT STATUS
32
33 The program will exit with error (1) if a non-root user tries to run it. Otherwise,
34 it will always exit with error status 0.
35
36 .SH BUGS
37 This program might fail if the output of the \fIlsof\fP utility changes since it
38 depends on it to detect which deleted files are used by processes. It might
39 also output some false positives depending on the processes' behaviour since
40 it does not check yet if the (deleted) files in use are really libraries.
41
42 .P
43 .B Checkrestart
44 is also sensitive to the kernel version in use. And might fail to work with newer
45 (or older) versions.
46
47 .P
48 A rewrite to make it less dependant on \fIlsof\fP could improve this, however.
49
50 .SH SEE ALSO
51 .B lsof(8)
52
53 .SH AUTHOR
54
55 .B checkrestart
56 was written by Matt Zimmerman for the Debian
57 GNU/Linux distribution.
58
59 .SH COPYRIGHT AND LICENCE
60
61 Copyright (C) 2001 Matt Zimmerman <mdz@debian.org>
62
63 This program is free software; you can redistribute it and/or modify
64 it under the terms of the GNU General Public License as published by
65 the Free Software Foundation; either version 2, or (at your option)
66 any later version.
67
68 On Debian systems, a copy of the GNU General Public License may be
69 found in /usr/share/common-licenses/GPL.
70
0 debian-goodies (0.27) unstable; urgency=medium
1
2 [ Fixes I would like to see in etch, even though we're on freeze now ]
3 * Fix checkrestart with patch provided by Justin Pryzby, modify to reduce
4 false positives by not complaining about deleted inodes/files under
5 /tmp/, /var/log/ or named /SYSV. This fixes the long-standing issue that
6 made this script rather useless (related to lsof, see bug #297029, and to
7 changes in dpkg) (Closes: #264985)
8 (Note I have included the code from Sam Morris, available at
9 http://robots.org.uk/src/psdel and contributed in the BTS. But it still
10 needs to be massaged to work as a replacement for lsof)
11 * Write a manpage for checkrestart so administrators are aware that this
12 tool should not be completely relied on.
13 * Update the version of network-test which fixes some of the bugs already
14 fixed in the experimental 'ifupdown-extra' package:
15 [ Note: Post-etch network-test will be removed from this package but
16 I rather not try to introduce an experimental package such as
17 ifupdown-extra into etch right now ]
18 * Make network-test use bash (Closed: #401363)
19 * Do not analyse resolv.conf lines that have been commented out.
20 * Change network-test so it does not complain loudly if ethtool is not
21 installed (just recommends its installation)
22 * Fix duplicate spaces in the script as well as some typos with patch
23 provided by Norbert Kiesel (Closed: #400463)
24 * Change behaviour of network-test when testing ethernet link
25 (based on ifupdown-extra's 'check-network-cable' tests) this is better
26 (and more reliable) than just using 'ifconfig' but requires users
27 install additional software.
28 * Lintian error fix: FSF address
29
30 -- Javier Fernandez-Sanguino Pen~a <jfs@computer.org> Tue, 19 Dec 2006 01:59:13 +0100
31
032 debian-goodies (0.26) unstable; urgency=low
133
234 * Remove extra space from which-pkg-broke which introduced a syntax
2020
2121 # You should have received a copy of the GNU General Public License
2222 # along with this program; if not, write to the Free Software
23 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24 # 02111-1307, USA.
25 #
23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
24 # MA 02110-1301 USA
2625
2726 On Debian systems, a copy of the GNU General Public License may be
2827 found in /usr/share/common-licenses/GPL.
6262 # dh_installinit
6363 # dh_installcron
6464 dh_installman debget.1 debman.1 dglob.1 dgrep.1 dpigs.1 popbugs.1 \
65 which-pkg-broke.1 network-test.1
65 which-pkg-broke.1 network-test.1 checkrestart.1
6666 # dh_installinfo
6767 # dh_undocumented
6868 dh_installchangelogs
00 #!/bin/bash
1 # Network testing script v 1.3
2 # (c) 2005 Javier Fernandez-Sanguino
1 # Network testing script v 1.8
2 # (c) 2005,2006 Javier Fernandez-Sanguino
33 #
44 # This script will test your system's network configuration using basic
55 # tests and providing both information (INFO messages), warnings (WARN)
8888
8989 # Check if all commands we need are available
9090 # NOTE: if using nslookup add "nslookup dnsutils"
91 ( echo -e "netstat net-tools\nifconfig net-tools\nping netkit-ping\n\
92 arp net-tools\nip iproute\nhost bind9-host\nmktemp debianutils\nnc netcat" |
91 ( echo -e "netstat net-tools\nifconfig net-tools\n\
92 ping netkit-ping|inetutils-ping|iputils-ping\n\
93 arp net-tools\nip iproute\nhost host|bind9-host\nmktemp debianutils\n\
94 nc netcat" |
9395 while read cmd package; do
9496 if ! `which $cmd 2>/dev/null >&2`; then
9597 echo "$cmd is not available! (please install $package)" >&2
9698 exit 1
9799 fi
98100 done ) || exit 1
101 # Recommended programs
102 ( echo -e "ethtool ethtool" |
103 while read cmd package; do
104 if ! `which $cmd 2>/dev/null >&2`; then
105 echo "$cmd is not available (consider installing $package)" >&2
106 exit 1
107 fi
108 done )
109
110 # Default route for programs
111 ETHTOOL=/usr/sbin/ethtool
112 MIITOOL=/sbin/mii-tool
113
114 # Other needs
115 # We need /proc/net
116 if [ ! -d /proc/net ] ; then
117 echo "/proc is not available! Please mount it ('mount -t /proc')" >&2
118 exit 1
119 fi
99120
100121
101122 # Extract the interface of our default route
138159 return $status
139160 }
140161
162 check_if_link_miitool () {
163 ifname=$1
164 [ ! -x "$MIITOOL" ] && return 0
165 status=0
166 if $MIITOOL $ifname 2>&1| grep -q "no link"; then
167 status=1
168 fi
169 return $status
170 }
171
172 check_if_link_ethtool () {
173 # Check if the interface has link
174 # Note: Unlike other sections of the script we need to be root
175 # to test this
176 ifname=$1
177 [ ! -x "$ETHTOOL" ] && return 0
178 status=0
179 LINK=`$ETHTOOL $ifname 2>&1| grep "Link detected"`
180 # If ethtool fails to print out the link line we break off
181 # notice that ethtool cannot get the link status out of all
182 # possible network interfaces
183 [ -z "$LINK" ] && return
184 if ! echo $LINK | grep -q "Link detected: yes" ; then
185 status=1
186 fi
187 return $status
188 }
189
190 check_if_link_iplink () {
191 ifname=$1
192 status=0
193 [ ! -x /sbin/ip ] && return 0
194 if /sbin/ip link show $ifname 2>&1 | grep -q "NO-CARRIER"; then
195 status=1
196 fi
197 return $status
198 }
199
200
201
202 check_if_link() {
203 status=-1
204 iface=$1
205 # Use ethtool if installed (preferable to mii-tool)
206 # If none are installed we will test using 'ip link show'
207 if [ "`id -u`" -eq 0 ] ; then
208 if [ -x "$ETHTOOL" ] ; then
209 check_if_link_ethtool $iface
210 status=$?
211 elif [ -x "$MIITOOL" ]; then
212 check_if_link_miitool $iface
213 status=$?
214 fi
215 fi
216 # If no test has done use ip link
217 if [ $status -eq -1 ]; then
218 check_if_link_iplink $iface
219 status=$?
220 fi
221 return $status
222 }
223
141224 # Check network interfaces
142225 check_if () {
143226 ifname=$1
144227 status=0
145228 [ -z "$ifname" ] && return 1
229 # Check if the interface has a link
230 case "$ifname" in
231 eth*) check_if_link $ifname ; status=$?;;
232 *) ;;
233 esac
234 # Print results
235 if [ $status -ne 0 ] ; then
236 if [ "$ifname" = "$defaultif" ] ; then
237 echo "ERR: The $ifname interface that is associated with your default route has no link!"
238 else
239 echo "WARN: Interface $ifname does not have link"
240 fi
241 fi
146242 # Find IP addresses for $ifname
147243 inetaddr=`ip addr show $ifname | grep inet | awk '{print $2}'`
148244 if [ -z "$inetaddr" ] ; then
151247 else
152248 # TODO: WARN if more than 2 IP addresses?
153249 echo $inetaddr | while read ipaddr; do
154 echo "INFO: The $ifname interface has IP address $ipaddr assigned"
250 echo "INFO: The $ifname interface has IP address $ipaddr assigned"
155251 done
156252 fi
157253
172268 elif [ "$rxpkts" -eq 0 ] ; then
173269 echo "WARN: The $ifname interface has not received any packets."
174270 else
175 echo "INFO: The $ifname interface has tx and rx packets."
271 echo "INFO: The $ifname interface has tx and rx packets."
176272 fi
177273 # TODO: It should be best if there was a comparison with tx/rx packets.
178274 # a few errors are not uncommon if the card has been running for a long
192288 ip link show | egrep '^[[:digit:]]' |
193289 while read ifnumber ifname status extra; do
194290 ifname=`echo $ifname |sed -e 's/:$//'`
195 if [ -z "`echo $status | grep UP\>`" ] && \
196 [ -z "`echo $status | grep UP,`" ] ; then
291 # TODO: this is redundant with the check if_link test
292 # (although faster since using it would make us call 'ip'
293 # twice.
294 if [ -n "`echo $status | grep NO-CARRIER`" ] ; then
197295 if [ "$ifname" = "$defaultif" ] ; then
198296 echo "ERR: The $ifname interface that is associated with your default route is down!"
199297 status=1
200298 elif [ "$ifname" = "lo" ] ; then
201 echo "ERR: Your lo inteface is down, this might cause issues with local applications (but not necessarily with network connectivity)"
299 echo "ERR: Your lo interface is down, this might cause issues with local applications (but not necessarily with network connectivity)"
202300 else
203301 echo "WARN: The $ifname interface is down"
204302 fi
279377 nsok=0
280378 tempfile=`mktemp tmptestnet.XXXXXX` || { echo "ERR: Cannot create temporary file! Aborting! " >&2 ; exit 1; }
281379 trap " [ -f \"$tempfile\" ] && /bin/rm -f -- \"$tempfile\"" 0 1 2 3 13 15
282 # TODO should warn about resolv.conf entries with more than one
283 # ip address in the nameserver line
284 cat /etc/resolv.conf |grep -v ^# | grep nameserver |
380 cat /etc/resolv.conf | grep -v ^# | grep nameserver |
285381 awk '/nameserver/ { for (i=2;i<=NF;i++) { print $i ; } }' >$tempfile
286382 for nameserver in `cat $tempfile`; do
287383 nsfound=$(( $nsfound + 1 ))
386482
387483 exit 0
388484
485
486 # Set our locale environment, just in case ethtool gets translated
487 LC_ALL=C
488 export LC_ALL
489