]>
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
.user(args
, ["mkdir", "-p", path
])
42 raise RuntimeError("Mount failed, folder does not exist: " +
45 # Actually mount the folder
46 tools
.helpers
.run
.user(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
.user(args
, ["mkdir", "-p", dir])
69 tools
.helpers
.run
.user(args
, ["touch", destination
])
72 tools
.helpers
.run
.user(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 all_list
= umount_all_list(folder
)
106 for mountpoint
in all_list
:
107 tools
.helpers
.run
.user(args
, ["umount", mountpoint
])
108 for mountpoint
in all_list
:
109 if ismount(mountpoint
):
110 raise RuntimeError("Failed to umount: " + mountpoint
)
112 def mount(args
, source
, destination
, create_folders
=True, umount
=False, readonly
=True, mount_type
=None, options
=None):
114 Mount and create necessary directory structure.
115 :param umount: when destination is already a mount point, umount it first.
117 # Check/umount destination
118 if ismount(destination
):
120 umount_all(args
, destination
)
124 # Check/create folders
125 if not os
.path
.exists(destination
):
127 tools
.helpers
.run
.user(args
, ["mkdir", "-p", destination
])
129 raise RuntimeError("Mount failed, folder does not exist: " +
135 extra_args
.extend(["-t", mount_type
])
137 opt_args
.append("ro")
139 opt_args
.extend(options
)
141 extra_args
.extend(["-o", ",".join(opt_args
)])
143 # Actually mount the folder
144 tools
.helpers
.run
.user(args
, ["mount", *extra_args
, source
, destination
])
146 # Verify, that it has worked
147 if not ismount(destination
):
148 raise RuntimeError("Mount failed: " + source
+ " -> " + destination
)