diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-01-14 19:48:04 -0500 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-01-14 21:29:27 -0500 |
commit | 6b3d378331fe714c7bf2263eaa9a8b33fc878e7c (patch) | |
tree | 5fca867e0b2cda62c2dc4f1a9a4bd78ab345b158 /src/nspawn | |
parent | ab8864ebc3ac01288729b44f0d5f18fff37defb5 (diff) | |
parent | bafbac4e85a5eefd4b57a5cd0eb61885fb60edc9 (diff) |
Merge pull request #4879 from poettering/systemd
Diffstat (limited to 'src/nspawn')
-rw-r--r-- | src/nspawn/nspawn-mount.c | 18 | ||||
-rw-r--r-- | src/nspawn/nspawn-mount.h | 11 | ||||
-rw-r--r-- | src/nspawn/nspawn.c | 77 |
3 files changed, 49 insertions, 57 deletions
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c index aaa64a7ba8..72c007f204 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -1349,21 +1349,3 @@ fail: (void) rmdir(template); return r; } - -VolatileMode volatile_mode_from_string(const char *s) { - int b; - - if (isempty(s)) - return _VOLATILE_MODE_INVALID; - - b = parse_boolean(s); - if (b > 0) - return VOLATILE_YES; - if (b == 0) - return VOLATILE_NO; - - if (streq(s, "state")) - return VOLATILE_STATE; - - return _VOLATILE_MODE_INVALID; -} diff --git a/src/nspawn/nspawn-mount.h b/src/nspawn/nspawn-mount.h index 467082a737..6b33fbff57 100644 --- a/src/nspawn/nspawn-mount.h +++ b/src/nspawn/nspawn-mount.h @@ -22,6 +22,7 @@ #include <stdbool.h> #include "cgroup-util.h" +#include "volatile-util.h" typedef enum MountSettingsMask { MOUNT_FATAL = 1 << 0, /* if set, a mount error is considered fatal */ @@ -32,14 +33,6 @@ typedef enum MountSettingsMask { Works only if MOUNT_APPLY_APIVFS_RO is also set. */ } MountSettingsMask; -typedef enum VolatileMode { - VOLATILE_NO, - VOLATILE_YES, - VOLATILE_STATE, - _VOLATILE_MODE_MAX, - _VOLATILE_MODE_INVALID = -1 -} VolatileMode; - typedef enum CustomMountType { CUSTOM_MOUNT_BIND, CUSTOM_MOUNT_TMPFS, @@ -77,5 +70,3 @@ int mount_custom(const char *dest, CustomMount *mounts, unsigned n, bool userns, int setup_volatile(const char *directory, VolatileMode mode, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context); int setup_volatile_state(const char *directory, VolatileMode mode, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context); - -VolatileMode volatile_mode_from_string(const char *s); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index e366f642c7..6396a69c5c 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1288,15 +1288,18 @@ static int setup_timezone(const char *dest) { return 0; } - r = unlink(where); - if (r < 0 && errno != ENOENT) { - log_error_errno(errno, "Failed to remove existing timezone info %s in container: %m", where); + if (unlink(where) < 0 && errno != ENOENT) { + log_full_errno(IN_SET(errno, EROFS, EACCES, EPERM) ? LOG_DEBUG : LOG_WARNING, /* Don't complain on read-only images */ + errno, + "Failed to remove existing timezone info %s in container, ignoring: %m", where); return 0; } what = strjoina("../usr/share/zoneinfo/", z); if (symlink(what, where) < 0) { - log_error_errno(errno, "Failed to correct timezone of container: %m"); + log_full_errno(IN_SET(errno, EROFS, EACCES, EPERM) ? LOG_DEBUG : LOG_WARNING, + errno, + "Failed to correct timezone of container, ignoring: %m"); return 0; } @@ -1308,31 +1311,43 @@ static int setup_timezone(const char *dest) { } static int setup_resolv_conf(const char *dest) { - const char *where = NULL; - int r; + _cleanup_free_ char *resolved = NULL, *etc = NULL; + const char *where; + int r, found; assert(dest); if (arg_private_network) return 0; - /* Fix resolv.conf, if possible */ - where = prefix_roota(dest, "/etc/resolv.conf"); + r = chase_symlinks("/etc", dest, CHASE_PREFIX_ROOT, &etc); + if (r < 0) { + log_warning_errno(r, "Failed to resolve /etc path in container, ignoring: %m"); + return 0; + } + + where = strjoina(etc, "/resolv.conf"); + found = chase_symlinks(where, dest, CHASE_NONEXISTENT, &resolved); + if (found < 0) { + log_warning_errno(found, "Failed to resolve /etc/resolv.conf path in container, ignoring: %m"); + return 0; + } if (access("/run/systemd/resolve/resolv.conf", F_OK) >= 0 && - access("/usr/lib/systemd/resolv.conf", F_OK) >= 0) { + access("/usr/lib/systemd/resolv.conf", F_OK) >= 0) { + /* resolved is enabled on the host. In this, case bind mount its static resolv.conf file into the * container, so that the container can use the host's resolver. Given that network namespacing is * disabled it's only natural of the container also uses the host's resolver. It also has the big * advantage that the container will be able to follow the host's DNS server configuration changes * transparently. */ - (void) touch(where); + if (found == 0) /* missing? */ + (void) touch(resolved); - r = mount_verbose(LOG_WARNING, "/usr/lib/systemd/resolv.conf", where, NULL, MS_BIND, NULL); + r = mount_verbose(LOG_DEBUG, "/usr/lib/systemd/resolv.conf", resolved, 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); + return mount_verbose(LOG_ERR, NULL, resolved, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL); } /* If that didn't work, let's copy the file */ @@ -1343,7 +1358,7 @@ static int setup_resolv_conf(const char *dest) { * * If the disk image is read-only, there's also no point in complaining. */ - log_full_errno(IN_SET(r, -ELOOP, -EROFS) ? LOG_DEBUG : LOG_WARNING, r, + log_full_errno(IN_SET(r, -ELOOP, -EROFS, -EACCES, -EPERM) ? LOG_DEBUG : LOG_WARNING, r, "Failed to copy /etc/resolv.conf to %s, ignoring: %m", where); return 0; } @@ -2467,20 +2482,6 @@ static int outer_child( 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 - * inside the containter that create a new mount namespace. - * See https://github.com/systemd/systemd/issues/3860 - * Further submounts (such as /dev) done after this will inherit the - * shared propagation mode.*/ - 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) - return r; - r = setup_volatile( directory, arg_volatile_mode, @@ -2501,6 +2502,20 @@ static int outer_child( 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 + * inside the containter that create a new mount namespace. + * See https://github.com/systemd/systemd/issues/3860 + * Further submounts (such as /dev) done after this will inherit the + * shared propagation mode.*/ + 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) + return r; + r = base_filesystem_create(directory, arg_uid_shift, (gid_t) arg_uid_shift); if (r < 0) return r; @@ -3740,7 +3755,11 @@ int main(int argc, char *argv[]) { goto finish; } - r = dissect_image(loop->fd, arg_root_hash, arg_root_hash_size, &dissected_image); + r = dissect_image( + loop->fd, + arg_root_hash, arg_root_hash_size, + DISSECT_IMAGE_REQUIRE_ROOT, + &dissected_image); if (r == -ENOPKG) { log_error_errno(r, "Could not find a suitable file system or partition table in image: %s", arg_image); |