Currently a user can connect to lxc:/// if cgroups aren't mounted, but they can't do a whole lot: starting and even stopping guests doesn't work (the latter only if cgroups were unmounted behind libvirt's back). To make matters worse, even after mounting cgroups, libvirt must be restarted to actually notice. This is frustrating for users who may make it all the way to the end of the virt-manager 'New VM' wizard only to receive an error that requires a libvirtd restart. Fix this by checking for cgroup mounts at lxc:/// connect time, and if none are found, fail the connection. v2: Track 'privileged' in lxc driver even though it isn't much useful at the moment. If it ever becomes useful we want things to just work. Signed-off-by: Cole Robinson <crobinso@xxxxxxxxxx> --- src/lxc/lxc_conf.h | 1 + src/lxc/lxc_driver.c | 33 ++++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/lxc/lxc_conf.h b/src/lxc/lxc_conf.h index 66aa469..7276699 100644 --- a/src/lxc/lxc_conf.h +++ b/src/lxc/lxc_conf.h @@ -54,6 +54,7 @@ struct __lxc_driver { char *logDir; int log_libvirtd; int have_netns; + int privileged : 1; virDomainEventStatePtr domainEventState; }; diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index d0f7158..55e562e 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -107,6 +107,20 @@ static void lxcDomainEventFlush(int timer, void *opaque); static void lxcDomainEventQueue(lxc_driver_t *driver, virDomainEventPtr event); +static int lxcGetCgroup(lxc_driver_t *driver) +{ + if (driver->cgroup) + return 0; + + int rc = virCgroupForDriver("lxc", &driver->cgroup, driver->privileged, 1); + if (rc < 0) { + char buf[1024]; + VIR_DEBUG("Unable to create cgroup for LXC driver: %s", + virStrerror(-rc, buf, sizeof(buf))); + } + + return rc; +} static virDrvOpenStatus lxcOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, @@ -146,6 +160,15 @@ static virDrvOpenStatus lxcOpen(virConnectPtr conn, "%s", _("lxc state driver is not active")); return VIR_DRV_OPEN_ERROR; } + + /* Driver loaded, but no cgroup stuff mounted. Refresh the data + * but error if nothing available */ + if (lxcGetCgroup(lxc_driver) < 0) { + lxcError(VIR_ERR_INTERNAL_ERROR, + _("The 'cpuacct', 'devices' & 'memory' cgroups " + "controllers must be mounted")); + return VIR_DRV_OPEN_ERROR; + } } conn->privateData = lxc_driver; @@ -2063,11 +2086,9 @@ cleanup: virDomainObjUnlock(vm); } - static int lxcStartup(int privileged) { char *ld; - int rc; /* Valgrind gets very annoyed when we clone containers, so * disable LXC when under valgrind @@ -2100,6 +2121,8 @@ static int lxcStartup(int privileged) } lxcDriverLock(lxc_driver); + lxc_driver->privileged = privileged; + if (virDomainObjListInit(&lxc_driver->domains) < 0) goto cleanup; @@ -2113,11 +2136,7 @@ static int lxcStartup(int privileged) lxc_driver->log_libvirtd = 0; /* by default log to container logfile */ lxc_driver->have_netns = lxcCheckNetNsSupport(); - rc = virCgroupForDriver("lxc", &lxc_driver->cgroup, privileged, 1); - if (rc < 0) { - char buf[1024]; - VIR_DEBUG("Unable to create cgroup for LXC driver: %s", - virStrerror(-rc, buf, sizeof(buf))); + if (lxcGetCgroup(lxc_driver) < 0) { /* Don't abort startup. We will explicitly report to * the user when they try to start a VM */ -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list