In enter_net_ns() we try to enter network namespace at first, before
entering a user namespace to support inherited netns case properly.
It is expected to get EPERM for unprivileged container with non-shared
network namespace at first try. Let's take this into account
and stop misleading users with these error messages.
Link: https://discuss.linuxcontainers.org/t/lxc-ls-fancy-command-shows-operation-not-permitted/24080
Fixes: 3011e79f92ef ("lxccontainer: fix enter_net_ns helper to work when netns is inherited")
Fixes: #4560
Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
if (pid < 0)
return false;
- net_ns_entered = switch_to_ns(pid, "net");
+ net_ns_entered = try_switch_to_ns(pid, "net", true);
if ((geteuid() != 0 || (c->lxc_conf && !list_empty(&c->lxc_conf->id_map))) &&
(access("/proc/self/ns/user", F_OK) == 0))
return 0;
}
-bool switch_to_ns(pid_t pid, const char *ns)
+bool try_switch_to_ns(pid_t pid, const char *ns, bool optional)
{
__do_close int fd = -EBADF;
int ret;
return log_error_errno(false, errno, "Failed to open \"%s\"", nspath);
ret = setns(fd, 0);
- if (ret)
- return log_error_errno(false, errno, "Failed to set process %d to \"%s\" of %d", pid, ns, fd);
+ if (ret) {
+ if (optional)
+ return log_trace_errno(false, errno, "Failed to set process %d to \"%s\" of %d", pid, ns, fd);
+ else
+ return log_error_errno(false, errno, "Failed to set process %d to \"%s\" of %d", pid, ns, fd);
+ }
return true;
}
__hidden extern int detect_shared_rootfs(void);
__hidden extern bool detect_ramfs_rootfs(void);
__hidden extern char *on_path(const char *cmd, const char *rootfs);
-__hidden extern bool switch_to_ns(pid_t pid, const char *ns);
+
+__hidden extern bool try_switch_to_ns(pid_t pid, const char *ns, bool optional);
+inline static bool switch_to_ns(pid_t pid, const char *ns)
+{
+ return try_switch_to_ns(pid, ns, false);
+}
+
__hidden extern char *get_template_path(const char *t);
__hidden extern int safe_mount(const char *src, const char *dest, const char *fstype,
unsigned long flags, const void *data, const char *rootfs);