nspawn,mount-util: add [u]mount_verbose and use it in nspawn
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 10 Oct 2016 19:55:20 +0000 (15:55 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 11 Oct 2016 20:50:07 +0000 (16:50 -0400)
This makes it easier to debug failed nspawn invocations:

Mounting sysfs on /var/lib/machines/fedora-rawhide/sys (MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV "")...
Mounting tmpfs on /var/lib/machines/fedora-rawhide/dev (MS_NOSUID|MS_STRICTATIME "mode=755,uid=1450901504,gid=1450901504")...
Mounting tmpfs on /var/lib/machines/fedora-rawhide/dev/shm (MS_NOSUID|MS_NODEV|MS_STRICTATIME "mode=1777,uid=1450901504,gid=1450901504")...
Mounting tmpfs on /var/lib/machines/fedora-rawhide/run (MS_NOSUID|MS_NODEV|MS_STRICTATIME "mode=755,uid=1450901504,gid=1450901504")...
Bind-mounting /sys/fs/selinux on /var/lib/machines/fedora-rawhide/sys/fs/selinux (MS_BIND "")...
Remounting /var/lib/machines/fedora-rawhide/sys/fs/selinux (MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_BIND|MS_REMOUNT "")...
Mounting proc on /proc (MS_NOSUID|MS_NOEXEC|MS_NODEV "")...
Bind-mounting /proc/sys on /proc/sys (MS_BIND "")...
Remounting /proc/sys (MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_BIND|MS_REMOUNT "")...
Bind-mounting /proc/sysrq-trigger on /proc/sysrq-trigger (MS_BIND "")...
Remounting /proc/sysrq-trigger (MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_BIND|MS_REMOUNT "")...
Mounting tmpfs on /tmp (MS_STRICTATIME "mode=1777,uid=0,gid=0")...
Mounting tmpfs on /sys/fs/cgroup (MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME "mode=755,uid=0,gid=0")...
Mounting cgroup on /sys/fs/cgroup/systemd (MS_NOSUID|MS_NOEXEC|MS_NODEV "none,name=systemd,xattr")...
Failed to mount cgroup on /sys/fs/cgroup/systemd (MS_NOSUID|MS_NOEXEC|MS_NODEV "none,name=systemd,xattr"): No such file or directory

src/basic/mount-util.c
src/basic/mount-util.h
src/nspawn/nspawn-cgroup.c
src/nspawn/nspawn-mount.c
src/nspawn/nspawn.c

index b9affb4..0ef0067 100644 (file)
@@ -581,3 +581,108 @@ const char* mode_to_inaccessible_node(mode_t mode) {
         }
         return NULL;
 }
