static int preserve_ns(int ns_fd[LXC_NS_MAX], int clone_flags) { int i, saved_errno; char path[MAXPATHLEN]; for (i = 0; i < LXC_NS_MAX; i++) ns_fd[i] = -1; if (access("/proc/self/ns", X_OK)) { WARN("Kernel does not support attach; preserve_ns ignored"); return 0; } for (i = 0; i < LXC_NS_MAX; i++) { if ((clone_flags & ns_info[i].clone_flag) == 0) continue; snprintf(path, MAXPATHLEN, "/proc/self/ns/%s", ns_info[i].proc_name); ns_fd[i] = open(path, O_RDONLY | O_CLOEXEC); if (ns_fd[i] < 0) goto error; } return 0; error: saved_errno = errno; close_ns(ns_fd); errno = saved_errno; SYSERROR("failed to open '%s'", path); return -1; }
/* preserve_ns: open /proc/@pid/ns/@ns for each namespace specified * in clone_flags. * Return true on success, false on failure. */ static bool preserve_ns(int ns_fd[LXC_NS_MAX], int clone_flags, pid_t pid) { int i, ret; for (i = 0; i < LXC_NS_MAX; i++) ns_fd[i] = -1; ret = lxc_preserve_ns(pid, ""); if (ret < 0) { SYSERROR("Kernel does not support attaching to namespaces."); return false; } else { close(ret); } for (i = 0; i < LXC_NS_MAX; i++) { if ((clone_flags & ns_info[i].clone_flag) == 0) continue; ns_fd[i] = lxc_preserve_ns(pid, ns_info[i].proc_name); if (ns_fd[i] < 0) goto error; } return true; error: if (errno == ENOENT) SYSERROR("Kernel does not support attaching to %s namespaces.", ns_info[i].proc_name); else SYSERROR("Failed to open file descriptor for %s namespace: %s.", ns_info[i].proc_name, strerror(errno)); close_ns(ns_fd); return false; }
/* * preserve_ns: open /proc/@pid/ns/@ns for each namespace specified * in clone_flags. * Return true on success, false on failure. On failure, leave an error * message in *errmsg, which caller must free. */ static bool preserve_ns(int ns_fd[LXC_NS_MAX], int clone_flags, pid_t pid, char **errmsg) { int i, ret; char path[MAXPATHLEN]; for (i = 0; i < LXC_NS_MAX; i++) ns_fd[i] = -1; snprintf(path, MAXPATHLEN, "/proc/%d/ns", pid); if (access(path, X_OK)) { if (asprintf(errmsg, "Kernel does not support setns.") == -1) *errmsg = NULL; return false; } for (i = 0; i < LXC_NS_MAX; i++) { if ((clone_flags & ns_info[i].clone_flag) == 0) continue; snprintf(path, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns_info[i].proc_name); ns_fd[i] = open(path, O_RDONLY | O_CLOEXEC); if (ns_fd[i] < 0) goto error; } return true; error: if (errno == ENOENT) { ret = asprintf(errmsg, "Kernel does not support setns for %s", ns_info[i].proc_name); } else { ret = asprintf(errmsg, "Failed to open %s: %s", path, strerror(errno)); } if (ret == -1) *errmsg = NULL; close_ns(ns_fd); return false; }