diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-08-02 17:58:13 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-08-20 15:58:11 +0200 |
commit | 8dfce114ab16022eb215a1e8ee8851531b71d828 (patch) | |
tree | 10ffb89d6b60c53cc114f60f054eb8d624cda1c3 /src/nspawn | |
parent | namespace: when creating device nodes, also create /dev/char/* symlinks (diff) | |
download | systemd-8dfce114ab16022eb215a1e8ee8851531b71d828.tar.xz systemd-8dfce114ab16022eb215a1e8ee8851531b71d828.zip |
nspawn: make sure to create /dev/char/x:y symlinks in nspawn containers too
On the host udev creates these, but they are useful API, hence create
them in nspawn containers too.
Diffstat (limited to 'src/nspawn')
-rw-r--r-- | src/nspawn/nspawn.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 9a2f72bf29..0e7a904a94 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1792,6 +1792,8 @@ static int copy_devnodes(const char *dest) { return -EIO; } else { + _cleanup_free_ char *sl = NULL, *prefixed = NULL, *dn = NULL, *t = NULL; + if (mknod(to, st.st_mode, st.st_rdev) < 0) { /* Explicitly warn the user when /dev is already populated. */ if (errno == EEXIST) @@ -1799,8 +1801,7 @@ static int copy_devnodes(const char *dest) { if (errno != EPERM) return log_error_errno(errno, "mknod(%s) failed: %m", to); - /* Some systems abusively restrict mknod but - * allow bind mounts. */ + /* Some systems abusively restrict mknod but allow bind mounts. */ r = touch(to); if (r < 0) return log_error_errno(r, "touch (%s) failed: %m", to); @@ -1812,6 +1813,28 @@ static int copy_devnodes(const char *dest) { r = userns_lchown(to, 0, 0); if (r < 0) return log_error_errno(r, "chown() of device node %s failed: %m", to); + + dn = strjoin("/dev/", S_ISCHR(st.st_mode) ? "char" : "block"); + if (!dn) + return log_oom(); + + r = userns_mkdir(dest, dn, 0755, 0, 0); + if (r < 0) + return log_error_errno(r, "Failed to create '%s': %m", dn); + + if (asprintf(&sl, "%s/%u:%u", dn, major(st.st_rdev), minor(st.st_rdev)) < 0) + return log_oom(); + + prefixed = prefix_root(dest, sl); + if (!prefixed) + return log_oom(); + + t = strjoin("../", d); + if (!t) + return log_oom(); + + if (symlink(t, prefixed) < 0) + log_debug_errno(errno, "Failed to symlink '%s' to '%s': %m", t, prefixed); } } |