+
+#define FLAG(name) (flags & name ? STRINGIFY(name) "|" : "")
+static char* mount_flags_to_string(long unsigned flags) {
+        char *x;
+        _cleanup_free_ char *y = NULL;
+        long unsigned overflow;
+
+        overflow = flags & ~(MS_RDONLY |
+                             MS_NOSUID |
+                             MS_NODEV |
+                             MS_NOEXEC |
+                             MS_SYNCHRONOUS |
+                             MS_REMOUNT |
+                             MS_MANDLOCK |
+                             MS_DIRSYNC |
+                             MS_NOATIME |
+                             MS_NODIRATIME |
+                             MS_BIND |
+                             MS_MOVE |
+                             MS_REC |
+                             MS_SILENT |
+                             MS_POSIXACL |
+                             MS_UNBINDABLE |
+                             MS_PRIVATE |
+                             MS_SLAVE |
+                             MS_SHARED |
+                             MS_RELATIME |
+                             MS_KERNMOUNT |
+                             MS_I_VERSION |
+                             MS_STRICTATIME |
+                             MS_LAZYTIME);
+
+        if (flags == 0 || overflow != 0)
+                if (asprintf(&y, "%lx", overflow) < 0)
+                        return NULL;
+
+        x = strjoin(FLAG(MS_RDONLY),
+                    FLAG(MS_NOSUID),
+                    FLAG(MS_NODEV),
+                    FLAG(MS_NOEXEC),
+                    FLAG(MS_SYNCHRONOUS),
+                    FLAG(MS_REMOUNT),
+                    FLAG(MS_MANDLOCK),
+                    FLAG(MS_DIRSYNC),
+                    FLAG(MS_NOATIME),
+                    FLAG(MS_NODIRATIME),
+                    FLAG(MS_BIND),
+                    FLAG(MS_MOVE),
+                    FLAG(MS_REC),
+                    FLAG(MS_SILENT),
+                    FLAG(MS_POSIXACL),
+                    FLAG(MS_UNBINDABLE),
+                    FLAG(MS_PRIVATE),
+                    FLAG(MS_SLAVE),
+                    FLAG(MS_SHARED),
+                    FLAG(MS_RELATIME),
+                    FLAG(MS_KERNMOUNT),
+                    FLAG(MS_I_VERSION),
+                    FLAG(MS_STRICTATIME),
+                    FLAG(MS_LAZYTIME),
+                    y, NULL);
+        if (!x)
+                return NULL;
+        if (!y)
+                x[strlen(x) - 1] = '\0'; /* truncate the last | */
+        return x;
+}
+
+int mount_verbose(
+                int error_log_level,
+                const char *what,
+                const char *where,
+                const char *type,
+                unsigned long flags,
+                const char *options) {
+
+        _cleanup_free_ char *fl = NULL;
+
+        fl = mount_flags_to_string(flags);
+
+        if ((flags & MS_REMOUNT) && !what && !type)
+                log_debug("Remounting %s (%s \"%s\")...",
+                          where, strnull(fl), strempty(options));
+        else if (!what && !type)
+                log_debug("Mounting %s (%s \"%s\")...",
+                          where, strnull(fl), strempty(options));
+        else if ((flags & MS_BIND) && !type)
+                log_debug("Bind-mounting %s on %s (%s \"%s\")...",
+                          what, where, strnull(fl), strempty(options));
+        else
+                log_debug("Mounting %s on %s (%s \"%s\")...",
+                          strna(type), where, strnull(fl), strempty(options));
+        if (mount(what, where, type, flags, options) < 0)
+                return log_full_errno(error_log_level, errno,
+                                      "Failed to mount %s on %s (%s \"%s\"): %m",
+                                      strna(type), where, strnull(fl), strempty(options));
+        return 0;
+}
+
+int umount_verbose(const char *what) {
+        log_debug("Umounting %s...", what);
+        if (umount(what) < 0)
+                return log_error_errno(errno, "Failed to unmount %s: %m", what);
+        return 0;
+}
index 74730de..4f305df 100644 (file)
@@ -52,3 +52,12 @@ union file_handle_union {
 const char* mode_to_inaccessible_node(mode_t mode);
 
 #define FILE_HANDLE_INIT { .handle.handle_bytes = MAX_HANDLE_SZ }
+
+int mount_verbose(
+                int error_log_level,
+                const char *what,
+                const char *where,
+                const char *type,
+                unsigned long flags,
+                const char *options);
+int umount_verbose(const char *where);
index aa0da04..6793df1 100644 (file)
@@ -23,6 +23,7 @@
 #include "fd-util.h"
 #include "fileio.h"
 #include "mkdir.h"
+#include "mount-util.h"
 #include "nspawn-cgroup.h"
 #include "string-util.h"
 #include "strv.h"
@@ -90,13 +91,13 @@ int sync_cgroup(pid_t pid, CGroupUnified unified_requested) {
                 return log_error_errno(errno, "Failed to generate temporary mount point for unified hierarchy: %m");
 
         if (unified)
-                r = mount("cgroup", tree, "cgroup", MS_NOSUID|MS_NOEXEC|MS_NODEV, "none,name=systemd,xattr");
+                r = mount_verbose(LOG_ERR, "cgroup", tree, "cgroup",
+                                  MS_NOSUID|MS_NOEXEC|MS_NODEV, "none,name=systemd,xattr");
         else
-                r = mount("cgroup", tree, "cgroup2", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
-        if (r < 0) {
-                r = log_error_errno(errno, "Failed to mount unified hierarchy: %m");
+                r = mount_verbose(LOG_ERR, "cgroup", tree, "cgroup2",
+                                  MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
+        if (r < 0)
                 goto finish;
-        }
 
         undo_mount = true;
 
@@ -110,7 +111,7 @@ int sync_cgroup(pid_t pid, CGroupUnified unified_requested) {
 
 finish:
         if (undo_mount)
-                (void) umount(tree);
+                (void) umount_verbose(tree);
 
         (void) rmdir(tree);
         return r;
index 02dc94c..da5bc68 100644 (file)
@@ -250,8 +250,10 @@ int mount_sysfs(const char *dest) {
 
         (void) mkdir(full, 0755);
 
-        if (mount("sysfs", full, "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) < 0)
-                return log_error_errno(errno, "Failed to mount sysfs to %s: %m", full);
+        r = mount_verbose(LOG_ERR, "sysfs", full, "sysfs",
+                          MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
+        if (r < 0)
+                return r;
 
         FOREACH_STRING(x, "block", "bus", "class", "dev", "devices", "kernel") {
                 _cleanup_free_ char *from = NULL, *to = NULL;
@@ -266,15 +268,19 @@ int mount_sysfs(const char *dest) {
 
                 (void) mkdir(to, 0755);
 
-                if (mount(from, to, NULL, MS_BIND, NULL) < 0)
-                        return log_error_errno(errno, "Failed to mount /sys/%s into place: %m", x);
+                r = mount_verbose(LOG_ERR, from, to, NULL, MS_BIND, NULL);
+                if (r < 0)
+                        return r;
 
-                if (mount(NULL, to, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL) < 0)
-                        return log_error_errno(errno, "Failed to mount /sys/%s read-only: %m", x);
+                r = mount_verbose(LOG_ERR, NULL, to, NULL,
+                                  MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL);
+                if (r < 0)
+                        return r;
         }
 
-        if (umount(full) < 0)
-                return log_error_errno(errno, "Failed to unmount %s: %m", full);
+        r = umount_verbose(full);
+        if (r < 0)
+                return r;
 
         if (rmdir(full) < 0)
                 return log_error_errno(errno, "Failed to remove %s: %m", full);
@@ -290,10 +296,8 @@ int mount_sysfs(const char *dest) {
                 (void) mkdir_p(x, 0755);
         }
 
-        if (mount(NULL, top, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL) < 0)
-                return log_error_errno(errno, "Failed to make %s read-only: %m", top);
-
-        return 0;
+        return mount_verbose(LOG_ERR, NULL, top, NULL,
+                             MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL);
 }
 
 int mount_all(const char *dest,
@@ -375,17 +379,14 @@ int mount_all(const char *dest,
                                 o = options;
                 }
 
-                if (mount(mount_table[k].what,
-                          where,
-                          mount_table[k].type,
-                          mount_table[k].flags,
-                          o) < 0) {
-
-                        if (mount_table[k].fatal)
-                                return log_error_errno(errno, "mount(%s) failed: %m", where);
-
-                        log_warning_errno(errno, "mount(%s) failed, ignoring: %m", where);
-                }
+                r = mount_verbose(mount_table[k].fatal ? LOG_ERR : LOG_WARNING,
+                                  mount_table[k].what,
+                                  where,
+                                  mount_table[k].type,
+                                  mount_table[k].flags,
+                                  o);
+                if (r < 0 && mount_table[k].fatal)
+                        return r;
         }
 
         return 0;
@@ -470,12 +471,12 @@ static int mount_bind(const char *dest, CustomMount *m) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to create mount point %s: %m", where);
 
-        } else {
+        } else
                 return log_error_errno(errno, "Failed to stat %s: %m", where);
-        }
 
-        if (mount(m->source, where, NULL, mount_flags, mount_opts) < 0)
-                return log_error_errno(errno, "mount(%s) failed: %m", where);
+        r = mount_verbose(LOG_ERR, m->source, where, NULL, mount_flags, mount_opts);
+        if (r < 0)
+                return r;
 
         if (m->read_only) {
                 r = bind_remount_recursive(where, true, NULL);
@@ -510,10 +511,7 @@ static int mount_tmpfs(
                 return log_oom();
         options = r > 0 ? buf : m->options;
 
-        if (mount("tmpfs", where, "tmpfs", MS_NODEV|MS_STRICTATIME, options) < 0)
-                return log_error_errno(errno, "tmpfs mount to %s failed: %m", where);
-
-        return 0;
+        return mount_verbose(LOG_ERR, "tmpfs", where, "tmpfs", MS_NODEV|MS_STRICTATIME, options);
 }
 
 static char *joined_and_escaped_lower_dirs(char * const *lower) {
@@ -575,10 +573,7 @@ static int mount_overlay(const char *dest, CustomMount *m) {
                 options = strjoina("lowerdir=", lower, ",upperdir=", escaped_source, ",workdir=", escaped_work_dir);
         }
 
-        if (mount("overlay", where, "overlay", m->read_only ? MS_RDONLY : 0, options) < 0)
-                return log_error_errno(errno, "overlay mount to %s failed: %m", where);
-
-        return 0;
+        return mount_verbose(LOG_ERR, "overlay", where, "overlay", m->read_only ? MS_RDONLY : 0, options);
 }
 
 int mount_custom(
@@ -665,7 +660,7 @@ static int get_controllers(Set *subsystems) {
 
 static int mount_legacy_cgroup_hierarchy(const char *dest, const char *controller, const char *hierarchy,
                                          CGroupUnified unified_requested, bool read_only) {
-        char *to;
+        const char *to, *fstype, *opts;
         int r;
 
         to = strjoina(strempty(dest), "/sys/fs/cgroup/", hierarchy);
@@ -681,22 +676,30 @@ static int mount_legacy_cgroup_hierarchy(const char *dest, const char *controlle
         /* The superblock mount options of the mount point need to be
          * identical to the hosts', and hence writable... */
         if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
-                if (unified_requested >= CGROUP_UNIFIED_SYSTEMD)
-                        r = mount("cgroup", to, "cgroup2", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
-                else
-                        r = mount("cgroup", to, "cgroup", MS_NOSUID|MS_NOEXEC|MS_NODEV, "none,name=systemd,xattr");
-        } else
-                r = mount("cgroup", to, "cgroup", MS_NOSUID|MS_NOEXEC|MS_NODEV, controller);
+                if (unified_requested >= CGROUP_UNIFIED_SYSTEMD) {
+                        fstype = "cgroup2";
+                        opts = NULL;
+                } else {
+                        fstype = "cgroup";
+                        opts = "none,name=systemd,xattr";
+                }
+        } else {
+                fstype = "cgroup";
+                opts = controller;
+        }
 
+        r = mount_verbose(LOG_ERR, "cgroup", to, fstype, MS_NOSUID|MS_NOEXEC|MS_NODEV, opts);
         if (r < 0)
-                return log_error_errno(errno, "Failed to mount to %s: %m", to);
+                return r;
 
-        /* ... hence let's only make the bind mount read-only, not the
-         * superblock. */
+        /* ... hence let's only make the bind mount read-only, not the superblock. */
         if (read_only) {
-                if (mount(NULL, to, NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL) < 0)
-                        return log_error_errno(errno, "Failed to remount %s read-only: %m", to);
+                r = mount_verbose(LOG_ERR, NULL, to, NULL,
+                                  MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL);
+                if (r < 0)
+                        return r;
         }
+
         return 1;
 }
 
@@ -728,8 +731,10 @@ static int mount_legacy_cgns_supported(
                 if (r < 0)
                         return log_oom();
 
-                if (mount("tmpfs", cgroup_root, "tmpfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, options) < 0)
-                        return log_error_errno(errno, "Failed to mount /sys/fs/cgroup: %m");
+                r = mount_verbose(LOG_ERR, "tmpfs", cgroup_root, "tmpfs",
+                                  MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, options);
+                if (r < 0)
+                        return r;
         }
 
         if (cg_all_unified() > 0)
@@ -788,10 +793,9 @@ skip_controllers:
         if (r < 0)
                 return r;
 
-        if (!userns) {
-                if (mount(NULL, cgroup_root, NULL, MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME|MS_RDONLY, "mode=755") < 0)
-                        return log_error_errno(errno, "Failed to remount %s read-only: %m", cgroup_root);
-        }
+        if (!userns)
+                return mount_verbose(LOG_ERR, NULL, cgroup_root, NULL,
+                                     MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME|MS_RDONLY, "mode=755");
 
         return 0;
 }
@@ -820,8 +824,10 @@ static int mount_legacy_cgns_unsupported(
                 if (r < 0)
                         return log_oom();
 
-                if (mount("tmpfs", cgroup_root, "tmpfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, options) < 0)
-                        return log_error_errno(errno, "Failed to mount /sys/fs/cgroup: %m");
+                r = mount_verbose(LOG_ERR, "tmpfs", cgroup_root, "tmpfs",
+                                  MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, options);
+                if (r < 0)
+                        return r;
         }
 
         if (cg_all_unified() > 0)
@@ -887,10 +893,8 @@ skip_controllers:
         if (r < 0)
                 return r;
 
-        if (mount(NULL, cgroup_root, NULL, MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME|MS_RDONLY, "mode=755") < 0)
-                return log_error_errno(errno, "Failed to remount %s read-only: %m", cgroup_root);
-
-        return 0;
+        return mount_verbose(LOG_ERR, NULL, cgroup_root, NULL,
+                             MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME|MS_RDONLY, "mode=755");
 }
 
 static int mount_unified_cgroups(const char *dest) {
@@ -917,10 +921,7 @@ static int mount_unified_cgroups(const char *dest) {
                 return -EINVAL;
         }
 
-        if (mount("cgroup", p, "cgroup2", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) < 0)
-                return log_error_errno(errno, "Failed to mount unified cgroup hierarchy to %s: %m", p);
-
-        return 0;
+        return mount_verbose(LOG_ERR, "cgroup", p, "cgroup2", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
 }
 
 int mount_cgroups(
@@ -965,14 +966,13 @@ int mount_systemd_cgroup_writable(
         }
 
         /* Make our own cgroup a (writable) bind mount */
-        if (mount(systemd_own, systemd_own,  NULL, MS_BIND, NULL) < 0)
-                return log_error_errno(errno, "Failed to turn %s into a bind mount: %m", own_cgroup_path);
+        r = mount_verbose(LOG_ERR, systemd_own, systemd_own,  NULL, MS_BIND, NULL);
+        if (r < 0)
+                return r;
 
         /* And then remount the systemd cgroup root read-only */
-        if (mount(NULL, systemd_root, NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL) < 0)
-                return log_error_errno(errno, "Failed to mount cgroup root read-only: %m");
-
-        return 0;
+        return mount_verbose(LOG_ERR, NULL, systemd_root, NULL,
+                             MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL);
 }
 
 int setup_volatile_state(
@@ -1009,10 +1009,7 @@ int setup_volatile_state(
         if (r > 0)
                 options = buf;
 
-        if (mount("tmpfs", p, "tmpfs", MS_STRICTATIME, options) < 0)
-                return log_error_errno(errno, "Failed to mount tmpfs to /var: %m");
-
-        return 0;
+        return mount_verbose(LOG_ERR, "tmpfs", p, "tmpfs", MS_STRICTATIME, options);
 }
 
 int setup_volatile(
@@ -1045,10 +1042,9 @@ int setup_volatile(
         if (r > 0)
                 options = buf;
 
-        if (mount("tmpfs", template, "tmpfs", MS_STRICTATIME, options) < 0) {
-                r = log_error_errno(errno, "Failed to mount tmpfs for root directory: %m");
+        r = mount_verbose(LOG_ERR, "tmpfs", template, "tmpfs", MS_STRICTATIME, options);
+        if (r < 0)
                 goto fail;
-        }
 
         tmpfs_mounted = true;
 
@@ -1061,10 +1057,9 @@ int setup_volatile(
                 goto fail;
         }
 
-        if (mount(f, t, NULL, MS_BIND|MS_REC, NULL) < 0) {
-                r = log_error_errno(errno, "Failed to create /usr bind mount: %m");
+        r = mount_verbose(LOG_ERR, f, t, NULL, MS_BIND|MS_REC, NULL);
+        if (r < 0)
                 goto fail;
-        }
 
         bind_mounted = true;
 
@@ -1074,10 +1069,9 @@ int setup_volatile(
                 goto fail;
         }
 
-        if (mount(template, directory, NULL, MS_MOVE, NULL) < 0) {
-                r = log_error_errno(errno, "Failed to move root mount: %m");
+        r = mount_verbose(LOG_ERR, template, directory, NULL, MS_MOVE, NULL);
+        if (r < 0)
                 goto fail;
-        }
 
         (void) rmdir(template);
 
@@ -1085,10 +1079,10 @@ int setup_volatile(
 
 fail:
         if (bind_mounted)
-                (void) umount(t);
+                (void) umount_verbose(t);
 
         if (tmpfs_mounted)
-                (void) umount(template);
+                (void) umount_verbose(template);
         (void) rmdir(template);
         return r;
 }
index d62b8c6..d95204f 100644 (file)
@@ -1316,14 +1316,10 @@ static int setup_resolv_conf(const char *dest) {
                  * advantage that the container will be able to follow the host's DNS server configuration changes
                  * transparently. */
 
-                if (mount("/usr/lib/systemd/resolv.conf", where, NULL, MS_BIND, NULL) < 0)
-                        log_warning_errno(errno, "Failed to mount /etc/resolv.conf in the container, ignoring: %m");
-                else {
-                        if (mount(NULL, where, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL) < 0)
-                                return log_error_errno(errno, "Failed to remount /etc/resolv.conf read-only: %m");
-
-                        return 0;
-                }
+                r = mount_verbose(LOG_WARNING, "/usr/lib/systemd/resolv.conf", where, NULL, MS_BIND, NULL);
+                if (r >= 0)
+                        return mount_verbose(LOG_ERR, NULL, where, NULL,
+                                             MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL);
         }
 
         /* If that didn't work, let's copy the file */
@@ -1365,10 +1361,10 @@ static int setup_boot_id(const char *dest) {
         if (r < 0)
                 return log_error_errno(r, "Failed to write boot id: %m");
 
-        if (mount(from, to, NULL, MS_BIND, NULL) < 0)
-                r = log_error_errno(errno, "Failed to bind mount boot id: %m");
-        else if (mount(NULL, to, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL) < 0)
-                r = log_error_errno(errno, "Failed to make boot id read-only: %m");
+        r = mount_verbose(LOG_ERR, from, to, NULL, MS_BIND, NULL);
+        if (r >= 0)
+                r = mount_verbose(LOG_ERR, NULL, to, NULL,
+                                  MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL);
 
         (void) unlink(from);
         return r;
@@ -1430,8 +1426,9 @@ static int copy_devnodes(const char *dest) {
                                 r = touch(to);
                                 if (r < 0)
                                         return log_error_errno(r, "touch (%s) failed: %m", to);
-                                if (mount(from, to, NULL, MS_BIND, NULL) < 0)
-                                        return log_error_errno(errno, "Both mknod and bind mount (%s) failed: %m", to);
+                                r = mount_verbose(LOG_DEBUG, from, to, NULL, MS_BIND, NULL);
+                                if (r < 0)
+                                        return log_error_errno(r, "Both mknod and bind mount (%s) failed: %m", to);
                         }
 
                         r = userns_lchown(to, 0, 0);
@@ -1467,8 +1464,9 @@ static int setup_pts(const char *dest) {
         p = prefix_roota(dest, "/dev/pts");
         if (mkdir(p, 0755) < 0)
                 return log_error_errno(errno, "Failed to create /dev/pts: %m");
-        if (mount("devpts", p, "devpts", MS_NOSUID|MS_NOEXEC, options) < 0)
-                return log_error_errno(errno, "Failed to mount /dev/pts: %m");
+        r = mount_verbose(LOG_ERR, "devpts", p, "devpts", MS_NOSUID|MS_NOEXEC, options);
+        if (r < 0)
+                return r;
         r = userns_lchown(p, 0, 0);
         if (r < 0)
                 return log_error_errno(r, "Failed to chown /dev/pts: %m");
@@ -1513,10 +1511,7 @@ static int setup_dev_console(const char *dest, const char *console) {
         if (r < 0)
                 return log_error_errno(r, "touch() for /dev/console failed: %m");
 
-        if (mount(console, to, NULL, MS_BIND, NULL) < 0)
-                return log_error_errno(errno, "Bind mount for /dev/console failed: %m");
-
-        return 0;
+        return mount_verbose(LOG_ERR, console, to, NULL, MS_BIND, NULL);
 }
 
 static int setup_kmsg(const char *dest, int kmsg_socket) {
@@ -1540,8 +1535,9 @@ static int setup_kmsg(const char *dest, int kmsg_socket) {
 
         if (mkfifo(from, 0600) < 0)
                 return log_error_errno(errno, "mkfifo() for /run/kmsg failed: %m");
-        if (mount(from, to, NULL, MS_BIND, NULL) < 0)
-                return log_error_errno(errno, "Bind mount for /proc/kmsg failed: %m");
+        r = mount_verbose(LOG_ERR, from, to, NULL, MS_BIND, NULL);
+        if (r < 0)
+                return r;
 
         fd = open(from, O_RDWR|O_NDELAY|O_CLOEXEC);
         if (fd < 0)
@@ -1711,7 +1707,8 @@ static int setup_journal(const char *directory) {
         if (r < 0)
                 return log_error_errno(r, "Failed to create %s: %m", q);
 
-        if (mount(p, q, NULL, MS_BIND, NULL) < 0)
+        r = mount_verbose(LOG_DEBUG, p, q, NULL, MS_BIND, NULL);
+        if (r < 0)
                 return log_error_errno(errno, "Failed to bind mount journal from host into guest: %m");
 
         return 0;
@@ -1776,18 +1773,17 @@ static int setup_propagate(const char *root) {
                 return log_error_errno(r, "Failed to create /run/systemd/nspawn/incoming: %m");
 
         q = prefix_roota(root, "/run/systemd/nspawn/incoming");
-        if (mount(p, q, NULL, MS_BIND, NULL) < 0)
-                return log_error_errno(errno, "Failed to install propagation bind mount.");
+        r = mount_verbose(LOG_ERR, p, q, NULL, MS_BIND, NULL);
+        if (r < 0)
+                return r;
 
-        if (mount(NULL, q, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0)
-                return log_error_errno(errno, "Failed to make propagation mount read-only");
+        r = mount_verbose(LOG_ERR, NULL, q, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
+        if (r < 0)
+                return r;
 
         /* machined will MS_MOVE into that directory, and that's only
          * supported for non-shared mounts. */
-        if (mount(NULL, q, NULL, MS_SLAVE, NULL) < 0)
-                return log_error_errno(errno, "Failed to make propagation mount slave");
-
-        return 0;
+        return mount_verbose(LOG_ERR, NULL, q, NULL, MS_SLAVE, NULL);
 }
 
 static int setup_image(char **device_path, int *loop_nr) {
@@ -2313,10 +2309,7 @@ static int mount_device(const char *what, const char *where, const char *directo
                 return -EOPNOTSUPP;
         }
 
-        if (mount(what, p, fstype, MS_NODEV|(rw ? 0 : MS_RDONLY), NULL) < 0)
-                return log_error_errno(errno, "Failed to mount %s: %m", what);
-
-        return 0;
+        return mount_verbose(LOG_ERR, what, p, fstype, MS_NODEV|(rw ? 0 : MS_RDONLY), NULL);
 #else
         log_error("--image= is not supported, compiled without blkid support.");
         return -EOPNOTSUPP;
@@ -2976,8 +2969,9 @@ static int outer_child(
         /* Mark everything as slave, so that we still
          * receive mounts from the real root, but don't
          * propagate mounts to the real root. */
-        if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0)
-                return log_error_errno(errno, "MS_SLAVE|MS_REC failed: %m");
+        r = mount_verbose(LOG_ERR, NULL, "/", NULL, MS_SLAVE|MS_REC, NULL);
+        if (r < 0)
+                return r;
 
         r = mount_devices(directory,
                           root_device, root_device_rw,
@@ -3023,8 +3017,9 @@ static int outer_child(
         }
 
         /* Turn directory into bind mount */
-        if (mount(directory, directory, NULL, MS_BIND|MS_REC, NULL) < 0)
-                return log_error_errno(errno, "Failed to make bind mount: %m");
+        r = mount_verbose(LOG_ERR, directory, directory, NULL, MS_BIND|MS_REC, NULL);
+        if (r < 0)
+                return r;
 
         /* Mark everything as shared so our mounts get propagated down. This is
          * required to make new bind mounts available in systemd services
@@ -3032,8 +3027,9 @@ static int outer_child(
          * See https://github.com/systemd/systemd/issues/3860
          * Further submounts (such as /dev) done after this will inherit the
          * shared propagation mode.*/
-        if (mount(NULL, directory, NULL, MS_SHARED|MS_REC, NULL) < 0)
-                return log_error_errno(errno, "MS_SHARED|MS_REC failed: %m");
+        r = mount_verbose(LOG_ERR, NULL, directory, NULL, MS_SHARED|MS_REC, NULL);
+        if (r < 0)
+                return r;
 
         r = recursive_chown(directory, arg_uid_shift, arg_uid_range);
         if (r < 0)