]>
glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/helpers/mount.py
1 # Copyright 2021 Oliver Smith
2 # SPDX-License-Identifier: GPL-3.0-or-later
4 import tools
.helpers
.run
9 Ismount() implementation, that works for mount --bind.
10 Workaround for: https://bugs.python.org/issue29707
12 folder
= os
.path
.realpath(os
.path
.realpath(folder
))
13 with open("/proc/mounts", "r") as handle
:
16 if len(words
) >= 2 and words
[1] == folder
:
18 if words
[0] == folder
:
23 def bind(args
, source
, destination
, create_folders
=True, umount
=False):
25 Mount --bind a folder and create necessary directory structure.
26 :param umount: when destination is already a mount point, umount it first.
28 # Check/umount destination
29 if ismount(destination
):
31 umount_all(args
, destination
)
35 # Check/create folders
36 for path
in [source
, destination
]:
37 if os
.path
.exists(path
):
40 tools
.helpers
.run
.root(args
, ["mkdir", "-p", path
])
42 raise RuntimeError("Mount failed, folder does not exist: " +
45 # Actually mount the folder
46 tools
.helpers
.run
.root(args
, ["mount", "-o", "bind", source
, destination
])
48 # Verify, that it has worked
49 if not ismount(destination
):
50 raise RuntimeError("Mount failed: " + source
+ " -> " + destination
)
53 def bind_file(args
, source
, destination
, create_folders
=False):
55 Mount a file with the --bind option, and create the destination file,
58 # Skip existing mountpoint
59 if ismount(destination
):
63 if not os
.path
.exists(destination
):
65 dir = os
.path
.dirname(destination
)
66 if not os
.path
.isdir(dir):
67 tools
.helpers
.run
.root(args
, ["mkdir", "-p", dir])
69 tools
.helpers
.run
.root(args
, ["touch", destination
])
72 tools
.helpers
.run
.root(args
, ["mount", "-o", "bind", source
,
76 def umount_all_list(prefix
, source
="/proc/mounts"):
78 Parses `/proc/mounts` for all folders beginning with a prefix.
79 :source: can be changed for testcases
80 :returns: a list of folders, that need to be umounted
83 prefix
= os
.path
.realpath(prefix
)
84 with open(source
, "r") as handle
:
88 raise RuntimeError("Failed to parse line in " + source
+ ": " +
91 if mountpoint
.startswith(prefix
):
92 # Remove "\040(deleted)" suffix (#545)
93 deleted_str
= r
"\040(deleted)"
94 if mountpoint
.endswith(deleted_str
):
95 mountpoint
= mountpoint
[:-len(deleted_str
)]
96 ret
.append(mountpoint
)
97 ret
.sort(reverse
=True)
101 def umount_all(args
, folder
):
103 Umount all folders, that are mounted inside a given folder.
105 for mountpoint
in umount_all_list(folder
):
106 tools
.helpers
.run
.root(args
, ["umount", mountpoint
])
107 if ismount(mountpoint
):
108 raise RuntimeError("Failed to umount: " + mountpoint
)
110 def mount(args
, source
, destination
, create_folders
=True, umount
=False, readonly
=True):
112 Mount and create necessary directory structure.
113 :param umount: when destination is already a mount point, umount it first.
115 # Check/umount destination
116 if ismount(destination
):
118 umount_all(args
, destination
)
122 # Check/create folders
123 if not os
.path
.exists(destination
):
125 tools
.helpers
.run
.root(args
, ["mkdir", "-p", destination
])
127 raise RuntimeError("Mount failed, folder does not exist: " +
130 # Actually mount the folder
131 tools
.helpers
.run
.root(args
, ["mount", source
, destination
])
133 tools
.helpers
.run
.root(args
, ["mount", "-o", "remount,ro", source
, destination
])
135 # Verify, that it has worked
136 if not ismount(destination
):
137 raise RuntimeError("Mount failed: " + source
+ " -> " + destination
)