namespace-util: introduce helper for combining unshare() + MS_SLAVE remount
We have multiple places we do these two non-trivial operations together, let's introduce a unified helper for doing both at once.
This commit is contained in:
parent
cda667722c
commit
e2ec9c4d3a
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "missing_fs.h"
|
||||
|
@ -169,3 +170,16 @@ int fd_is_network_ns(int fd) {
|
|||
|
||||
return r == CLONE_NEWNET;
|
||||
}
|
||||
|
||||
int detach_mount_namespace(void) {
|
||||
|
||||
/* Detaches the mount namespace, disabling propagation from our namespace to the host */
|
||||
|
||||
if (unshare(CLONE_NEWNS) < 0)
|
||||
return -errno;
|
||||
|
||||
if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,3 +7,5 @@ int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *
|
|||
int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
|
||||
|
||||
int fd_is_network_ns(int fd);
|
||||
|
||||
int detach_mount_namespace(void);
|
||||
|
|
|
@ -223,11 +223,9 @@ int machine_id_commit(const char *root) {
|
|||
return log_error_errno(r, "Can't fetch current mount namespace: %m");
|
||||
|
||||
/* Switch to a new mount namespace, isolate ourself and unmount etc_machine_id in our new namespace */
|
||||
if (unshare(CLONE_NEWNS) < 0)
|
||||
return log_error_errno(errno, "Failed to enter new namespace: %m");
|
||||
|
||||
if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0)
|
||||
return log_error_errno(errno, "Couldn't make-rslave / mountpoint in our private namespace: %m");
|
||||
r = detach_mount_namespace();
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set up new mount namespace: %m");
|
||||
|
||||
if (umount(etc_machine_id) < 0)
|
||||
return log_error_errno(errno, "Failed to unmount transient %s file in our private namespace: %m", etc_machine_id);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "env-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "log.h"
|
||||
#include "namespace-util.h"
|
||||
#include "path-util.h"
|
||||
#include "random-util.h"
|
||||
#include "strv.h"
|
||||
|
@ -137,10 +138,7 @@ bool have_namespaces(void) {
|
|||
|
||||
if (pid == 0) {
|
||||
/* child */
|
||||
if (unshare(CLONE_NEWNS) < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0)
|
||||
if (detach_mount_namespace() < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "mkdir.h"
|
||||
#include "namespace-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "string-util.h"
|
||||
|
@ -36,15 +37,13 @@ static int fake_filesystems(void) {
|
|||
{ "test/run", "/etc/udev/rules.d", "Failed to mount empty /etc/udev/rules.d", true },
|
||||
{ "test/run", UDEVLIBEXECDIR "/rules.d", "Failed to mount empty " UDEVLIBEXECDIR "/rules.d", true },
|
||||
};
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
if (unshare(CLONE_NEWNS) < 0)
|
||||
return log_error_errno(errno, "Failed to call unshare(): %m");
|
||||
r = detach_mount_namespace();
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to detach mount namespace: %m");
|
||||
|
||||
if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0)
|
||||
return log_error_errno(errno, "Failed to mount / as private: %m");
|
||||
|
||||
for (i = 0; i < ELEMENTSOF(fakefss); i++)
|
||||
for (size_t i = 0; i < ELEMENTSOF(fakefss); i++)
|
||||
if (mount(fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL) < 0) {
|
||||
log_full_errno(fakefss[i].ignore_mount_error ? LOG_DEBUG : LOG_ERR, errno, "%s: %m", fakefss[i].error);
|
||||
if (!fakefss[i].ignore_mount_error)
|
||||
|
|
Loading…
Reference in a new issue