virProcessGetStartTime;
virProcessKill;
virProcessKillPainfully;
+virProcessNamespaceAvailable;
virProcessRunInMountNamespace;
virProcessSchedPolicyTypeFromString;
virProcessSchedPolicyTypeToString;
#include <config.h>
#include <fcntl.h>
-#include <sched.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
static int userns_supported(void)
{
- return lxcContainerAvailable(LXC_CONTAINER_FEATURE_USER) == 0;
+ return virProcessNamespaceAvailable(VIR_PROCESS_NAMESPACE_USER) == 0;
}
static int userns_required(virDomainDefPtr def)
return pid;
}
-ATTRIBUTE_NORETURN static int
-lxcContainerDummyChild(void *argv ATTRIBUTE_UNUSED)
-{
- _exit(0);
-}
-
-int lxcContainerAvailable(int features)
-{
- int flags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|
- CLONE_NEWIPC|SIGCHLD;
- int cpid;
- char *childStack;
- char *stack;
- int stacksize = getpagesize() * 4;
-
- if (features & LXC_CONTAINER_FEATURE_USER)
- flags |= CLONE_NEWUSER;
-
- if (features & LXC_CONTAINER_FEATURE_NET)
- flags |= CLONE_NEWNET;
-
- if (VIR_ALLOC_N(stack, stacksize) < 0)
- return -1;
-
- childStack = stack + stacksize;
-
- cpid = clone(lxcContainerDummyChild, childStack, flags, NULL);
- VIR_FREE(stack);
- if (cpid < 0) {
- char ebuf[1024] ATTRIBUTE_UNUSED;
- VIR_DEBUG("clone call returned %s, container support is not enabled",
- virStrerror(errno, ebuf, sizeof(ebuf)));
- return -1;
- } else if (virProcessWait(cpid, NULL, false) < 0) {
- return -1;
- }
-
- VIR_DEBUG("container support is enabled");
- return 0;
-}
-
int lxcContainerChown(virDomainDefPtr def, const char *path)
{
uid_t uid;
# include "lxc_domain.h"
# include "security/security_manager.h"
-enum {
- LXC_CONTAINER_FEATURE_NET = (1 << 0),
- LXC_CONTAINER_FEATURE_USER = (1 << 1),
-};
-
# define LXC_DEV_MAJ_MEMORY 1
# define LXC_DEV_MIN_NULL 3
# define LXC_DEV_MIN_ZERO 5
size_t nttyPaths,
char **ttyPaths);
-int lxcContainerAvailable(int features);
-
int lxcContainerSetupHostdevCapsMakePath(const char *dev);
virArch lxcContainerGetAlt32bitArch(virArch arch);
if (virRun(argv, &ip_rc) < 0 || ip_rc == 255)
return 0;
- if (lxcContainerAvailable(LXC_CONTAINER_FEATURE_NET) < 0)
+ if (virProcessNamespaceAvailable(VIR_PROCESS_NAMESPACE_NET) < 0)
return 0;
return 1;
}
/* Check that this is a container enabled kernel */
- if (lxcContainerAvailable(0) < 0) {
+ if (virProcessNamespaceAvailable(VIR_PROCESS_NAMESPACE_MNT |
+ VIR_PROCESS_NAMESPACE_PID |
+ VIR_PROCESS_NAMESPACE_UTS |
+ VIR_PROCESS_NAMESPACE_IPC) < 0) {
VIR_INFO("LXC support not available in this kernel, disabling driver");
return 0;
}
}
#endif /* !defined(HAVE_SYS_MOUNT_H) || !defined(HAVE_UNSHARE) */
+#if defined(__linux__)
+ATTRIBUTE_NORETURN static int
+virProcessDummyChild(void *argv ATTRIBUTE_UNUSED)
+{
+ _exit(0);
+}
+
+/**
+ * virProcessNamespaceAvailable:
+ * @ns: what namespaces to check (bitwise-OR of virProcessNamespaceFlags)
+ *
+ * Check if given list of namespaces (@ns) is available.
+ * If not, appropriate error message is produced.
+ *
+ * Returns: 0 on success (all the namespaces from @flags are available),
+ * -1 on error (with error message reported).
+ */
+int
+virProcessNamespaceAvailable(unsigned int ns)
+{
+ int flags = 0;
+ int cpid;
+ char *childStack;
+ char *stack;
+ int stacksize = getpagesize() * 4;
+
+ if (ns & VIR_PROCESS_NAMESPACE_MNT)
+ flags |= CLONE_NEWNS;
+ if (ns & VIR_PROCESS_NAMESPACE_IPC)
+ flags |= CLONE_NEWIPC;
+ if (ns & VIR_PROCESS_NAMESPACE_NET)
+ flags |= CLONE_NEWNET;
+ if (ns & VIR_PROCESS_NAMESPACE_PID)
+ flags |= CLONE_NEWPID;
+ if (ns & VIR_PROCESS_NAMESPACE_USER)
+ flags |= CLONE_NEWUSER;
+ if (ns & VIR_PROCESS_NAMESPACE_UTS)
+ flags |= CLONE_NEWUTS;
+
+ /* Signal parent as soon as the child dies. RIP. */
+ flags |= SIGCHLD;
+
+ if (VIR_ALLOC_N(stack, stacksize) < 0)
+ return -1;
+
+ childStack = stack + stacksize;
+
+ cpid = clone(virProcessDummyChild, childStack, flags, NULL);
+ VIR_FREE(stack);
+ if (cpid < 0) {
+ char ebuf[1024] ATTRIBUTE_UNUSED;
+ VIR_DEBUG("clone call returned %s, container support is not enabled",
+ virStrerror(errno, ebuf, sizeof(ebuf)));
+ return -1;
+ } else if (virProcessWait(cpid, NULL, false) < 0) {
+ return -1;
+ }
+
+ VIR_DEBUG("All namespaces (%x) are enabled", ns);
+ return 0;
+}
+
+#else /* !defined(__linux__) */
+
+int
+virProcessNamespaceAvailable(unsigned int ns ATTRIBUTE_UNUSED)
+{
+ virReportSystemError(ENOSYS, "%s",
+ _("Namespaces are not supported on this platform."));
+ return -1;
+}
+#endif /* !defined(__linux__) */
/**
* virProcessExitWithStatus:
int virProcessSetScheduler(pid_t pid,
virProcessSchedPolicy policy,
int priority);
+typedef enum {
+ VIR_PROCESS_NAMESPACE_MNT = (1 << 1),
+ VIR_PROCESS_NAMESPACE_IPC = (1 << 2),
+ VIR_PROCESS_NAMESPACE_NET = (1 << 3),
+ VIR_PROCESS_NAMESPACE_PID = (1 << 4),
+ VIR_PROCESS_NAMESPACE_USER = (1 << 5),
+ VIR_PROCESS_NAMESPACE_UTS = (1 << 6),
+} virProcessNamespaceFlags;
+
+int virProcessNamespaceAvailable(unsigned int ns);
#endif /* __VIR_PROCESS_H__ */