mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-07 04:07:17 +00:00
lxc: Move lxcContainerAvailable to virprocess
Other drivers (like qemu) would like to know if the namespaces are available therefore it makes sense to move this function to a shared module. At the same time, this function had some default namespaces that are checked with every call. It is not necessary - let callers pass just those namespaces they are interested in. With the move the function is renamed to virProcessNamespaceAvailable. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
2ff8c30548
commit
083fcd06d3
@ -2275,6 +2275,7 @@ virProcessGetPids;
|
||||
virProcessGetStartTime;
|
||||
virProcessKill;
|
||||
virProcessKillPainfully;
|
||||
virProcessNamespaceAvailable;
|
||||
virProcessRunInMountNamespace;
|
||||
virProcessSchedPolicyTypeFromString;
|
||||
virProcessSchedPolicyTypeToString;
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -2265,7 +2264,7 @@ static int lxcContainerChild(void *data)
|
||||
|
||||
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)
|
||||
@ -2399,47 +2398,6 @@ int lxcContainerStart(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;
|
||||
|
@ -28,11 +28,6 @@
|
||||
# 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
|
||||
@ -65,8 +60,6 @@ int lxcContainerStart(virDomainDefPtr def,
|
||||
size_t nttyPaths,
|
||||
char **ttyPaths);
|
||||
|
||||
int lxcContainerAvailable(int features);
|
||||
|
||||
int lxcContainerSetupHostdevCapsMakePath(const char *dev);
|
||||
|
||||
virArch lxcContainerGetAlt32bitArch(virArch arch);
|
||||
|
@ -1575,7 +1575,7 @@ static int lxcCheckNetNsSupport(void)
|
||||
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;
|
||||
@ -1633,7 +1633,10 @@ static int lxcStateInitialize(bool privileged,
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
@ -1183,6 +1183,78 @@ virProcessSetupPrivateMountNS(void)
|
||||
}
|
||||
#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:
|
||||
|
@ -95,5 +95,15 @@ int virProcessSetupPrivateMountNS(void);
|
||||
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__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user