]> arthur.barton.de Git - bup.git/blob - dev/cleanup-mounts-under
fedc0b34a7a78390acab8c8423c69d3f18837901
[bup.git] / dev / cleanup-mounts-under
1 #!/bin/sh
2 """": # -*-python-*-
3 # This command is used by "make clean", so don't rely on ./configure
4 set -e
5 for python in \
6     python3 \
7     python3.9 \
8     python3.8 \
9     python3.7 \
10     python3.6 \
11     python \
12     python2.7; do \
13     if command -v "$python"; then
14         exec "$python" "$0" "$@"
15     fi
16 done
17 echo "error: unable to find suitable python executable; please report" 1>&2
18 exit 2
19 """
20
21 from __future__ import absolute_import, print_function
22 from sys import stderr
23 import os.path, re, subprocess, sys
24
25 def mntent_unescape(x):
26     def replacement(m):
27         unescapes = {
28             "\\\\" : "\\",
29             "\\011" : "\t",
30             "\\012" : "\n",
31             "\\040" : " "
32         }
33         return unescapes.get(m.group(0))
34     return re.sub(r'(\\\\|\\011|\\012|\\040)', replacement, x)
35
36 targets = sys.argv[1:]
37
38 if not os.path.exists('/proc/mounts'):
39     print('No /proc/mounts; skipping mount cleanup in', repr(targets),
40           file=stderr)
41     sys.exit(0)
42
43 exit_status = 0
44 for target in targets:
45     if not os.path.isdir(target):
46         print(repr(target), 'is not a directory', file=stderr)
47         exit_status = 1
48         continue
49     top = os.path.realpath(target)
50     proc_mounts = open('/proc/mounts', 'r')
51     for line in proc_mounts:
52         _, point, fstype, _ = line.split(' ', 3)
53         point = mntent_unescape(point)
54         if top == point or os.path.commonprefix((top + '/', point)) == top + '/':
55             if fstype.startswith('fuse'):
56                 if subprocess.call(['fusermount', '-uz', point]) != 0:
57                     exit_status = 1
58             else:
59                 if subprocess.call(['umount', '-l', point]) != 0:
60                     exit_status = 1
61
62 sys.exit(exit_status)