forked from xapi-project/sm
-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathsafe-umount
More file actions
executable file
·54 lines (43 loc) · 1.66 KB
/
Copy pathsafe-umount
File metadata and controls
executable file
·54 lines (43 loc) · 1.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/env python3
import argparse
import subprocess
import sys
import time
def safe_umount(path):
retry_count = 10
not_mounted_str = 'umount: {}: not mounted'.format(path)
last_code = 0
while retry_count:
proc = subprocess.Popen(['mountpoint', '-q', path])
proc.wait()
if proc.returncode:
return 0
proc = subprocess.Popen(['umount', path], stderr=subprocess.PIPE)
(_stdout, stderr) = proc.communicate()
if not proc.returncode:
return 0
error = stderr.strip()
if error == not_mounted_str:
return 0
retry_count -= 1
last_code = proc.returncode
time.sleep(0.500)
# Lazy attempt.
# Unmounting can fail for example due to a network outage of a DRBD volume mounted
# as `xcp-persistent-database` and which would be blocked in the kernel because of
# ext4 commands that cannot complete.
# In this kind of situation, it's necessary to force a umount call with lazy arg to
# ensure that the mountpoint does not remain present.
print(f'Failed to unmount `{path}`, trying with lazy option...', file=sys.stderr)
proc = subprocess.Popen(['umount', '-l', path], stderr=subprocess.PIPE)
(_stdout, stderr) = proc.communicate()
if proc.returncode:
print(f'Failed to unmount `{path}` with lazy option: `{stderr.strip()}`.', file=sys.stderr)
else:
print(f'Successfully unmounted `{path}`.', file=sys.stderr)
return proc.returncode
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('path')
args = parser.parse_args()
sys.exit(safe_umount(args.path))