2008-03-21 15:03:37 +00:00
|
|
|
/*
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
2008-03-21 15:03:37 +00:00
|
|
|
* Copyright IBM Corp. 2008
|
|
|
|
*
|
|
|
|
* lxc_driver.c: linux container driver functions
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* David L. Leskovec <dlesko at linux.vnet.ibm.com>
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2008-04-10 07:30:52 +00:00
|
|
|
#include <fcntl.h>
|
2008-03-21 15:03:37 +00:00
|
|
|
#include <sched.h>
|
|
|
|
#include <sys/utsname.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/types.h>
|
2008-08-13 10:52:15 +00:00
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/un.h>
|
|
|
|
#include <sys/poll.h>
|
2008-03-21 15:03:37 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <wait.h>
|
|
|
|
|
2008-11-04 22:30:33 +00:00
|
|
|
#include "virterror_internal.h"
|
2008-11-06 16:36:07 +00:00
|
|
|
#include "logging.h"
|
2008-11-04 23:22:06 +00:00
|
|
|
#include "datatypes.h"
|
2008-03-21 15:03:37 +00:00
|
|
|
#include "lxc_conf.h"
|
2008-04-10 07:30:52 +00:00
|
|
|
#include "lxc_container.h"
|
2008-03-21 15:03:37 +00:00
|
|
|
#include "lxc_driver.h"
|
2008-06-09 22:51:32 +00:00
|
|
|
#include "memory.h"
|
2008-04-10 07:30:52 +00:00
|
|
|
#include "util.h"
|
2008-06-26 16:09:48 +00:00
|
|
|
#include "bridge.h"
|
|
|
|
#include "veth.h"
|
2008-08-13 10:52:15 +00:00
|
|
|
#include "event.h"
|
2009-06-03 13:29:23 +00:00
|
|
|
#include "nodeinfo.h"
|
2009-07-06 15:05:32 +00:00
|
|
|
#include "uuid.h"
|
2009-11-12 13:55:44 +00:00
|
|
|
#include "stats_linux.h"
|
2010-03-26 15:02:05 +00:00
|
|
|
#include "hooks.h"
|
2010-11-09 20:48:48 +00:00
|
|
|
#include "files.h"
|
2010-10-22 13:40:26 +00:00
|
|
|
#include "fdstream.h"
|
2008-08-13 10:52:15 +00:00
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2009-01-20 17:13:33 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_LXC
|
|
|
|
|
2011-05-05 20:35:00 +00:00
|
|
|
#define START_POSTFIX ": starting up\n"
|
|
|
|
|
2010-10-12 16:39:05 +00:00
|
|
|
#define LXC_NB_MEM_PARAM 3
|
|
|
|
|
2009-11-26 17:56:01 +00:00
|
|
|
typedef struct _lxcDomainObjPrivate lxcDomainObjPrivate;
|
|
|
|
typedef lxcDomainObjPrivate *lxcDomainObjPrivatePtr;
|
|
|
|
struct _lxcDomainObjPrivate {
|
|
|
|
int monitor;
|
|
|
|
int monitorWatch;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-06-12 13:20:13 +00:00
|
|
|
static int lxcStartup(int privileged);
|
2008-03-27 09:34:06 +00:00
|
|
|
static int lxcShutdown(void);
|
2008-03-31 12:02:12 +00:00
|
|
|
static lxc_driver_t *lxc_driver = NULL;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
|
|
|
/* Functions */
|
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
static void lxcDriverLock(lxc_driver_t *driver)
|
|
|
|
{
|
2009-01-15 19:56:05 +00:00
|
|
|
virMutexLock(&driver->lock);
|
2008-12-04 21:12:41 +00:00
|
|
|
}
|
|
|
|
static void lxcDriverUnlock(lxc_driver_t *driver)
|
|
|
|
{
|
2009-01-15 19:56:05 +00:00
|
|
|
virMutexUnlock(&driver->lock);
|
2008-12-04 21:12:41 +00:00
|
|
|
}
|
|
|
|
|
2009-11-26 17:56:01 +00:00
|
|
|
static void *lxcDomainObjPrivateAlloc(void)
|
|
|
|
{
|
|
|
|
lxcDomainObjPrivatePtr priv;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(priv) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
priv->monitor = -1;
|
|
|
|
priv->monitorWatch = -1;
|
|
|
|
|
|
|
|
return priv;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void lxcDomainObjPrivateFree(void *data)
|
|
|
|
{
|
|
|
|
lxcDomainObjPrivatePtr priv = data;
|
|
|
|
|
|
|
|
VIR_FREE(priv);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-06 15:04:36 +00:00
|
|
|
static void lxcDomainEventFlush(int timer, void *opaque);
|
|
|
|
static void lxcDomainEventQueue(lxc_driver_t *driver,
|
|
|
|
virDomainEventPtr event);
|
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
static virDrvOpenStatus lxcOpen(virConnectPtr conn,
|
|
|
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
|
|
|
int flags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
/* Verify uri was specified */
|
2008-11-17 11:44:51 +00:00
|
|
|
if (conn->uri == NULL) {
|
2009-06-12 12:06:15 +00:00
|
|
|
if (lxc_driver == NULL)
|
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
2009-01-30 16:51:33 +00:00
|
|
|
|
2008-11-17 11:44:51 +00:00
|
|
|
conn->uri = xmlParseURI("lxc:///");
|
|
|
|
if (!conn->uri) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-11-17 11:44:51 +00:00
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
}
|
2009-06-12 12:06:15 +00:00
|
|
|
} else {
|
|
|
|
if (conn->uri->scheme == NULL ||
|
|
|
|
STRNEQ(conn->uri->scheme, "lxc"))
|
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
|
|
|
|
|
|
|
/* Leave for remote driver */
|
|
|
|
if (conn->uri->server != NULL)
|
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
|
|
|
|
|
|
|
/* If path isn't '/' then they typoed, tell them correct path */
|
2010-02-11 15:00:25 +00:00
|
|
|
if (conn->uri->path != NULL &&
|
|
|
|
STRNEQ(conn->uri->path, "/")) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("Unexpected LXC URI path '%s', try lxc:///"),
|
2009-06-12 12:06:15 +00:00
|
|
|
conn->uri->path);
|
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
}
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2009-06-12 12:06:15 +00:00
|
|
|
/* URI was good, but driver isn't active */
|
|
|
|
if (lxc_driver == NULL) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
2009-07-23 16:27:47 +00:00
|
|
|
"%s", _("lxc state driver is not active"));
|
2009-06-12 12:06:15 +00:00
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
}
|
|
|
|
}
|
2009-01-30 16:51:33 +00:00
|
|
|
|
2008-03-27 09:34:06 +00:00
|
|
|
conn->privateData = lxc_driver;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
|
|
|
return VIR_DRV_OPEN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lxcClose(virConnectPtr conn)
|
|
|
|
{
|
2009-07-06 15:04:36 +00:00
|
|
|
lxc_driver_t *driver = conn->privateData;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
2011-01-06 17:42:12 +00:00
|
|
|
virDomainEventCallbackListRemoveConn(conn,
|
|
|
|
driver->domainEventState->callbacks);
|
2009-07-06 15:04:36 +00:00
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
2008-03-27 09:34:06 +00:00
|
|
|
conn->privateData = NULL;
|
|
|
|
return 0;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
|
|
|
static int lxcIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
/* Trivially secure, since always inside the daemon */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int lxcIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
/* Not encrypted, but remote driver takes care of that */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-06-03 13:29:23 +00:00
|
|
|
static char *lxcGetCapabilities(virConnectPtr conn) {
|
|
|
|
lxc_driver_t *driver = conn->privateData;
|
|
|
|
char *xml;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2009-06-03 13:29:23 +00:00
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
|
|
|
return xml;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
static virDomainPtr lxcDomainLookupByID(virConnectPtr conn,
|
|
|
|
int id)
|
|
|
|
{
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
virDomainPtr dom = NULL;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
2008-12-04 21:11:41 +00:00
|
|
|
vm = virDomainFindByID(&driver->domains, id);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
if (!vm) {
|
2010-05-03 11:59:03 +00:00
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching id %d"), id);
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
|
2008-12-04 21:11:41 +00:00
|
|
|
if (dom)
|
2008-03-21 15:03:37 +00:00
|
|
|
dom->id = vm->def->id;
|
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
cleanup:
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-03-21 15:03:37 +00:00
|
|
|
return dom;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainPtr lxcDomainLookupByUUID(virConnectPtr conn,
|
|
|
|
const unsigned char *uuid)
|
|
|
|
{
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
virDomainPtr dom = NULL;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
2008-12-04 21:11:41 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, uuid);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
if (!vm) {
|
2010-05-03 11:59:03 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
|
2008-12-04 21:11:41 +00:00
|
|
|
if (dom)
|
2008-03-21 15:03:37 +00:00
|
|
|
dom->id = vm->def->id;
|
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
cleanup:
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-03-21 15:03:37 +00:00
|
|
|
return dom;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainPtr lxcDomainLookupByName(virConnectPtr conn,
|
|
|
|
const char *name)
|
|
|
|
{
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
virDomainPtr dom = NULL;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
2008-12-04 21:11:41 +00:00
|
|
|
vm = virDomainFindByName(&driver->domains, name);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2008-03-21 15:03:37 +00:00
|
|
|
if (!vm) {
|
2010-05-03 11:59:03 +00:00
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching name '%s'"), name);
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
|
2008-12-04 21:11:41 +00:00
|
|
|
if (dom)
|
2008-03-21 15:03:37 +00:00
|
|
|
dom->id = vm->def->id;
|
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
cleanup:
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-03-21 15:03:37 +00:00
|
|
|
return dom;
|
|
|
|
}
|
|
|
|
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
|
|
|
static int lxcDomainIsActive(virDomainPtr dom)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr obj;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
obj = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
if (!obj) {
|
2010-05-03 11:59:03 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
ret = virDomainObjIsActive(obj);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (obj)
|
|
|
|
virDomainObjUnlock(obj);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int lxcDomainIsPersistent(virDomainPtr dom)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr obj;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
obj = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
if (!obj) {
|
2010-05-03 11:59:03 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
ret = obj->persistent;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (obj)
|
|
|
|
virDomainObjUnlock(obj);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-11-24 07:43:15 +00:00
|
|
|
static int lxcDomainIsUpdated(virDomainPtr dom)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr obj;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
obj = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
if (!obj) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
ret = obj->updated;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (obj)
|
|
|
|
virDomainObjUnlock(obj);
|
|
|
|
return ret;
|
|
|
|
}
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
2008-08-13 12:50:55 +00:00
|
|
|
static int lxcListDomains(virConnectPtr conn, int *ids, int nids) {
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = conn->privateData;
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
int n;
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
n = virDomainObjListGetActiveIDs(&driver->domains, ids, nids);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2008-10-10 14:20:37 +00:00
|
|
|
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
return n;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
2008-12-04 21:11:41 +00:00
|
|
|
|
2008-08-13 12:50:55 +00:00
|
|
|
static int lxcNumDomains(virConnectPtr conn) {
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = conn->privateData;
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
int n;
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
n = virDomainObjListNumOfDomains(&driver->domains, 1);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2008-08-13 12:50:55 +00:00
|
|
|
return n;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int lxcListDefinedDomains(virConnectPtr conn,
|
2008-08-13 12:50:55 +00:00
|
|
|
char **const names, int nnames) {
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = conn->privateData;
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
int n;
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
n = virDomainObjListGetInactiveNames(&driver->domains, names, nnames);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2008-10-10 14:20:37 +00:00
|
|
|
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
return n;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-08-13 12:50:55 +00:00
|
|
|
static int lxcNumDefinedDomains(virConnectPtr conn) {
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = conn->privateData;
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
int n;
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
n = virDomainObjListNumOfDomains(&driver->domains, 0);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2008-08-13 12:50:55 +00:00
|
|
|
return n;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
2008-08-13 12:50:55 +00:00
|
|
|
|
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
|
|
|
|
{
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = conn->privateData;
|
|
|
|
virDomainDefPtr def = NULL;
|
2008-12-04 21:12:41 +00:00
|
|
|
virDomainObjPtr vm = NULL;
|
2008-12-04 21:11:41 +00:00
|
|
|
virDomainPtr dom = NULL;
|
2009-07-06 15:04:36 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2009-11-02 18:37:38 +00:00
|
|
|
int dupVM;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
2010-02-09 18:58:01 +00:00
|
|
|
if (!(def = virDomainDefParseString(driver->caps, xml,
|
2009-01-08 13:54:20 +00:00
|
|
|
VIR_DOMAIN_XML_INACTIVE)))
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2009-11-02 18:37:38 +00:00
|
|
|
if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0)
|
|
|
|
goto cleanup;
|
2009-07-31 14:25:03 +00:00
|
|
|
|
2008-06-26 16:08:59 +00:00
|
|
|
if ((def->nets != NULL) && !(driver->have_netns)) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_NO_SUPPORT,
|
avoid many format string warnings
Building with --disable-nls exposed many new warnings like these:
virsh.c:4952: warning: format not a string literal and no format ...
util.c:163: warning: format not a string literal and no format arguments
All but one of the following changes add a "%s" argument before
the offending _(...) argument.
This was the only manual change:
* src/lxc_driver.c (lxcVersion): Use %s and strerror(errno)
rather than %m, to avoid a warning from gcc -Wformat-security.
Add "%s" before each warned about format-string-with-no-%-directive:
* src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML)
(virDomainDefParseString, virDomainDefParseFile):
* src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain)
(__virGetNetwork, virReleaseNetwork, __virGetStoragePool)
(virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol):
* src/lxc_container.c (lxcContainerChild):
* src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine)
(lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML)
(lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart)
(lxcVersion, lxcGetSchedulerParameters):
* src/network_conf.c (virNetworkDefParseString)
(virNetworkDefParseFile):
* src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains):
* src/openvz_driver.c (openvzDomainDefineCmd)
(openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown)
(openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML)
(openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine)
(openvzDomainSetAutostart, openvzDomainGetAutostart)
(openvzDomainSetVcpus):
* src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek):
* src/remote_internal.c (remoteDomainBlockPeek)
(remoteDomainMemoryPeek, remoteAuthPolkit):
* src/sexpr.c (sexpr_new, _string2sexpr):
* src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol)
(virStorageBackendDiskCreateVol):
* src/storage_backend_fs.c
(virStorageBackendFileSystemNetFindPoolSources):
* src/storage_backend_logical.c (virStorageBackendLogicalFindLVs)
(virStorageBackendLogicalFindPoolSources):
* src/test.c (testOpenDefault, testOpenFromFile, testOpen)
(testGetDomainInfo, testDomainRestore)
(testNodeGetCellsFreeMemory):
* src/util.c (virExec):
* src/virsh.c (cmdAttachDevice, cmdDetachDevice)
(cmdAttachInterface, cmdDetachInterface, cmdAttachDisk)
(cmdDetachDisk, cmdEdit):
* src/xend_internal.c (do_connect, wr_sync, xend_op_ext)
(urlencode, xenDaemonDomainCreateXML)
(xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID)
(xenDaemonParseSxprOS, xend_parse_sexp_desc_char)
(xenDaemonParseSxprChar, xenDaemonParseSxprDisks)
(xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain)
(xenDaemonDomainFetch, xenDaemonDomainGetAutostart)
(xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform)
(xenDaemonDomainDefineXML, xenDaemonGetSchedulerType)
(xenDaemonGetSchedulerParameters)
(xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek)
(xenDaemonFormatSxprChr, virDomainXMLDevID):
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu)
(xenXMDomainCreate, xenXMDomainDefineXML)
(xenXMDomainAttachDevice, xenXMDomainDetachDevice):
* src/xml.c (virXPathString, virXPathNumber, virXPathLong)
(virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet):
* src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
|
|
|
"%s", _("System lacks NETNS support"));
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-06-26 16:08:59 +00:00
|
|
|
}
|
|
|
|
|
2010-02-09 18:58:01 +00:00
|
|
|
if (!(vm = virDomainAssignDef(driver->caps,
|
2010-03-24 14:31:21 +00:00
|
|
|
&driver->domains, def, false)))
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
|
|
|
def = NULL;
|
2008-08-20 19:42:36 +00:00
|
|
|
vm->persistent = 1;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2010-02-09 18:58:01 +00:00
|
|
|
if (virDomainSaveConfig(driver->configDir,
|
2008-08-20 19:42:36 +00:00
|
|
|
vm->newDef ? vm->newDef : vm->def) < 0) {
|
2008-08-13 12:50:55 +00:00
|
|
|
virDomainRemoveInactive(&driver->domains, vm);
|
2008-12-04 21:12:41 +00:00
|
|
|
vm = NULL;
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
2009-07-06 15:04:36 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_DEFINED,
|
2009-11-02 18:37:38 +00:00
|
|
|
!dupVM ?
|
2009-07-06 15:04:36 +00:00
|
|
|
VIR_DOMAIN_EVENT_DEFINED_ADDED :
|
|
|
|
VIR_DOMAIN_EVENT_DEFINED_UPDATED);
|
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
|
2008-12-04 21:11:41 +00:00
|
|
|
if (dom)
|
2008-03-21 15:03:37 +00:00
|
|
|
dom->id = vm->def->id;
|
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
cleanup:
|
|
|
|
virDomainDefFree(def);
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2009-07-06 15:04:36 +00:00
|
|
|
if (event)
|
|
|
|
lxcDomainEventQueue(driver, event);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2008-03-21 15:03:37 +00:00
|
|
|
return dom;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lxcDomainUndefine(virDomainPtr dom)
|
|
|
|
{
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2009-07-06 15:04:36 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2008-12-04 21:11:41 +00:00
|
|
|
int ret = -1;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
2008-12-04 21:11:41 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-03-21 15:03:37 +00:00
|
|
|
if (!vm) {
|
2010-05-03 11:59:03 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
Rename internal APis
Rename virDomainIsActive to virDomainObjIsActive, and
virInterfaceIsActive to virInterfaceObjIsActive and finally
virNetworkIsActive to virNetworkObjIsActive.
* src/conf/domain_conf.c, src/conf/domain_conf.h,
src/conf/interface_conf.h, src/conf/network_conf.c,
src/conf/network_conf.h, src/lxc/lxc_driver.c,
src/network/bridge_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_driver.c, src/qemu/qemu_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c: Update for
renamed APIs.
2009-10-20 14:51:03 +00:00
|
|
|
if (virDomainObjIsActive(vm)) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_OPERATION_INVALID,
|
2009-11-05 12:39:09 +00:00
|
|
|
"%s", _("Cannot delete active domain"));
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
2008-08-20 19:42:36 +00:00
|
|
|
if (!vm->persistent) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_OPERATION_INVALID,
|
2009-11-05 12:39:09 +00:00
|
|
|
"%s", _("Cannot undefine transient domain"));
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-08-20 19:42:36 +00:00
|
|
|
}
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2010-02-09 18:58:01 +00:00
|
|
|
if (virDomainDeleteConfig(driver->configDir,
|
2008-08-20 19:42:36 +00:00
|
|
|
driver->autostartDir,
|
2008-12-04 21:11:41 +00:00
|
|
|
vm) < 0)
|
|
|
|
goto cleanup;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2009-07-06 15:04:36 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_UNDEFINED,
|
|
|
|
VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
|
|
|
|
|
2008-08-13 12:50:55 +00:00
|
|
|
virDomainRemoveInactive(&driver->domains, vm);
|
2008-12-04 21:12:41 +00:00
|
|
|
vm = NULL;
|
2008-12-04 21:11:41 +00:00
|
|
|
ret = 0;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
cleanup:
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2009-07-06 15:04:36 +00:00
|
|
|
if (event)
|
|
|
|
lxcDomainEventQueue(driver, event);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2008-12-04 21:11:41 +00:00
|
|
|
return ret;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int lxcDomainGetInfo(virDomainPtr dom,
|
|
|
|
virDomainInfoPtr info)
|
|
|
|
{
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2009-03-06 14:44:04 +00:00
|
|
|
virCgroupPtr cgroup = NULL;
|
2010-10-15 08:01:38 +00:00
|
|
|
int ret = -1, rc;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
2008-12-04 21:11:41 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:12:41 +00:00
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
if (!vm) {
|
2010-05-03 11:59:03 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
2011-05-04 09:07:01 +00:00
|
|
|
info->state = virDomainObjGetState(vm, NULL);
|
2008-03-21 15:03:37 +00:00
|
|
|
|
Rename internal APis
Rename virDomainIsActive to virDomainObjIsActive, and
virInterfaceIsActive to virInterfaceObjIsActive and finally
virNetworkIsActive to virNetworkObjIsActive.
* src/conf/domain_conf.c, src/conf/domain_conf.h,
src/conf/interface_conf.h, src/conf/network_conf.c,
src/conf/network_conf.h, src/lxc/lxc_driver.c,
src/network/bridge_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_driver.c, src/qemu/qemu_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c: Update for
renamed APIs.
2009-10-20 14:51:03 +00:00
|
|
|
if (!virDomainObjIsActive(vm) || driver->cgroup == NULL) {
|
2008-03-21 15:03:37 +00:00
|
|
|
info->cpuTime = 0;
|
2010-10-12 14:43:39 +00:00
|
|
|
info->memory = vm->def->mem.cur_balloon;
|
2008-03-21 15:03:37 +00:00
|
|
|
} else {
|
2009-07-10 10:40:04 +00:00
|
|
|
if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("Unable to get cgroup for %s"), vm->def->name);
|
2009-03-06 14:44:04 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virCgroupGetCpuacctUsage(cgroup, &(info->cpuTime)) < 0) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_OPERATION_FAILED,
|
2009-11-05 12:39:09 +00:00
|
|
|
"%s", _("Cannot read cputime for domain"));
|
2009-10-07 13:26:23 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-10-15 08:01:38 +00:00
|
|
|
if ((rc = virCgroupGetMemoryUsage(cgroup, &(info->memory))) < 0) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_OPERATION_FAILED,
|
2009-11-05 12:39:09 +00:00
|
|
|
"%s", _("Cannot read memory usage for domain"));
|
2010-10-15 08:01:38 +00:00
|
|
|
if (rc == -ENOENT) {
|
|
|
|
/* Don't fail if we can't read memory usage due to a lack of
|
|
|
|
* kernel support */
|
|
|
|
info->memory = 0;
|
|
|
|
} else
|
|
|
|
goto cleanup;
|
2009-03-06 14:44:04 +00:00
|
|
|
}
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
2010-10-12 14:43:39 +00:00
|
|
|
info->maxMem = vm->def->mem.max_balloon;
|
2008-03-21 15:03:37 +00:00
|
|
|
info->nrVirtCpu = 1;
|
2008-12-04 21:11:41 +00:00
|
|
|
ret = 0;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
cleanup:
|
2009-09-02 13:02:06 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2009-03-06 14:44:04 +00:00
|
|
|
if (cgroup)
|
|
|
|
virCgroupFree(&cgroup);
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:11:41 +00:00
|
|
|
return ret;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
2011-05-02 09:35:29 +00:00
|
|
|
static int
|
|
|
|
lxcDomainGetState(virDomainPtr dom,
|
|
|
|
int *state,
|
|
|
|
int *reason,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
|
|
|
if (!vm) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-05-04 09:07:01 +00:00
|
|
|
*state = virDomainObjGetState(vm, reason);
|
2011-05-02 09:35:29 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-08-13 12:50:55 +00:00
|
|
|
static char *lxcGetOSType(virDomainPtr dom)
|
2008-03-21 15:03:37 +00:00
|
|
|
{
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
char *ret = NULL;
|
2008-08-13 12:50:55 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
2008-12-04 21:11:41 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
2008-08-13 12:50:55 +00:00
|
|
|
if (!vm) {
|
2010-05-03 11:59:03 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-08-13 12:50:55 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
ret = strdup(vm->def->os.type);
|
|
|
|
|
2009-11-08 21:08:54 +00:00
|
|
|
if (ret == NULL)
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2009-11-08 21:08:54 +00:00
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
cleanup:
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:11:41 +00:00
|
|
|
return ret;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
2009-10-07 13:26:23 +00:00
|
|
|
/* Returns max memory in kb, 0 if error */
|
|
|
|
static unsigned long lxcDomainGetMaxMemory(virDomainPtr dom) {
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
unsigned long ret = 0;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
|
|
|
if (!vm) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2009-10-07 13:26:23 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-10-12 14:43:39 +00:00
|
|
|
ret = vm->def->mem.max_balloon;
|
2009-10-07 13:26:23 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lxcDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) {
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
|
|
|
if (!vm) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2009-10-07 13:26:23 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-10-12 14:43:39 +00:00
|
|
|
if (newmax < vm->def->mem.cur_balloon) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_INVALID_ARG,
|
2009-11-05 12:39:09 +00:00
|
|
|
"%s", _("Cannot set max memory lower than current memory"));
|
2009-10-07 13:26:23 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-10-12 14:43:39 +00:00
|
|
|
vm->def->mem.max_balloon = newmax;
|
2009-10-07 13:26:23 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lxcDomainSetMemory(virDomainPtr dom, unsigned long newmem) {
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
virCgroupPtr cgroup = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
if (!vm) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2009-10-07 13:26:23 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-10-12 14:43:39 +00:00
|
|
|
if (newmem > vm->def->mem.max_balloon) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_INVALID_ARG,
|
2009-11-05 12:39:09 +00:00
|
|
|
"%s", _("Cannot set memory higher than max memory"));
|
2009-10-07 13:26:23 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-05-03 12:02:56 +00:00
|
|
|
if (!virDomainObjIsActive(vm)) {
|
|
|
|
lxcError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
"%s", _("Domain is not running"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-03-22 15:42:14 +00:00
|
|
|
|
2010-05-03 12:02:56 +00:00
|
|
|
if (driver->cgroup == NULL) {
|
|
|
|
lxcError(VIR_ERR_NO_SUPPORT,
|
|
|
|
"%s", _("cgroups must be configured on the host"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-10-07 13:26:23 +00:00
|
|
|
|
2010-05-03 12:02:56 +00:00
|
|
|
if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
|
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Unable to get cgroup for %s"), vm->def->name);
|
|
|
|
goto cleanup;
|
2009-10-07 13:26:23 +00:00
|
|
|
}
|
2010-05-03 12:02:56 +00:00
|
|
|
|
|
|
|
if (virCgroupSetMemory(cgroup, newmem) < 0) {
|
|
|
|
lxcError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
"%s", _("Failed to set memory for domain"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2009-10-07 13:26:23 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
if (cgroup)
|
|
|
|
virCgroupFree(&cgroup);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-10-12 16:31:19 +00:00
|
|
|
static int lxcDomainSetMemoryParameters(virDomainPtr dom,
|
2011-05-26 17:39:04 +00:00
|
|
|
virTypedParameterPtr params,
|
2010-10-12 16:31:19 +00:00
|
|
|
int nparams,
|
|
|
|
unsigned int flags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
int i;
|
|
|
|
virCgroupPtr cgroup = NULL;
|
|
|
|
virDomainObjPtr vm = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
|
|
|
|
if (vm == NULL) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
|
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("cannot find cgroup for domain %s"), vm->def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
for (i = 0; i < nparams; i++) {
|
2011-05-26 17:39:04 +00:00
|
|
|
virTypedParameterPtr param = ¶ms[i];
|
2010-10-12 16:31:19 +00:00
|
|
|
|
|
|
|
if (STREQ(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT)) {
|
|
|
|
int rc;
|
2011-05-26 17:39:04 +00:00
|
|
|
if (param->type != VIR_TYPED_PARAM_ULLONG) {
|
2010-10-12 16:31:19 +00:00
|
|
|
lxcError(VIR_ERR_INVALID_ARG, "%s",
|
|
|
|
_("invalid type for memory hard_limit tunable, expected a 'ullong'"));
|
|
|
|
ret = -1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = virCgroupSetMemoryHardLimit(cgroup, params[i].value.ul);
|
|
|
|
if (rc != 0) {
|
|
|
|
virReportSystemError(-rc, "%s",
|
|
|
|
_("unable to set memory hard_limit tunable"));
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
} else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT)) {
|
|
|
|
int rc;
|
2011-05-26 17:39:04 +00:00
|
|
|
if (param->type != VIR_TYPED_PARAM_ULLONG) {
|
2010-10-12 16:31:19 +00:00
|
|
|
lxcError(VIR_ERR_INVALID_ARG, "%s",
|
|
|
|
_("invalid type for memory soft_limit tunable, expected a 'ullong'"));
|
|
|
|
ret = -1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = virCgroupSetMemorySoftLimit(cgroup, params[i].value.ul);
|
|
|
|
if (rc != 0) {
|
|
|
|
virReportSystemError(-rc, "%s",
|
|
|
|
_("unable to set memory soft_limit tunable"));
|
|
|
|
ret = -1;
|
|
|
|
}
|
2010-10-20 11:52:48 +00:00
|
|
|
} else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT)) {
|
2010-10-12 16:31:19 +00:00
|
|
|
int rc;
|
2011-05-26 17:39:04 +00:00
|
|
|
if (param->type != VIR_TYPED_PARAM_ULLONG) {
|
2010-10-12 16:31:19 +00:00
|
|
|
lxcError(VIR_ERR_INVALID_ARG, "%s",
|
|
|
|
_("invalid type for swap_hard_limit tunable, expected a 'ullong'"));
|
|
|
|
ret = -1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2011-03-16 05:07:12 +00:00
|
|
|
rc = virCgroupSetMemSwapHardLimit(cgroup, params[i].value.ul);
|
2010-10-12 16:31:19 +00:00
|
|
|
if (rc != 0) {
|
|
|
|
virReportSystemError(-rc, "%s",
|
|
|
|
_("unable to set swap_hard_limit tunable"));
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
} else if (STREQ(param->field, VIR_DOMAIN_MEMORY_MIN_GUARANTEE)) {
|
|
|
|
lxcError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("Memory tunable `%s' not implemented"), param->field);
|
|
|
|
ret = -1;
|
|
|
|
} else {
|
|
|
|
lxcError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("Parameter `%s' not supported"), param->field);
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (cgroup)
|
|
|
|
virCgroupFree(&cgroup);
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-10-12 16:39:05 +00:00
|
|
|
static int lxcDomainGetMemoryParameters(virDomainPtr dom,
|
2011-05-26 17:39:04 +00:00
|
|
|
virTypedParameterPtr params,
|
2010-10-12 16:39:05 +00:00
|
|
|
int *nparams,
|
|
|
|
unsigned int flags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
int i;
|
|
|
|
virCgroupPtr cgroup = NULL;
|
|
|
|
virDomainObjPtr vm = NULL;
|
2011-01-13 09:18:11 +00:00
|
|
|
unsigned long long val;
|
2010-10-12 16:39:05 +00:00
|
|
|
int ret = -1;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
|
|
|
|
if (vm == NULL) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*nparams) == 0) {
|
|
|
|
/* Current number of memory parameters supported by cgroups */
|
|
|
|
*nparams = LXC_NB_MEM_PARAM;
|
|
|
|
ret = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2011-05-18 09:33:42 +00:00
|
|
|
if ((*nparams) < LXC_NB_MEM_PARAM) {
|
2010-10-12 16:39:05 +00:00
|
|
|
lxcError(VIR_ERR_INVALID_ARG,
|
|
|
|
"%s", _("Invalid parameter count"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
|
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Unable to get cgroup for %s"), vm->def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-05-18 09:33:42 +00:00
|
|
|
for (i = 0; i < LXC_NB_MEM_PARAM; i++) {
|
2011-05-26 17:39:04 +00:00
|
|
|
virTypedParameterPtr param = ¶ms[i];
|
2010-10-12 16:39:05 +00:00
|
|
|
val = 0;
|
|
|
|
param->value.ul = 0;
|
2011-05-26 17:39:04 +00:00
|
|
|
param->type = VIR_TYPED_PARAM_ULLONG;
|
2010-10-12 16:39:05 +00:00
|
|
|
|
|
|
|
switch(i) {
|
|
|
|
case 0: /* fill memory hard limit here */
|
|
|
|
rc = virCgroupGetMemoryHardLimit(cgroup, &val);
|
|
|
|
if (rc != 0) {
|
|
|
|
virReportSystemError(-rc, "%s",
|
|
|
|
_("unable to get memory hard limit"));
|
2010-11-06 17:52:00 +00:00
|
|
|
goto cleanup;
|
2010-10-12 16:39:05 +00:00
|
|
|
}
|
|
|
|
if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT) == NULL) {
|
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Field memory hard limit too long for destination"));
|
2010-11-06 17:52:00 +00:00
|
|
|
goto cleanup;
|
2010-10-12 16:39:05 +00:00
|
|
|
}
|
|
|
|
param->value.ul = val;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: /* fill memory soft limit here */
|
|
|
|
rc = virCgroupGetMemorySoftLimit(cgroup, &val);
|
|
|
|
if (rc != 0) {
|
|
|
|
virReportSystemError(-rc, "%s",
|
|
|
|
_("unable to get memory soft limit"));
|
2010-11-06 17:52:00 +00:00
|
|
|
goto cleanup;
|
2010-10-12 16:39:05 +00:00
|
|
|
}
|
|
|
|
if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT) == NULL) {
|
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Field memory soft limit too long for destination"));
|
2010-11-06 17:52:00 +00:00
|
|
|
goto cleanup;
|
2010-10-12 16:39:05 +00:00
|
|
|
}
|
|
|
|
param->value.ul = val;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2: /* fill swap hard limit here */
|
2011-03-16 05:07:12 +00:00
|
|
|
rc = virCgroupGetMemSwapHardLimit(cgroup, &val);
|
2010-10-12 16:39:05 +00:00
|
|
|
if (rc != 0) {
|
|
|
|
virReportSystemError(-rc, "%s",
|
|
|
|
_("unable to get swap hard limit"));
|
2010-11-06 17:52:00 +00:00
|
|
|
goto cleanup;
|
2010-10-12 16:39:05 +00:00
|
|
|
}
|
2010-10-20 11:52:48 +00:00
|
|
|
if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT) == NULL) {
|
2010-10-12 16:39:05 +00:00
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Field swap hard limit too long for destination"));
|
2010-11-06 17:52:00 +00:00
|
|
|
goto cleanup;
|
2010-10-12 16:39:05 +00:00
|
|
|
}
|
|
|
|
param->value.ul = val;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
/* should not hit here */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-18 09:33:42 +00:00
|
|
|
*nparams = LXC_NB_MEM_PARAM;
|
2010-11-06 17:52:00 +00:00
|
|
|
ret = 0;
|
|
|
|
|
2010-10-12 16:39:05 +00:00
|
|
|
cleanup:
|
|
|
|
if (cgroup)
|
|
|
|
virCgroupFree(&cgroup);
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-05-06 19:53:10 +00:00
|
|
|
static char *lxcDomainGetXMLDesc(virDomainPtr dom,
|
|
|
|
int flags)
|
2008-03-21 15:03:37 +00:00
|
|
|
{
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
char *ret = NULL;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
2008-12-04 21:11:41 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
if (!vm) {
|
2010-05-03 11:59:03 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
2010-02-09 18:58:01 +00:00
|
|
|
ret = virDomainDefFormat((flags & VIR_DOMAIN_XML_INACTIVE) &&
|
2008-12-04 21:11:41 +00:00
|
|
|
vm->newDef ? vm->newDef : vm->def,
|
|
|
|
flags);
|
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:11:41 +00:00
|
|
|
return ret;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
2008-08-13 10:52:15 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* lxcVmCleanup:
|
2009-11-05 12:35:13 +00:00
|
|
|
* @driver: pointer to driver structure
|
|
|
|
* @vm: pointer to VM to clean up
|
2011-05-04 09:07:01 +00:00
|
|
|
* @reason: reason for switching the VM to shutoff state
|
2008-08-13 10:52:15 +00:00
|
|
|
*
|
2011-02-22 17:35:06 +00:00
|
|
|
* Cleanout resources associated with the now dead VM
|
2008-08-13 10:52:15 +00:00
|
|
|
*
|
|
|
|
*/
|
2011-02-22 17:35:06 +00:00
|
|
|
static void lxcVmCleanup(lxc_driver_t *driver,
|
2011-05-04 09:07:01 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainShutoffReason reason)
|
2008-08-13 10:52:15 +00:00
|
|
|
{
|
2008-10-03 16:46:01 +00:00
|
|
|
virCgroupPtr cgroup;
|
2008-10-10 16:08:01 +00:00
|
|
|
int i;
|
2009-11-26 17:56:01 +00:00
|
|
|
lxcDomainObjPrivatePtr priv = vm->privateData;
|
2008-08-13 10:52:15 +00:00
|
|
|
|
2010-03-26 15:02:05 +00:00
|
|
|
/* now that we know it's stopped call the hook if present */
|
|
|
|
if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
|
|
|
|
char *xml = virDomainDefFormat(vm->def, 0);
|
|
|
|
|
|
|
|
/* we can't stop the operation even if the script raised an error */
|
|
|
|
virHookCall(VIR_HOOK_DRIVER_LXC, vm->def->name,
|
|
|
|
VIR_HOOK_LXC_OP_STOPPED, VIR_HOOK_SUBOP_END, NULL, xml);
|
|
|
|
VIR_FREE(xml);
|
|
|
|
}
|
|
|
|
|
2009-11-26 17:56:01 +00:00
|
|
|
virEventRemoveHandle(priv->monitorWatch);
|
2010-11-09 20:48:48 +00:00
|
|
|
VIR_FORCE_CLOSE(priv->monitor);
|
2008-08-13 10:52:15 +00:00
|
|
|
|
|
|
|
virFileDeletePid(driver->stateDir, vm->def->name);
|
2010-02-09 18:58:01 +00:00
|
|
|
virDomainDeleteConfig(driver->stateDir, NULL, vm);
|
2008-08-13 10:52:15 +00:00
|
|
|
|
2011-05-04 09:07:01 +00:00
|
|
|
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
|
2008-08-13 10:52:15 +00:00
|
|
|
vm->pid = -1;
|
|
|
|
vm->def->id = -1;
|
2009-11-26 17:56:01 +00:00
|
|
|
priv->monitor = -1;
|
|
|
|
priv->monitorWatch = -1;
|
2008-08-13 10:52:15 +00:00
|
|
|
|
2008-10-10 16:08:01 +00:00
|
|
|
for (i = 0 ; i < vm->def->nnets ; i++) {
|
|
|
|
vethInterfaceUpOrDown(vm->def->nets[i]->ifname, 0);
|
|
|
|
vethDelete(vm->def->nets[i]->ifname);
|
2008-08-22 15:35:37 +00:00
|
|
|
}
|
|
|
|
|
2009-07-10 10:40:04 +00:00
|
|
|
if (driver->cgroup &&
|
|
|
|
virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) == 0) {
|
2008-10-03 16:46:01 +00:00
|
|
|
virCgroupRemove(cgroup);
|
|
|
|
virCgroupFree(&cgroup);
|
|
|
|
}
|
|
|
|
|
2009-07-06 15:04:36 +00:00
|
|
|
if (vm->newDef) {
|
|
|
|
virDomainDefFree(vm->def);
|
|
|
|
vm->def = vm->newDef;
|
|
|
|
vm->def->id = -1;
|
|
|
|
vm->newDef = NULL;
|
|
|
|
}
|
2008-08-13 10:52:15 +00:00
|
|
|
}
|
|
|
|
|
2008-06-26 16:09:48 +00:00
|
|
|
/**
|
|
|
|
* lxcSetupInterfaces:
|
2009-11-05 12:35:13 +00:00
|
|
|
* @conn: pointer to connection
|
2008-08-13 10:52:15 +00:00
|
|
|
* @def: pointer to virtual machine structure
|
2009-11-05 12:35:13 +00:00
|
|
|
* @nveths: number of interfaces
|
|
|
|
* @veths: interface names
|
2008-06-26 16:09:48 +00:00
|
|
|
*
|
|
|
|
* Sets up the container interfaces by creating the veth device pairs and
|
|
|
|
* attaching the parent end to the appropriate bridge. The container end
|
|
|
|
* will moved into the container namespace later after clone has been called.
|
|
|
|
*
|
|
|
|
* Returns 0 on success or -1 in case of error
|
|
|
|
*/
|
|
|
|
static int lxcSetupInterfaces(virConnectPtr conn,
|
2008-08-13 12:50:55 +00:00
|
|
|
virDomainDefPtr def,
|
2008-08-13 10:52:15 +00:00
|
|
|
unsigned int *nveths,
|
|
|
|
char ***veths)
|
2008-06-26 16:09:48 +00:00
|
|
|
{
|
2008-10-10 16:08:01 +00:00
|
|
|
int rc = -1, i;
|
2008-08-13 10:52:15 +00:00
|
|
|
char *bridge = NULL;
|
|
|
|
brControl *brctl = NULL;
|
2011-03-17 15:54:24 +00:00
|
|
|
int ret;
|
2008-06-26 16:09:48 +00:00
|
|
|
|
2011-03-17 15:54:24 +00:00
|
|
|
if ((ret = brInit(&brctl)) != 0) {
|
|
|
|
virReportSystemError(ret, "%s",
|
|
|
|
_("Unable to initialize bridging"));
|
2008-06-26 16:09:48 +00:00
|
|
|
return -1;
|
2011-03-17 15:54:24 +00:00
|
|
|
}
|
2008-06-26 16:09:48 +00:00
|
|
|
|
2008-10-10 16:08:01 +00:00
|
|
|
for (i = 0 ; i < def->nnets ; i++) {
|
2010-08-31 22:04:46 +00:00
|
|
|
char *parentVeth;
|
|
|
|
char *containerVeth = NULL;
|
2010-05-03 09:13:26 +00:00
|
|
|
|
2008-10-10 16:08:01 +00:00
|
|
|
switch (def->nets[i]->type) {
|
2008-08-13 12:50:55 +00:00
|
|
|
case VIR_DOMAIN_NET_TYPE_NETWORK:
|
|
|
|
{
|
2010-08-31 22:04:46 +00:00
|
|
|
virNetworkPtr network;
|
|
|
|
|
|
|
|
network = virNetworkLookupByName(conn,
|
|
|
|
def->nets[i]->data.network.name);
|
2008-06-26 16:09:48 +00:00
|
|
|
if (!network) {
|
|
|
|
goto error_exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
bridge = virNetworkGetBridgeName(network);
|
|
|
|
|
|
|
|
virNetworkFree(network);
|
2008-08-13 12:50:55 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case VIR_DOMAIN_NET_TYPE_BRIDGE:
|
2008-10-10 16:08:01 +00:00
|
|
|
bridge = def->nets[i]->data.bridge.brname;
|
2008-08-13 12:50:55 +00:00
|
|
|
break;
|
2010-03-26 16:01:35 +00:00
|
|
|
|
|
|
|
case VIR_DOMAIN_NET_TYPE_USER:
|
|
|
|
case VIR_DOMAIN_NET_TYPE_ETHERNET:
|
|
|
|
case VIR_DOMAIN_NET_TYPE_SERVER:
|
|
|
|
case VIR_DOMAIN_NET_TYPE_CLIENT:
|
|
|
|
case VIR_DOMAIN_NET_TYPE_MCAST:
|
|
|
|
case VIR_DOMAIN_NET_TYPE_INTERNAL:
|
|
|
|
case VIR_DOMAIN_NET_TYPE_DIRECT:
|
|
|
|
case VIR_DOMAIN_NET_TYPE_LAST:
|
|
|
|
break;
|
2008-06-26 16:09:48 +00:00
|
|
|
}
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("bridge: %s", bridge);
|
2008-06-26 16:09:48 +00:00
|
|
|
if (NULL == bridge) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
2009-11-05 12:39:09 +00:00
|
|
|
"%s", _("Failed to get bridge for interface"));
|
2008-06-26 16:09:48 +00:00
|
|
|
goto error_exit;
|
|
|
|
}
|
|
|
|
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("calling vethCreate()");
|
2010-08-31 22:04:46 +00:00
|
|
|
parentVeth = def->nets[i]->ifname;
|
|
|
|
if (vethCreate(&parentVeth, &containerVeth) < 0)
|
2008-06-26 16:09:48 +00:00
|
|
|
goto error_exit;
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("parentVeth: %s, containerVeth: %s", parentVeth, containerVeth);
|
2010-07-23 17:25:56 +00:00
|
|
|
|
2008-10-10 16:08:01 +00:00
|
|
|
if (NULL == def->nets[i]->ifname) {
|
2010-08-31 22:04:46 +00:00
|
|
|
def->nets[i]->ifname = parentVeth;
|
2008-06-26 16:09:48 +00:00
|
|
|
}
|
2010-08-31 22:04:46 +00:00
|
|
|
|
2009-11-08 21:08:54 +00:00
|
|
|
if (VIR_REALLOC_N(*veths, (*nveths)+1) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2010-08-31 22:04:46 +00:00
|
|
|
VIR_FREE(containerVeth);
|
2008-08-13 10:52:15 +00:00
|
|
|
goto error_exit;
|
2009-11-08 21:08:54 +00:00
|
|
|
}
|
2010-08-31 22:04:46 +00:00
|
|
|
(*veths)[(*nveths)] = containerVeth;
|
2009-11-08 21:08:54 +00:00
|
|
|
(*nveths)++;
|
2008-06-26 16:09:48 +00:00
|
|
|
|
2010-01-18 08:49:57 +00:00
|
|
|
{
|
2009-10-21 10:04:02 +00:00
|
|
|
char macaddr[VIR_MAC_STRING_BUFLEN];
|
|
|
|
virFormatMacAddr(def->nets[i]->mac, macaddr);
|
2010-07-23 17:25:56 +00:00
|
|
|
if (setMacAddr(containerVeth, macaddr) < 0)
|
2009-10-21 10:04:02 +00:00
|
|
|
goto error_exit;
|
|
|
|
}
|
|
|
|
|
2011-03-17 15:54:24 +00:00
|
|
|
if ((ret = brAddInterface(brctl, bridge, parentVeth)) != 0) {
|
2011-05-03 20:30:34 +00:00
|
|
|
virReportSystemError(ret,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("Failed to add %s device to %s"),
|
2009-01-20 17:13:33 +00:00
|
|
|
parentVeth, bridge);
|
2008-06-26 16:09:48 +00:00
|
|
|
goto error_exit;
|
|
|
|
}
|
|
|
|
|
2010-07-23 17:25:56 +00:00
|
|
|
if (vethInterfaceUpOrDown(parentVeth, 1) < 0)
|
2008-06-26 16:09:48 +00:00
|
|
|
goto error_exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
|
|
|
|
error_exit:
|
2008-08-13 10:52:15 +00:00
|
|
|
brShutdown(brctl);
|
2008-06-26 16:09:48 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2010-02-09 18:22:56 +00:00
|
|
|
static int lxcMonitorClient(lxc_driver_t * driver,
|
2008-08-13 12:50:55 +00:00
|
|
|
virDomainObjPtr vm)
|
2008-04-10 07:30:52 +00:00
|
|
|
{
|
2008-08-13 10:52:15 +00:00
|
|
|
char *sockpath = NULL;
|
|
|
|
int fd;
|
|
|
|
struct sockaddr_un addr;
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(&sockpath, "%s/%s.sock",
|
|
|
|
driver->stateDir, vm->def->name) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-08-13 10:52:15 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno, "%s",
|
2009-11-05 12:39:09 +00:00
|
|
|
_("Failed to create client socket"));
|
2008-08-13 10:52:15 +00:00
|
|
|
goto error;
|
2008-04-10 07:30:52 +00:00
|
|
|
}
|
|
|
|
|
2008-08-13 10:52:15 +00:00
|
|
|
memset(&addr, 0, sizeof(addr));
|
|
|
|
addr.sun_family = AF_UNIX;
|
2009-08-03 12:37:44 +00:00
|
|
|
if (virStrcpyStatic(addr.sun_path, sockpath) == NULL) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
2009-08-03 12:37:44 +00:00
|
|
|
_("Socket path %s too big for destination"), sockpath);
|
|
|
|
goto error;
|
|
|
|
}
|
2008-08-13 10:52:15 +00:00
|
|
|
|
|
|
|
if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno, "%s",
|
2009-11-05 12:39:09 +00:00
|
|
|
_("Failed to connect to client socket"));
|
2008-08-13 10:52:15 +00:00
|
|
|
goto error;
|
2008-04-10 07:30:52 +00:00
|
|
|
}
|
|
|
|
|
2008-08-13 10:52:15 +00:00
|
|
|
VIR_FREE(sockpath);
|
|
|
|
return fd;
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2008-08-13 10:52:15 +00:00
|
|
|
error:
|
|
|
|
VIR_FREE(sockpath);
|
2010-11-09 20:48:48 +00:00
|
|
|
VIR_FORCE_CLOSE(fd);
|
2008-08-13 10:52:15 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-09 18:22:56 +00:00
|
|
|
static int lxcVmTerminate(lxc_driver_t *driver,
|
2011-05-04 09:07:01 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainShutoffReason reason)
|
2008-08-13 10:52:15 +00:00
|
|
|
{
|
2011-02-22 17:35:06 +00:00
|
|
|
virCgroupPtr group = NULL;
|
|
|
|
int rc;
|
2008-08-13 10:14:47 +00:00
|
|
|
|
2008-08-20 20:55:32 +00:00
|
|
|
if (vm->pid <= 0) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("Invalid PID %d for container"), vm->pid);
|
2008-08-20 20:55:32 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-02-22 17:35:06 +00:00
|
|
|
if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
rc = virCgroupKillPainfully(group);
|
|
|
|
if (rc < 0) {
|
|
|
|
virReportSystemError(-rc, "%s",
|
|
|
|
_("Failed to kill container PIDs"));
|
|
|
|
rc = -1;
|
|
|
|
goto cleanup;
|
2008-04-10 07:30:52 +00:00
|
|
|
}
|
2011-02-22 17:35:06 +00:00
|
|
|
if (rc == 1) {
|
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Some container PIDs refused to die"));
|
|
|
|
rc = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2011-05-04 09:07:01 +00:00
|
|
|
lxcVmCleanup(driver, vm, reason);
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2011-02-22 17:35:06 +00:00
|
|
|
rc = 0;
|
2008-08-13 10:14:47 +00:00
|
|
|
|
2011-02-22 17:35:06 +00:00
|
|
|
cleanup:
|
|
|
|
virCgroupFree(&group);
|
|
|
|
return rc;
|
2008-08-13 10:52:15 +00:00
|
|
|
}
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2008-11-19 16:19:36 +00:00
|
|
|
static void lxcMonitorEvent(int watch,
|
|
|
|
int fd,
|
2008-08-13 10:52:15 +00:00
|
|
|
int events ATTRIBUTE_UNUSED,
|
|
|
|
void *data)
|
|
|
|
{
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
lxc_driver_t *driver = lxc_driver;
|
|
|
|
virDomainObjPtr vm = data;
|
2009-07-06 15:04:36 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2009-11-26 17:56:01 +00:00
|
|
|
lxcDomainObjPrivatePtr priv;
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
virDomainObjLock(vm);
|
|
|
|
lxcDriverUnlock(driver);
|
2008-11-19 16:19:36 +00:00
|
|
|
|
2009-11-26 17:56:01 +00:00
|
|
|
priv = vm->privateData;
|
|
|
|
|
|
|
|
if (priv->monitor != fd || priv->monitorWatch != watch) {
|
2008-11-19 16:19:36 +00:00
|
|
|
virEventRemoveHandle(watch);
|
2008-12-04 21:12:41 +00:00
|
|
|
goto cleanup;
|
2008-04-10 07:30:52 +00:00
|
|
|
}
|
|
|
|
|
2011-05-04 09:07:01 +00:00
|
|
|
if (lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN) < 0) {
|
2008-11-19 16:19:36 +00:00
|
|
|
virEventRemoveHandle(watch);
|
2009-07-06 15:04:36 +00:00
|
|
|
} else {
|
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
|
|
|
|
}
|
2009-07-31 13:38:46 +00:00
|
|
|
if (!vm->persistent) {
|
|
|
|
virDomainRemoveInactive(&driver->domains, vm);
|
|
|
|
vm = NULL;
|
|
|
|
}
|
2008-12-04 21:12:41 +00:00
|
|
|
|
|
|
|
cleanup:
|
2009-11-12 14:13:33 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
if (event) {
|
|
|
|
lxcDriverLock(driver);
|
2009-07-06 15:04:36 +00:00
|
|
|
lxcDomainEventQueue(driver, event);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
}
|
2008-04-10 07:30:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-09 18:22:56 +00:00
|
|
|
static int lxcControllerStart(lxc_driver_t *driver,
|
2008-08-20 20:55:32 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
int nveths,
|
|
|
|
char **veths,
|
|
|
|
int appPty,
|
2011-05-05 20:34:05 +00:00
|
|
|
int logfile)
|
2008-08-20 20:55:32 +00:00
|
|
|
{
|
|
|
|
int i;
|
2011-05-05 20:34:05 +00:00
|
|
|
int ret = -1;
|
2009-10-08 15:16:08 +00:00
|
|
|
char *filterstr;
|
|
|
|
char *outputstr;
|
2011-05-05 20:34:05 +00:00
|
|
|
virCommandPtr cmd;
|
2011-05-05 20:35:00 +00:00
|
|
|
off_t pos = -1;
|
|
|
|
char ebuf[1024];
|
|
|
|
char *timestamp;
|
2011-05-05 20:34:05 +00:00
|
|
|
|
|
|
|
cmd = virCommandNew(vm->def->emulator);
|
|
|
|
|
|
|
|
/* The controller may call ip command, so we have to retain PATH. */
|
|
|
|
virCommandAddEnvPass(cmd, "PATH");
|
|
|
|
|
|
|
|
virCommandAddEnvFormat(cmd, "LIBVIRT_DEBUG=%d",
|
|
|
|
virLogGetDefaultPriority());
|
2009-10-08 15:16:08 +00:00
|
|
|
|
|
|
|
if (virLogGetNbFilters() > 0) {
|
|
|
|
filterstr = virLogGetFilters();
|
2011-05-05 20:34:05 +00:00
|
|
|
if (!filterstr) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
virCommandAddEnvPair(cmd, "LIBVIRT_LOG_FILTERS", filterstr);
|
2009-10-08 15:16:08 +00:00
|
|
|
VIR_FREE(filterstr);
|
|
|
|
}
|
|
|
|
|
2009-10-08 15:40:14 +00:00
|
|
|
if (driver->log_libvirtd) {
|
|
|
|
if (virLogGetNbOutputs() > 0) {
|
|
|
|
outputstr = virLogGetOutputs();
|
2011-05-05 20:34:05 +00:00
|
|
|
if (!outputstr) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
virCommandAddEnvPair(cmd, "LIBVIRT_LOG_OUTPUTS", outputstr);
|
2009-10-08 15:40:14 +00:00
|
|
|
VIR_FREE(outputstr);
|
|
|
|
}
|
|
|
|
} else {
|
2011-05-05 20:34:05 +00:00
|
|
|
virCommandAddEnvFormat(cmd,
|
|
|
|
"LIBVIRT_LOG_OUTPUTS=%d:stderr",
|
|
|
|
virLogGetDefaultPriority());
|
2009-10-08 15:16:08 +00:00
|
|
|
}
|
|
|
|
|
2011-05-05 20:34:05 +00:00
|
|
|
virCommandAddArgList(cmd, "--name", vm->def->name, "--console", NULL);
|
|
|
|
virCommandAddArgFormat(cmd, "%d", appPty);
|
|
|
|
virCommandAddArg(cmd, "--background");
|
2008-08-20 20:55:32 +00:00
|
|
|
|
|
|
|
for (i = 0 ; i < nveths ; i++) {
|
2011-05-05 20:34:05 +00:00
|
|
|
virCommandAddArgList(cmd, "--veth", veths[i], NULL);
|
2008-08-20 20:55:32 +00:00
|
|
|
}
|
|
|
|
|
2010-03-26 15:02:05 +00:00
|
|
|
/* now that we know it is about to start call the hook if present */
|
|
|
|
if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
|
|
|
|
char *xml = virDomainDefFormat(vm->def, 0);
|
|
|
|
int hookret;
|
|
|
|
|
|
|
|
hookret = virHookCall(VIR_HOOK_DRIVER_LXC, vm->def->name,
|
|
|
|
VIR_HOOK_LXC_OP_START, VIR_HOOK_SUBOP_BEGIN, NULL, xml);
|
|
|
|
VIR_FREE(xml);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the script raised an error abort the launch
|
|
|
|
*/
|
|
|
|
if (hookret < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-05-05 20:35:00 +00:00
|
|
|
/* Log timestamp */
|
|
|
|
if ((timestamp = virTimestamp()) == NULL) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (safewrite(logfile, timestamp, strlen(timestamp)) < 0 ||
|
|
|
|
safewrite(logfile, START_POSTFIX, strlen(START_POSTFIX)) < 0) {
|
|
|
|
VIR_WARN("Unable to write timestamp to logfile: %s",
|
|
|
|
virStrerror(errno, ebuf, sizeof ebuf));
|
|
|
|
}
|
|
|
|
VIR_FREE(timestamp);
|
|
|
|
|
|
|
|
/* Log generated command line */
|
|
|
|
virCommandWriteArgLog(cmd, logfile);
|
|
|
|
if ((pos = lseek(logfile, 0, SEEK_END)) < 0)
|
|
|
|
VIR_WARN("Unable to seek to end of logfile: %s",
|
|
|
|
virStrerror(errno, ebuf, sizeof ebuf));
|
|
|
|
|
2011-05-05 20:34:05 +00:00
|
|
|
virCommandPreserveFD(cmd, appPty);
|
|
|
|
virCommandSetOutputFD(cmd, &logfile);
|
|
|
|
virCommandSetErrorFD(cmd, &logfile);
|
2008-08-20 20:55:32 +00:00
|
|
|
|
2011-05-05 20:34:05 +00:00
|
|
|
ret = virCommandRun(cmd, NULL);
|
2008-08-20 20:55:32 +00:00
|
|
|
|
2009-10-08 15:16:08 +00:00
|
|
|
cleanup:
|
2011-05-05 20:34:05 +00:00
|
|
|
virCommandFree(cmd);
|
|
|
|
return ret;
|
2008-08-20 20:55:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-04-10 07:30:52 +00:00
|
|
|
/**
|
|
|
|
* lxcVmStart:
|
|
|
|
* @conn: pointer to connection
|
|
|
|
* @driver: pointer to driver structure
|
|
|
|
* @vm: pointer to virtual machine structure
|
2011-05-04 09:07:01 +00:00
|
|
|
* @reason: reason for switching vm to running state
|
2008-04-10 07:30:52 +00:00
|
|
|
*
|
|
|
|
* Starts a vm
|
|
|
|
*
|
|
|
|
* Returns 0 on success or -1 in case of error
|
|
|
|
*/
|
|
|
|
static int lxcVmStart(virConnectPtr conn,
|
|
|
|
lxc_driver_t * driver,
|
2011-05-04 09:07:01 +00:00
|
|
|
virDomainObjPtr vm,
|
|
|
|
virDomainRunningReason reason)
|
2008-04-10 07:30:52 +00:00
|
|
|
{
|
2009-10-13 14:36:59 +00:00
|
|
|
int rc = -1, r;
|
2008-08-13 10:52:15 +00:00
|
|
|
unsigned int i;
|
|
|
|
int parentTty;
|
2008-08-13 12:50:55 +00:00
|
|
|
char *parentTtyPath = NULL;
|
2008-08-13 10:52:15 +00:00
|
|
|
char *logfile = NULL;
|
|
|
|
int logfd = -1;
|
|
|
|
unsigned int nveths = 0;
|
|
|
|
char **veths = NULL;
|
2009-11-26 17:56:01 +00:00
|
|
|
lxcDomainObjPrivatePtr priv = vm->privateData;
|
2008-08-13 10:52:15 +00:00
|
|
|
|
2011-02-22 17:35:06 +00:00
|
|
|
if (!lxc_driver->cgroup) {
|
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("The 'cpuacct', 'devices' & 'memory' cgroups controllers must be mounted"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!virCgroupMounted(lxc_driver->cgroup,
|
|
|
|
VIR_CGROUP_CONTROLLER_CPUACCT)) {
|
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Unable to find 'cpuacct' cgroups controller mount"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!virCgroupMounted(lxc_driver->cgroup,
|
|
|
|
VIR_CGROUP_CONTROLLER_DEVICES)) {
|
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Unable to find 'devices' cgroups controller mount"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!virCgroupMounted(lxc_driver->cgroup,
|
|
|
|
VIR_CGROUP_CONTROLLER_MEMORY)) {
|
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Unable to find 'memory' cgroups controller mount"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-01-20 23:52:13 +00:00
|
|
|
if ((r = virFileMakePath(driver->logDir)) != 0) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(r,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("Cannot create log directory '%s'"),
|
2009-01-20 17:13:33 +00:00
|
|
|
driver->logDir);
|
2008-08-13 10:52:15 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2008-12-23 13:03:29 +00:00
|
|
|
if (virAsprintf(&logfile, "%s/%s.log",
|
|
|
|
driver->logDir, vm->def->name) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-08-13 10:52:15 +00:00
|
|
|
return -1;
|
2008-04-10 07:30:52 +00:00
|
|
|
}
|
|
|
|
|
2008-08-13 10:52:15 +00:00
|
|
|
/* open parent tty */
|
2008-08-13 12:50:55 +00:00
|
|
|
if (virFileOpenTty(&parentTty, &parentTtyPath, 1) < 0) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno, "%s",
|
2009-11-05 12:39:09 +00:00
|
|
|
_("Failed to allocate tty"));
|
2008-04-10 07:30:52 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2008-08-13 12:50:55 +00:00
|
|
|
if (vm->def->console &&
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
vm->def->console->source.type == VIR_DOMAIN_CHR_TYPE_PTY) {
|
|
|
|
VIR_FREE(vm->def->console->source.data.file.path);
|
|
|
|
vm->def->console->source.data.file.path = parentTtyPath;
|
2008-08-13 12:50:55 +00:00
|
|
|
} else {
|
|
|
|
VIR_FREE(parentTtyPath);
|
|
|
|
}
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2008-08-13 10:52:15 +00:00
|
|
|
if (lxcSetupInterfaces(conn, vm->def, &nveths, &veths) != 0)
|
2008-06-26 16:09:48 +00:00
|
|
|
goto cleanup;
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2010-06-27 13:07:00 +00:00
|
|
|
/* Save the configuration for the controller */
|
2010-02-09 18:58:01 +00:00
|
|
|
if (virDomainSaveConfig(driver->stateDir, vm->def) < 0)
|
2008-08-20 20:55:32 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2009-10-08 15:37:09 +00:00
|
|
|
if ((logfd = open(logfile, O_WRONLY | O_APPEND | O_CREAT,
|
2008-08-13 10:52:15 +00:00
|
|
|
S_IRUSR|S_IWUSR)) < 0) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("Failed to open '%s'"),
|
2009-01-20 17:13:33 +00:00
|
|
|
logfile);
|
2008-06-26 16:09:48 +00:00
|
|
|
goto cleanup;
|
2008-04-10 07:30:52 +00:00
|
|
|
}
|
|
|
|
|
2010-02-09 18:22:56 +00:00
|
|
|
if (lxcControllerStart(driver,
|
2008-08-20 20:55:32 +00:00
|
|
|
vm,
|
|
|
|
nveths, veths,
|
|
|
|
parentTty, logfd) < 0)
|
2008-06-26 16:09:48 +00:00
|
|
|
goto cleanup;
|
2008-08-13 10:52:15 +00:00
|
|
|
|
|
|
|
/* Connect to the controller as a client *first* because
|
|
|
|
* this will block until the child has written their
|
|
|
|
* pid file out to disk */
|
2010-02-09 18:22:56 +00:00
|
|
|
if ((priv->monitor = lxcMonitorClient(driver, vm)) < 0)
|
2008-06-26 16:09:48 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2008-08-13 10:52:15 +00:00
|
|
|
/* And get its pid */
|
2009-10-13 14:36:59 +00:00
|
|
|
if ((r = virFileReadPid(driver->stateDir, vm->def->name, &vm->pid)) != 0) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(r,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("Failed to read pid file %s/%s.pid"),
|
|
|
|
driver->stateDir, vm->def->name);
|
2008-06-26 16:09:48 +00:00
|
|
|
goto cleanup;
|
2008-08-13 10:52:15 +00:00
|
|
|
}
|
2008-06-26 16:09:48 +00:00
|
|
|
|
2008-08-13 10:52:15 +00:00
|
|
|
vm->def->id = vm->pid;
|
2011-05-04 09:07:01 +00:00
|
|
|
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
|
2008-06-26 16:09:48 +00:00
|
|
|
|
2009-11-26 17:56:01 +00:00
|
|
|
if ((priv->monitorWatch = virEventAddHandle(
|
|
|
|
priv->monitor,
|
2008-11-19 16:19:36 +00:00
|
|
|
VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
|
|
|
|
lxcMonitorEvent,
|
2009-11-12 14:13:33 +00:00
|
|
|
vm, NULL)) < 0) {
|
2011-05-04 09:07:01 +00:00
|
|
|
lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
|
2008-08-13 10:52:15 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2008-06-26 16:09:48 +00:00
|
|
|
|
2010-06-27 13:07:00 +00:00
|
|
|
/*
|
|
|
|
* Again, need to save the live configuration, because the function
|
|
|
|
* requires vm->def->id != -1 to save tty info surely.
|
|
|
|
*/
|
|
|
|
if (virDomainSaveConfig(driver->stateDir, vm->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2011-01-12 06:04:33 +00:00
|
|
|
if (virDomainObjSetDefTransient(driver->caps, vm, false) < 0)
|
2010-11-19 18:36:29 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2011-05-31 10:03:41 +00:00
|
|
|
/* Write domain status to disk. */
|
|
|
|
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2008-08-13 10:52:15 +00:00
|
|
|
rc = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2010-11-09 20:48:48 +00:00
|
|
|
if (VIR_CLOSE(logfd) < 0) {
|
|
|
|
virReportSystemError(errno, "%s", _("could not close logfile"));
|
|
|
|
rc = -1;
|
|
|
|
}
|
2008-08-13 10:52:15 +00:00
|
|
|
for (i = 0 ; i < nveths ; i++) {
|
|
|
|
if (rc != 0)
|
|
|
|
vethDelete(veths[i]);
|
|
|
|
VIR_FREE(veths[i]);
|
|
|
|
}
|
2010-11-09 20:48:48 +00:00
|
|
|
if (rc != 0)
|
|
|
|
VIR_FORCE_CLOSE(priv->monitor);
|
|
|
|
VIR_FORCE_CLOSE(parentTty);
|
2008-08-13 10:52:15 +00:00
|
|
|
VIR_FREE(logfile);
|
2008-04-10 07:30:52 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2010-06-10 15:55:36 +00:00
|
|
|
* lxcDomainStartWithFlags:
|
2008-04-10 07:30:52 +00:00
|
|
|
* @dom: domain to start
|
2010-06-10 15:55:36 +00:00
|
|
|
* @flags: Must be 0 for now
|
2008-04-10 07:30:52 +00:00
|
|
|
*
|
|
|
|
* Looks up domain and starts it.
|
|
|
|
*
|
|
|
|
* Returns 0 on success or -1 in case of error
|
|
|
|
*/
|
2010-06-10 15:55:36 +00:00
|
|
|
static int lxcDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
|
2008-04-10 07:30:52 +00:00
|
|
|
{
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2009-07-06 15:04:36 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2008-12-04 21:11:41 +00:00
|
|
|
int ret = -1;
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2010-06-10 15:55:36 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
2010-05-03 11:59:03 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-04-10 07:30:52 +00:00
|
|
|
if (!vm) {
|
2010-05-03 11:59:03 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2008-04-10 07:30:52 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2008-08-13 12:50:55 +00:00
|
|
|
if ((vm->def->nets != NULL) && !(driver->have_netns)) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_NO_SUPPORT,
|
avoid many format string warnings
Building with --disable-nls exposed many new warnings like these:
virsh.c:4952: warning: format not a string literal and no format ...
util.c:163: warning: format not a string literal and no format arguments
All but one of the following changes add a "%s" argument before
the offending _(...) argument.
This was the only manual change:
* src/lxc_driver.c (lxcVersion): Use %s and strerror(errno)
rather than %m, to avoid a warning from gcc -Wformat-security.
Add "%s" before each warned about format-string-with-no-%-directive:
* src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML)
(virDomainDefParseString, virDomainDefParseFile):
* src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain)
(__virGetNetwork, virReleaseNetwork, __virGetStoragePool)
(virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol):
* src/lxc_container.c (lxcContainerChild):
* src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine)
(lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML)
(lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart)
(lxcVersion, lxcGetSchedulerParameters):
* src/network_conf.c (virNetworkDefParseString)
(virNetworkDefParseFile):
* src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains):
* src/openvz_driver.c (openvzDomainDefineCmd)
(openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown)
(openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML)
(openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine)
(openvzDomainSetAutostart, openvzDomainGetAutostart)
(openvzDomainSetVcpus):
* src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek):
* src/remote_internal.c (remoteDomainBlockPeek)
(remoteDomainMemoryPeek, remoteAuthPolkit):
* src/sexpr.c (sexpr_new, _string2sexpr):
* src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol)
(virStorageBackendDiskCreateVol):
* src/storage_backend_fs.c
(virStorageBackendFileSystemNetFindPoolSources):
* src/storage_backend_logical.c (virStorageBackendLogicalFindLVs)
(virStorageBackendLogicalFindPoolSources):
* src/test.c (testOpenDefault, testOpenFromFile, testOpen)
(testGetDomainInfo, testDomainRestore)
(testNodeGetCellsFreeMemory):
* src/util.c (virExec):
* src/virsh.c (cmdAttachDevice, cmdDetachDevice)
(cmdAttachInterface, cmdDetachInterface, cmdAttachDisk)
(cmdDetachDisk, cmdEdit):
* src/xend_internal.c (do_connect, wr_sync, xend_op_ext)
(urlencode, xenDaemonDomainCreateXML)
(xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID)
(xenDaemonParseSxprOS, xend_parse_sexp_desc_char)
(xenDaemonParseSxprChar, xenDaemonParseSxprDisks)
(xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain)
(xenDaemonDomainFetch, xenDaemonDomainGetAutostart)
(xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform)
(xenDaemonDomainDefineXML, xenDaemonGetSchedulerType)
(xenDaemonGetSchedulerParameters)
(xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek)
(xenDaemonFormatSxprChr, virDomainXMLDevID):
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu)
(xenXMDomainCreate, xenXMDomainDefineXML)
(xenXMDomainAttachDevice, xenXMDomainDetachDevice):
* src/xml.c (virXPathString, virXPathNumber, virXPathLong)
(virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet):
* src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
|
|
|
"%s", _("System lacks NETNS support"));
|
2008-08-13 12:50:55 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-05-03 12:04:44 +00:00
|
|
|
if (virDomainObjIsActive(vm)) {
|
|
|
|
lxcError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
"%s", _("Domain is already running"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-05-04 09:07:01 +00:00
|
|
|
ret = lxcVmStart(dom->conn, driver, vm, VIR_DOMAIN_RUNNING_BOOTED);
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2009-07-06 15:04:36 +00:00
|
|
|
if (ret == 0)
|
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED_BOOTED);
|
|
|
|
|
2008-04-10 07:30:52 +00:00
|
|
|
cleanup:
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2009-07-06 15:04:36 +00:00
|
|
|
if (event)
|
|
|
|
lxcDomainEventQueue(driver, event);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2008-12-04 21:11:41 +00:00
|
|
|
return ret;
|
2008-04-10 07:30:52 +00:00
|
|
|
}
|
|
|
|
|
2010-06-10 15:55:36 +00:00
|
|
|
/**
|
|
|
|
* lxcDomainStart:
|
|
|
|
* @dom: domain to start
|
|
|
|
*
|
|
|
|
* Looks up domain and starts it.
|
|
|
|
*
|
|
|
|
* Returns 0 on success or -1 in case of error
|
|
|
|
*/
|
|
|
|
static int lxcDomainStart(virDomainPtr dom)
|
|
|
|
{
|
|
|
|
return lxcDomainStartWithFlags(dom, 0);
|
|
|
|
}
|
|
|
|
|
2008-04-10 07:30:52 +00:00
|
|
|
/**
|
|
|
|
* lxcDomainCreateAndStart:
|
|
|
|
* @conn: pointer to connection
|
|
|
|
* @xml: XML definition of domain
|
2010-05-25 17:13:13 +00:00
|
|
|
* @flags: Must be 0 for now
|
2008-04-10 07:30:52 +00:00
|
|
|
*
|
|
|
|
* Creates a domain based on xml and starts it
|
|
|
|
*
|
|
|
|
* Returns 0 on success or -1 in case of error
|
|
|
|
*/
|
|
|
|
static virDomainPtr
|
|
|
|
lxcDomainCreateAndStart(virConnectPtr conn,
|
|
|
|
const char *xml,
|
2010-05-25 17:13:13 +00:00
|
|
|
unsigned int flags) {
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = conn->privateData;
|
2008-12-04 21:12:41 +00:00
|
|
|
virDomainObjPtr vm = NULL;
|
2008-08-13 12:50:55 +00:00
|
|
|
virDomainDefPtr def;
|
2008-04-10 07:30:52 +00:00
|
|
|
virDomainPtr dom = NULL;
|
2009-07-06 15:04:36 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2010-05-25 17:13:13 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
2010-02-09 18:58:01 +00:00
|
|
|
if (!(def = virDomainDefParseString(driver->caps, xml,
|
2009-01-08 13:54:20 +00:00
|
|
|
VIR_DOMAIN_XML_INACTIVE)))
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2009-11-02 18:37:38 +00:00
|
|
|
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
|
|
|
|
goto cleanup;
|
2009-07-31 14:25:03 +00:00
|
|
|
|
2008-08-13 12:50:55 +00:00
|
|
|
if ((def->nets != NULL) && !(driver->have_netns)) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_NO_SUPPORT,
|
avoid many format string warnings
Building with --disable-nls exposed many new warnings like these:
virsh.c:4952: warning: format not a string literal and no format ...
util.c:163: warning: format not a string literal and no format arguments
All but one of the following changes add a "%s" argument before
the offending _(...) argument.
This was the only manual change:
* src/lxc_driver.c (lxcVersion): Use %s and strerror(errno)
rather than %m, to avoid a warning from gcc -Wformat-security.
Add "%s" before each warned about format-string-with-no-%-directive:
* src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML)
(virDomainDefParseString, virDomainDefParseFile):
* src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain)
(__virGetNetwork, virReleaseNetwork, __virGetStoragePool)
(virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol):
* src/lxc_container.c (lxcContainerChild):
* src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine)
(lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML)
(lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart)
(lxcVersion, lxcGetSchedulerParameters):
* src/network_conf.c (virNetworkDefParseString)
(virNetworkDefParseFile):
* src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains):
* src/openvz_driver.c (openvzDomainDefineCmd)
(openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown)
(openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML)
(openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine)
(openvzDomainSetAutostart, openvzDomainGetAutostart)
(openvzDomainSetVcpus):
* src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek):
* src/remote_internal.c (remoteDomainBlockPeek)
(remoteDomainMemoryPeek, remoteAuthPolkit):
* src/sexpr.c (sexpr_new, _string2sexpr):
* src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol)
(virStorageBackendDiskCreateVol):
* src/storage_backend_fs.c
(virStorageBackendFileSystemNetFindPoolSources):
* src/storage_backend_logical.c (virStorageBackendLogicalFindLVs)
(virStorageBackendLogicalFindPoolSources):
* src/test.c (testOpenDefault, testOpenFromFile, testOpen)
(testGetDomainInfo, testDomainRestore)
(testNodeGetCellsFreeMemory):
* src/util.c (virExec):
* src/virsh.c (cmdAttachDevice, cmdDetachDevice)
(cmdAttachInterface, cmdDetachInterface, cmdAttachDisk)
(cmdDetachDisk, cmdEdit):
* src/xend_internal.c (do_connect, wr_sync, xend_op_ext)
(urlencode, xenDaemonDomainCreateXML)
(xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID)
(xenDaemonParseSxprOS, xend_parse_sexp_desc_char)
(xenDaemonParseSxprChar, xenDaemonParseSxprDisks)
(xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain)
(xenDaemonDomainFetch, xenDaemonDomainGetAutostart)
(xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform)
(xenDaemonDomainDefineXML, xenDaemonGetSchedulerType)
(xenDaemonGetSchedulerParameters)
(xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek)
(xenDaemonFormatSxprChr, virDomainXMLDevID):
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu)
(xenXMDomainCreate, xenXMDomainDefineXML)
(xenXMDomainAttachDevice, xenXMDomainDetachDevice):
* src/xml.c (virXPathString, virXPathNumber, virXPathLong)
(virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet):
* src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
|
|
|
"%s", _("System lacks NETNS support"));
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-04-10 07:30:52 +00:00
|
|
|
}
|
|
|
|
|
2008-08-13 12:50:55 +00:00
|
|
|
|
2010-02-09 18:58:01 +00:00
|
|
|
if (!(vm = virDomainAssignDef(driver->caps,
|
2010-03-24 14:31:21 +00:00
|
|
|
&driver->domains, def, false)))
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
|
|
|
def = NULL;
|
2008-04-10 07:30:52 +00:00
|
|
|
|
2011-05-04 09:07:01 +00:00
|
|
|
if (lxcVmStart(conn, driver, vm, VIR_DOMAIN_RUNNING_BOOTED) < 0) {
|
2008-08-13 12:50:55 +00:00
|
|
|
virDomainRemoveInactive(&driver->domains, vm);
|
2008-12-04 21:12:41 +00:00
|
|
|
vm = NULL;
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-04-10 07:30:52 +00:00
|
|
|
}
|
|
|
|
|
2009-07-06 15:04:36 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED_BOOTED);
|
|
|
|
|
2008-04-10 07:30:52 +00:00
|
|
|
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
|
2008-12-04 21:11:41 +00:00
|
|
|
if (dom)
|
2008-04-10 07:30:52 +00:00
|
|
|
dom->id = vm->def->id;
|
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
cleanup:
|
|
|
|
virDomainDefFree(def);
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2009-07-06 15:04:36 +00:00
|
|
|
if (event)
|
|
|
|
lxcDomainEventQueue(driver, event);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2008-04-10 07:30:52 +00:00
|
|
|
return dom;
|
|
|
|
}
|
|
|
|
|
2009-07-06 15:04:36 +00:00
|
|
|
|
|
|
|
static int
|
2010-03-18 14:47:07 +00:00
|
|
|
lxcDomainEventRegister(virConnectPtr conn,
|
|
|
|
virConnectDomainEventCallback callback,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
2009-07-06 15:04:36 +00:00
|
|
|
{
|
|
|
|
lxc_driver_t *driver = conn->privateData;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
2011-01-06 17:42:12 +00:00
|
|
|
ret = virDomainEventCallbackListAdd(conn,
|
|
|
|
driver->domainEventState->callbacks,
|
2009-07-06 15:04:36 +00:00
|
|
|
callback, opaque, freecb);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2009-07-06 15:04:36 +00:00
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
return ret;
|
2008-04-10 07:30:52 +00:00
|
|
|
}
|
|
|
|
|
2010-03-18 14:47:07 +00:00
|
|
|
|
2009-07-06 15:04:36 +00:00
|
|
|
static int
|
2010-03-18 14:47:07 +00:00
|
|
|
lxcDomainEventDeregister(virConnectPtr conn,
|
|
|
|
virConnectDomainEventCallback callback)
|
2009-07-06 15:04:36 +00:00
|
|
|
{
|
|
|
|
lxc_driver_t *driver = conn->privateData;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
2011-01-06 17:42:12 +00:00
|
|
|
ret = virDomainEventStateDeregister(conn,
|
|
|
|
driver->domainEventState,
|
|
|
|
callback);
|
2009-07-06 15:04:36 +00:00
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-03-18 14:47:07 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
lxcDomainEventRegisterAny(virConnectPtr conn,
|
|
|
|
virDomainPtr dom,
|
|
|
|
int eventID,
|
|
|
|
virConnectDomainEventGenericCallback callback,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = conn->privateData;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
ret = virDomainEventCallbackListAddID(conn,
|
2011-01-06 17:42:12 +00:00
|
|
|
driver->domainEventState->callbacks,
|
2010-03-18 14:47:07 +00:00
|
|
|
dom, eventID,
|
|
|
|
callback, opaque, freecb);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
lxcDomainEventDeregisterAny(virConnectPtr conn,
|
|
|
|
int callbackID)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = conn->privateData;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
2011-01-06 17:42:12 +00:00
|
|
|
ret = virDomainEventStateDeregisterAny(conn,
|
|
|
|
driver->domainEventState,
|
|
|
|
callbackID);
|
2010-03-18 14:47:07 +00:00
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-06 15:04:36 +00:00
|
|
|
static void lxcDomainEventDispatchFunc(virConnectPtr conn,
|
|
|
|
virDomainEventPtr event,
|
2010-03-18 14:06:09 +00:00
|
|
|
virConnectDomainEventGenericCallback cb,
|
2009-07-06 15:04:36 +00:00
|
|
|
void *cbopaque,
|
|
|
|
void *opaque)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = opaque;
|
|
|
|
|
|
|
|
/* Drop the lock whle dispatching, for sake of re-entrancy */
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
virDomainEventDispatchDefaultFunc(conn, event, cb, cbopaque, NULL);
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void lxcDomainEventFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = opaque;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
2011-01-06 17:42:12 +00:00
|
|
|
virDomainEventStateFlush(driver->domainEventState,
|
|
|
|
lxcDomainEventDispatchFunc,
|
|
|
|
driver);
|
2009-07-06 15:04:36 +00:00
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* driver must be locked before calling */
|
|
|
|
static void lxcDomainEventQueue(lxc_driver_t *driver,
|
|
|
|
virDomainEventPtr event)
|
|
|
|
{
|
2011-01-06 17:42:12 +00:00
|
|
|
virDomainEventStateQueue(driver->domainEventState, event);
|
2009-07-06 15:04:36 +00:00
|
|
|
}
|
2008-05-13 06:30:58 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* lxcDomainDestroy:
|
2009-11-05 12:35:13 +00:00
|
|
|
* @dom: pointer to domain to destroy
|
2008-05-13 06:30:58 +00:00
|
|
|
*
|
|
|
|
* Sends SIGKILL to container root process to terminate the container
|
|
|
|
*
|
|
|
|
* Returns 0 on success or -1 in case of error
|
|
|
|
*/
|
|
|
|
static int lxcDomainDestroy(virDomainPtr dom)
|
|
|
|
{
|
2008-12-04 21:11:41 +00:00
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
2009-07-06 15:04:36 +00:00
|
|
|
virDomainEventPtr event = NULL;
|
2008-12-04 21:11:41 +00:00
|
|
|
int ret = -1;
|
2008-05-13 06:30:58 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
2010-05-03 11:59:03 +00:00
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
2008-05-13 06:30:58 +00:00
|
|
|
if (!vm) {
|
2010-05-03 11:59:03 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-05-13 06:30:58 +00:00
|
|
|
}
|
|
|
|
|
2010-05-03 12:04:44 +00:00
|
|
|
if (!virDomainObjIsActive(vm)) {
|
|
|
|
lxcError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
"%s", _("Domain is not running"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-05-04 09:07:01 +00:00
|
|
|
ret = lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED);
|
2009-07-06 15:04:36 +00:00
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED,
|
|
|
|
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
|
2008-12-04 21:12:41 +00:00
|
|
|
if (!vm->persistent) {
|
|
|
|
virDomainRemoveInactive(&driver->domains, vm);
|
|
|
|
vm = NULL;
|
|
|
|
}
|
2008-12-04 21:11:41 +00:00
|
|
|
|
|
|
|
cleanup:
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2009-07-06 15:04:36 +00:00
|
|
|
if (event)
|
|
|
|
lxcDomainEventQueue(driver, event);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2008-12-04 21:11:41 +00:00
|
|
|
return ret;
|
2008-04-10 07:30:52 +00:00
|
|
|
}
|
2008-03-27 09:34:06 +00:00
|
|
|
|
2008-06-26 16:05:02 +00:00
|
|
|
static int lxcCheckNetNsSupport(void)
|
|
|
|
{
|
|
|
|
const char *argv[] = {"ip", "link", "set", "lo", "netns", "-1", NULL};
|
|
|
|
int ip_rc;
|
|
|
|
|
2010-02-04 22:41:52 +00:00
|
|
|
if (virRun(argv, &ip_rc) < 0 ||
|
2008-08-13 10:25:34 +00:00
|
|
|
!(WIFEXITED(ip_rc) && (WEXITSTATUS(ip_rc) != 255)))
|
|
|
|
return 0;
|
2008-06-26 16:05:02 +00:00
|
|
|
|
2008-08-13 10:25:34 +00:00
|
|
|
if (lxcContainerAvailable(LXC_CONTAINER_FEATURE_NET) < 0)
|
|
|
|
return 0;
|
2008-06-26 16:05:02 +00:00
|
|
|
|
2008-08-13 10:25:34 +00:00
|
|
|
return 1;
|
2008-06-26 16:05:02 +00:00
|
|
|
}
|
|
|
|
|
2009-07-06 15:05:32 +00:00
|
|
|
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
struct lxcAutostartData {
|
|
|
|
lxc_driver_t *driver;
|
|
|
|
virConnectPtr conn;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
Allow hash tables to use generic pointers as keys
Relax the restriction that the hash table key must be a string
by allowing an arbitrary hash code generator + comparison func
to be provided
* util/hash.c, util/hash.h: Allow any pointer as a key
* internal.h: Include stdbool.h as standard.
* conf/domain_conf.c, conf/domain_conf.c,
conf/nwfilter_params.c, nwfilter/nwfilter_gentech_driver.c,
nwfilter/nwfilter_gentech_driver.h, nwfilter/nwfilter_learnipaddr.c,
qemu/qemu_command.c, qemu/qemu_driver.c,
qemu/qemu_process.c, uml/uml_driver.c,
xen/xm_internal.c: s/char */void */ in hash callbacks
2011-02-22 15:11:59 +00:00
|
|
|
lxcAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr vm = payload;
|
|
|
|
const struct lxcAutostartData *data = opaque;
|
|
|
|
|
|
|
|
virDomainObjLock(vm);
|
|
|
|
if (vm->autostart &&
|
Rename internal APis
Rename virDomainIsActive to virDomainObjIsActive, and
virInterfaceIsActive to virInterfaceObjIsActive and finally
virNetworkIsActive to virNetworkObjIsActive.
* src/conf/domain_conf.c, src/conf/domain_conf.h,
src/conf/interface_conf.h, src/conf/network_conf.c,
src/conf/network_conf.h, src/lxc/lxc_driver.c,
src/network/bridge_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_driver.c, src/qemu/qemu_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c: Update for
renamed APIs.
2009-10-20 14:51:03 +00:00
|
|
|
!virDomainObjIsActive(vm)) {
|
2011-05-04 09:07:01 +00:00
|
|
|
int ret = lxcVmStart(data->conn, data->driver, vm,
|
|
|
|
VIR_DOMAIN_RUNNING_BOOTED);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
if (ret < 0) {
|
|
|
|
virErrorPtr err = virGetLastError();
|
2010-01-19 13:17:20 +00:00
|
|
|
VIR_ERROR(_("Failed to autostart VM '%s': %s"),
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
vm->def->name,
|
|
|
|
err ? err->message : "");
|
|
|
|
} else {
|
|
|
|
virDomainEventPtr event =
|
|
|
|
virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED,
|
|
|
|
VIR_DOMAIN_EVENT_STARTED_BOOTED);
|
|
|
|
if (event)
|
|
|
|
lxcDomainEventQueue(data->driver, event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
}
|
|
|
|
|
2009-07-06 15:05:32 +00:00
|
|
|
static void
|
|
|
|
lxcAutostartConfigs(lxc_driver_t *driver) {
|
|
|
|
/* XXX: Figure out a better way todo this. The domain
|
|
|
|
* startup code needs a connection handle in order
|
|
|
|
* to lookup the bridge associated with a virtual
|
|
|
|
* network
|
|
|
|
*/
|
|
|
|
virConnectPtr conn = virConnectOpen("lxc:///");
|
|
|
|
/* Ignoring NULL conn which is mostly harmless here */
|
|
|
|
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
struct lxcAutostartData data = { driver, conn };
|
|
|
|
|
2009-07-06 15:05:32 +00:00
|
|
|
lxcDriverLock(driver);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
virHashForEach(driver->domains.objs, lxcAutostartDomain, &data);
|
2009-07-06 15:05:32 +00:00
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
|
|
|
if (conn)
|
|
|
|
virConnectClose(conn);
|
|
|
|
}
|
|
|
|
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
static void
|
Allow hash tables to use generic pointers as keys
Relax the restriction that the hash table key must be a string
by allowing an arbitrary hash code generator + comparison func
to be provided
* util/hash.c, util/hash.h: Allow any pointer as a key
* internal.h: Include stdbool.h as standard.
* conf/domain_conf.c, conf/domain_conf.c,
conf/nwfilter_params.c, nwfilter/nwfilter_gentech_driver.c,
nwfilter/nwfilter_gentech_driver.h, nwfilter/nwfilter_learnipaddr.c,
qemu/qemu_command.c, qemu/qemu_driver.c,
qemu/qemu_process.c, uml/uml_driver.c,
xen/xm_internal.c: s/char */void */ in hash callbacks
2011-02-22 15:11:59 +00:00
|
|
|
lxcReconnectVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr vm = payload;
|
|
|
|
lxc_driver_t *driver = opaque;
|
2009-11-26 17:56:01 +00:00
|
|
|
lxcDomainObjPrivatePtr priv;
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
|
|
|
|
virDomainObjLock(vm);
|
2009-11-26 17:56:01 +00:00
|
|
|
|
|
|
|
priv = vm->privateData;
|
2010-02-09 18:22:56 +00:00
|
|
|
if ((priv->monitor = lxcMonitorClient(driver, vm)) < 0) {
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Read pid from controller */
|
|
|
|
if ((virFileReadPid(lxc_driver->stateDir, vm->def->name, &vm->pid)) != 0) {
|
2010-11-09 20:48:48 +00:00
|
|
|
VIR_FORCE_CLOSE(priv->monitor);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vm->pid != 0) {
|
|
|
|
vm->def->id = vm->pid;
|
2011-05-04 09:07:01 +00:00
|
|
|
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
|
|
|
|
VIR_DOMAIN_RUNNING_UNKNOWN);
|
2009-11-26 17:56:01 +00:00
|
|
|
|
|
|
|
if ((priv->monitorWatch = virEventAddHandle(
|
|
|
|
priv->monitor,
|
|
|
|
VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
|
|
|
|
lxcMonitorEvent,
|
|
|
|
vm, NULL)) < 0) {
|
2011-05-04 09:07:01 +00:00
|
|
|
lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
|
2009-11-26 17:56:01 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
} else {
|
|
|
|
vm->def->id = -1;
|
2010-11-09 20:48:48 +00:00
|
|
|
VIR_FORCE_CLOSE(priv->monitor);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
}
|
|
|
|
|
2009-07-06 15:05:32 +00:00
|
|
|
|
2009-06-12 13:20:13 +00:00
|
|
|
static int lxcStartup(int privileged)
|
2008-03-21 15:03:37 +00:00
|
|
|
{
|
2009-01-30 16:51:33 +00:00
|
|
|
char *ld;
|
2009-07-10 10:40:04 +00:00
|
|
|
int rc;
|
2009-01-30 16:51:33 +00:00
|
|
|
|
|
|
|
/* Valgrind gets very annoyed when we clone containers, so
|
|
|
|
* disable LXC when under valgrind
|
|
|
|
* XXX remove this when valgrind is fixed
|
|
|
|
*/
|
|
|
|
ld = getenv("LD_PRELOAD");
|
Fix return value in virStateInitialize impl for LXC
The LXC driver was mistakenly returning -1 for lxcStartup()
in scenarios that are not an error. This caused the libvirtd
to quit for unprivileged users. This fixes the return code
of LXC driver, and also adds a "name" field to the virStateDriver
struct and logging to make it easier to find these problems
in the future
* src/driver.h: Add a 'name' field to state driver to allow
easy identification during failures
* src/libvirt.c: Log name of failed driver for virStateInit
failures
* src/lxc/lxc_driver.c: Don't return a failure code for
lxcStartup() if LXC is not available on this host, simply
disable the driver.
* src/network/bridge_driver.c, src/node_device/node_device_devkit.c,
src/node_device/node_device_hal.c, src/opennebula/one_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/secret/secret_driver.c, src/storage/storage_driver.c,
src/uml/uml_driver.c, src/xen/xen_driver.c: Fill in name
field in virStateDriver struct
2009-11-02 23:18:19 +00:00
|
|
|
if (ld && strstr(ld, "vgpreload")) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_INFO("Running under valgrind, disabling driver");
|
Fix return value in virStateInitialize impl for LXC
The LXC driver was mistakenly returning -1 for lxcStartup()
in scenarios that are not an error. This caused the libvirtd
to quit for unprivileged users. This fixes the return code
of LXC driver, and also adds a "name" field to the virStateDriver
struct and logging to make it easier to find these problems
in the future
* src/driver.h: Add a 'name' field to state driver to allow
easy identification during failures
* src/libvirt.c: Log name of failed driver for virStateInit
failures
* src/lxc/lxc_driver.c: Don't return a failure code for
lxcStartup() if LXC is not available on this host, simply
disable the driver.
* src/network/bridge_driver.c, src/node_device/node_device_devkit.c,
src/node_device/node_device_hal.c, src/opennebula/one_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/secret/secret_driver.c, src/storage/storage_driver.c,
src/uml/uml_driver.c, src/xen/xen_driver.c: Fill in name
field in virStateDriver struct
2009-11-02 23:18:19 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2008-03-31 12:02:12 +00:00
|
|
|
|
Fix return value in virStateInitialize impl for LXC
The LXC driver was mistakenly returning -1 for lxcStartup()
in scenarios that are not an error. This caused the libvirtd
to quit for unprivileged users. This fixes the return code
of LXC driver, and also adds a "name" field to the virStateDriver
struct and logging to make it easier to find these problems
in the future
* src/driver.h: Add a 'name' field to state driver to allow
easy identification during failures
* src/libvirt.c: Log name of failed driver for virStateInit
failures
* src/lxc/lxc_driver.c: Don't return a failure code for
lxcStartup() if LXC is not available on this host, simply
disable the driver.
* src/network/bridge_driver.c, src/node_device/node_device_devkit.c,
src/node_device/node_device_hal.c, src/opennebula/one_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/secret/secret_driver.c, src/storage/storage_driver.c,
src/uml/uml_driver.c, src/xen/xen_driver.c: Fill in name
field in virStateDriver struct
2009-11-02 23:18:19 +00:00
|
|
|
/* Check that the user is root, silently disable if not */
|
2009-06-12 13:20:13 +00:00
|
|
|
if (!privileged) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_INFO("Not running privileged, disabling driver");
|
Fix return value in virStateInitialize impl for LXC
The LXC driver was mistakenly returning -1 for lxcStartup()
in scenarios that are not an error. This caused the libvirtd
to quit for unprivileged users. This fixes the return code
of LXC driver, and also adds a "name" field to the virStateDriver
struct and logging to make it easier to find these problems
in the future
* src/driver.h: Add a 'name' field to state driver to allow
easy identification during failures
* src/libvirt.c: Log name of failed driver for virStateInit
failures
* src/lxc/lxc_driver.c: Don't return a failure code for
lxcStartup() if LXC is not available on this host, simply
disable the driver.
* src/network/bridge_driver.c, src/node_device/node_device_devkit.c,
src/node_device/node_device_hal.c, src/opennebula/one_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/secret/secret_driver.c, src/storage/storage_driver.c,
src/uml/uml_driver.c, src/xen/xen_driver.c: Fill in name
field in virStateDriver struct
2009-11-02 23:18:19 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check that this is a container enabled kernel */
|
|
|
|
if (lxcContainerAvailable(0) < 0) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_INFO("LXC support not available in this kernel, disabling driver");
|
Fix return value in virStateInitialize impl for LXC
The LXC driver was mistakenly returning -1 for lxcStartup()
in scenarios that are not an error. This caused the libvirtd
to quit for unprivileged users. This fixes the return code
of LXC driver, and also adds a "name" field to the virStateDriver
struct and logging to make it easier to find these problems
in the future
* src/driver.h: Add a 'name' field to state driver to allow
easy identification during failures
* src/libvirt.c: Log name of failed driver for virStateInit
failures
* src/lxc/lxc_driver.c: Don't return a failure code for
lxcStartup() if LXC is not available on this host, simply
disable the driver.
* src/network/bridge_driver.c, src/node_device/node_device_devkit.c,
src/node_device/node_device_hal.c, src/opennebula/one_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/secret/secret_driver.c, src/storage/storage_driver.c,
src/uml/uml_driver.c, src/xen/xen_driver.c: Fill in name
field in virStateDriver struct
2009-11-02 23:18:19 +00:00
|
|
|
return 0;
|
2008-03-31 12:02:12 +00:00
|
|
|
}
|
|
|
|
|
2008-06-06 11:09:57 +00:00
|
|
|
if (VIR_ALLOC(lxc_driver) < 0) {
|
2008-03-27 09:34:06 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2009-01-15 19:56:05 +00:00
|
|
|
if (virMutexInit(&lxc_driver->lock) < 0) {
|
|
|
|
VIR_FREE(lxc_driver);
|
|
|
|
return -1;
|
|
|
|
}
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(lxc_driver);
|
2008-03-21 15:03:37 +00:00
|
|
|
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
if (virDomainObjListInit(&lxc_driver->domains) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2011-01-06 17:42:12 +00:00
|
|
|
lxc_driver->domainEventState = virDomainEventStateNew(lxcDomainEventFlush,
|
|
|
|
lxc_driver,
|
|
|
|
NULL,
|
|
|
|
true);
|
|
|
|
if (!lxc_driver->domainEventState)
|
2009-07-06 15:04:36 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2009-10-08 15:40:14 +00:00
|
|
|
lxc_driver->log_libvirtd = 0; /* by default log to container logfile */
|
2008-06-26 16:05:02 +00:00
|
|
|
lxc_driver->have_netns = lxcCheckNetNsSupport();
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2009-07-10 10:40:04 +00:00
|
|
|
rc = virCgroupForDriver("lxc", &lxc_driver->cgroup, privileged, 1);
|
|
|
|
if (rc < 0) {
|
|
|
|
char buf[1024];
|
2011-02-22 17:35:06 +00:00
|
|
|
VIR_DEBUG("Unable to create cgroup for LXC driver: %s",
|
|
|
|
virStrerror(-rc, buf, sizeof(buf)));
|
|
|
|
/* Don't abort startup. We will explicitly report to
|
|
|
|
* the user when they try to start a VM
|
|
|
|
*/
|
2009-07-10 10:40:04 +00:00
|
|
|
}
|
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
/* Call function to load lxc driver configuration information */
|
2008-12-04 21:12:41 +00:00
|
|
|
if (lxcLoadDriverConfig(lxc_driver) < 0)
|
|
|
|
goto cleanup;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
if ((lxc_driver->caps = lxcCapsInit()) == NULL)
|
|
|
|
goto cleanup;
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2009-11-26 17:56:01 +00:00
|
|
|
lxc_driver->caps->privateDataAllocFunc = lxcDomainObjPrivateAlloc;
|
|
|
|
lxc_driver->caps->privateDataFreeFunc = lxcDomainObjPrivateFree;
|
|
|
|
|
2011-05-31 10:03:41 +00:00
|
|
|
/* Get all the running persistent or transient configs first */
|
|
|
|
if (virDomainLoadAllConfigs(lxc_driver->caps,
|
|
|
|
&lxc_driver->domains,
|
|
|
|
lxc_driver->stateDir,
|
|
|
|
NULL,
|
|
|
|
1, NULL, NULL) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
virHashForEach(lxc_driver->domains.objs, lxcReconnectVM, lxc_driver);
|
|
|
|
|
|
|
|
/* Then inactive persistent configs */
|
2010-02-09 18:58:01 +00:00
|
|
|
if (virDomainLoadAllConfigs(lxc_driver->caps,
|
2008-08-13 12:50:55 +00:00
|
|
|
&lxc_driver->domains,
|
|
|
|
lxc_driver->configDir,
|
2008-11-17 16:52:32 +00:00
|
|
|
lxc_driver->autostartDir,
|
2009-06-12 11:38:50 +00:00
|
|
|
0, NULL, NULL) < 0)
|
2008-12-04 21:12:41 +00:00
|
|
|
goto cleanup;
|
2008-08-13 12:50:55 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(lxc_driver);
|
2010-07-29 14:21:17 +00:00
|
|
|
|
|
|
|
lxcAutostartConfigs(lxc_driver);
|
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
return 0;
|
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
cleanup:
|
|
|
|
lxcDriverUnlock(lxc_driver);
|
|
|
|
lxcShutdown();
|
|
|
|
return -1;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
2009-07-06 15:05:32 +00:00
|
|
|
static void lxcNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = opaque;
|
|
|
|
|
|
|
|
if (newVM) {
|
|
|
|
virDomainEventPtr event =
|
|
|
|
virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_DEFINED,
|
|
|
|
VIR_DOMAIN_EVENT_DEFINED_ADDED);
|
|
|
|
if (event)
|
|
|
|
lxcDomainEventQueue(driver, event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* lxcReload:
|
|
|
|
*
|
|
|
|
* Function to restart the LXC driver, it will recheck the configuration
|
|
|
|
* files and perform autostart
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
lxcReload(void) {
|
|
|
|
if (!lxc_driver)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
lxcDriverLock(lxc_driver);
|
2010-02-09 18:58:01 +00:00
|
|
|
virDomainLoadAllConfigs(lxc_driver->caps,
|
2009-07-06 15:05:32 +00:00
|
|
|
&lxc_driver->domains,
|
|
|
|
lxc_driver->configDir,
|
|
|
|
lxc_driver->autostartDir,
|
|
|
|
0, lxcNotifyLoadDomain, lxc_driver);
|
|
|
|
lxcDriverUnlock(lxc_driver);
|
|
|
|
|
|
|
|
lxcAutostartConfigs(lxc_driver);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-03-27 09:34:06 +00:00
|
|
|
static int lxcShutdown(void)
|
2008-03-21 15:03:37 +00:00
|
|
|
{
|
2008-03-31 12:02:12 +00:00
|
|
|
if (lxc_driver == NULL)
|
2008-03-31 14:38:12 +00:00
|
|
|
return(-1);
|
2008-10-10 14:20:37 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(lxc_driver);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
virDomainObjListDeinit(&lxc_driver->domains);
|
2011-01-06 17:42:12 +00:00
|
|
|
virDomainEventStateFree(lxc_driver->domainEventState);
|
2009-07-06 15:04:36 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
virCapabilitiesFree(lxc_driver->caps);
|
|
|
|
VIR_FREE(lxc_driver->configDir);
|
|
|
|
VIR_FREE(lxc_driver->autostartDir);
|
|
|
|
VIR_FREE(lxc_driver->stateDir);
|
|
|
|
VIR_FREE(lxc_driver->logDir);
|
|
|
|
lxcDriverUnlock(lxc_driver);
|
2009-01-15 19:56:05 +00:00
|
|
|
virMutexDestroy(&lxc_driver->lock);
|
2008-12-04 21:12:41 +00:00
|
|
|
VIR_FREE(lxc_driver);
|
2008-03-27 09:34:06 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2008-03-21 15:03:37 +00:00
|
|
|
|
2008-03-27 09:34:06 +00:00
|
|
|
/**
|
|
|
|
* lxcActive:
|
|
|
|
*
|
|
|
|
* Checks if the LXC daemon is active, i.e. has an active domain
|
|
|
|
*
|
|
|
|
* Returns 1 if active, 0 otherwise
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
lxcActive(void) {
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
int active;
|
2008-08-13 12:50:55 +00:00
|
|
|
|
2008-03-31 12:02:12 +00:00
|
|
|
if (lxc_driver == NULL)
|
|
|
|
return(0);
|
2008-08-13 12:50:55 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(lxc_driver);
|
Convert virDomainObjListPtr to use a hash of domain objects
The current virDomainObjListPtr object stores domain objects in
an array. This means that to find a particular objects requires
O(n) time, and more critically acquiring O(n) mutex locks.
The new impl replaces the array with a virHashTable, keyed off
UUID. Finding a object based on UUID is now O(1) time, and only
requires a single mutex lock. Finding by name/id is unchanged
in complexity.
In changing this, all code which iterates over the array had
to be updated to use a hash table iterator function callback.
Several of the functions which were identically duplicating
across all drivers were pulled into domain_conf.c
* src/conf/domain_conf.h, src/conf/domain_conf.c: Change
virDomainObjListPtr to use virHashTable. Add a initializer
method virDomainObjListInit, and rename virDomainObjListFree
to virDomainObjListDeinit, since its not actually freeing
the container, only its contents. Also add some convenient
methods virDomainObjListGetInactiveNames,
virDomainObjListGetActiveIDs and virDomainObjListNumOfDomains
which can be used to implement the correspondingly named
public API entry points in drivers
* src/libvirt_private.syms: Export new methods from domain_conf.h
* src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_conf.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/test/test_driver.c,
src/uml/uml_driver.c, src/vbox/vbox_tmpl.c: Update all code
to deal with hash tables instead of arrays for domains
2009-10-09 11:33:51 +00:00
|
|
|
active = virDomainObjListNumOfDomains(&lxc_driver->domains, 1);
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverUnlock(lxc_driver);
|
2008-03-27 09:34:06 +00:00
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
return active;
|
2008-03-21 15:03:37 +00:00
|
|
|
}
|
|
|
|
|
2010-02-09 18:22:56 +00:00
|
|
|
static int lxcVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *version)
|
2008-09-03 17:21:27 +00:00
|
|
|
{
|
|
|
|
struct utsname ver;
|
|
|
|
|
2009-01-20 17:13:33 +00:00
|
|
|
uname(&ver);
|
2008-09-03 17:21:27 +00:00
|
|
|
|
2010-03-30 14:15:13 +00:00
|
|
|
if (virParseVersionString(ver.release, version) < 0) {
|
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR, _("Unknown release: %s"), ver.release);
|
2008-09-03 17:21:27 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2008-03-27 09:34:06 +00:00
|
|
|
|
2010-02-04 18:19:08 +00:00
|
|
|
static char *lxcGetSchedulerType(virDomainPtr domain ATTRIBUTE_UNUSED,
|
|
|
|
int *nparams)
|
2008-10-08 16:28:48 +00:00
|
|
|
{
|
2009-11-08 21:08:54 +00:00
|
|
|
char *schedulerType = NULL;
|
|
|
|
|
2008-10-08 16:28:48 +00:00
|
|
|
if (nparams)
|
|
|
|
*nparams = 1;
|
|
|
|
|
2009-11-08 21:08:54 +00:00
|
|
|
schedulerType = strdup("posix");
|
|
|
|
|
|
|
|
if (schedulerType == NULL)
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2009-11-08 21:08:54 +00:00
|
|
|
|
|
|
|
return schedulerType;
|
2008-10-08 16:28:48 +00:00
|
|
|
}
|
|
|
|
|
2011-05-17 22:33:53 +00:00
|
|
|
static int
|
|
|
|
lxcSetSchedulerParametersFlags(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
|
|
|
unsigned int flags)
|
2008-10-08 16:28:48 +00:00
|
|
|
{
|
2008-12-04 21:12:41 +00:00
|
|
|
lxc_driver_t *driver = domain->conn->privateData;
|
2008-10-08 16:28:48 +00:00
|
|
|
int i;
|
2008-12-04 21:11:41 +00:00
|
|
|
virCgroupPtr group = NULL;
|
|
|
|
virDomainObjPtr vm = NULL;
|
|
|
|
int ret = -1;
|
2008-10-08 16:28:48 +00:00
|
|
|
|
2011-05-17 22:33:53 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2009-07-10 10:40:04 +00:00
|
|
|
if (driver->cgroup == NULL)
|
2008-12-04 21:12:41 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
|
2008-10-08 16:28:48 +00:00
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
if (vm == NULL) {
|
2010-05-03 11:59:03 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(domain->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-10-08 16:28:48 +00:00
|
|
|
}
|
|
|
|
|
2009-07-10 10:40:04 +00:00
|
|
|
if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0)
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-10-08 16:28:48 +00:00
|
|
|
|
|
|
|
for (i = 0; i < nparams; i++) {
|
2011-05-26 17:39:04 +00:00
|
|
|
virTypedParameterPtr param = ¶ms[i];
|
2010-05-11 13:51:46 +00:00
|
|
|
|
|
|
|
if (STRNEQ(param->field, "cpu_shares")) {
|
|
|
|
lxcError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("Invalid parameter `%s'"), param->field);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-05-26 17:39:04 +00:00
|
|
|
if (param->type != VIR_TYPED_PARAM_ULLONG) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_INVALID_ARG, "%s",
|
2010-05-11 13:51:46 +00:00
|
|
|
_("Invalid type for cpu_shares tunable, expected a 'ullong'"));
|
2009-07-09 13:11:21 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2008-10-08 16:28:48 +00:00
|
|
|
|
2010-05-11 13:51:46 +00:00
|
|
|
int rc = virCgroupSetCpuShares(group, params[i].value.ul);
|
|
|
|
if (rc != 0) {
|
|
|
|
virReportSystemError(-rc, _("failed to set cpu_shares=%llu"),
|
|
|
|
params[i].value.ul);
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-10-08 16:28:48 +00:00
|
|
|
}
|
2011-03-29 13:42:54 +00:00
|
|
|
|
|
|
|
vm->def->cputune.shares = params[i].value.ul;
|
2008-10-08 16:28:48 +00:00
|
|
|
}
|
2008-12-04 21:11:41 +00:00
|
|
|
ret = 0;
|
2008-10-08 16:28:48 +00:00
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
cleanup:
|
2009-09-02 13:02:06 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2008-10-08 16:28:48 +00:00
|
|
|
virCgroupFree(&group);
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:11:41 +00:00
|
|
|
return ret;
|
2008-10-08 16:28:48 +00:00
|
|
|
}
|
|
|
|
|
2011-05-17 22:33:53 +00:00
|
|
|
static int
|
|
|
|
lxcSetSchedulerParameters(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams)
|
|
|
|
{
|
|
|
|
return lxcSetSchedulerParametersFlags(domain, params, nparams, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
lxcGetSchedulerParametersFlags(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
2008-10-08 16:28:48 +00:00
|
|
|
{
|
2008-12-04 21:12:41 +00:00
|
|
|
lxc_driver_t *driver = domain->conn->privateData;
|
2008-12-04 21:11:41 +00:00
|
|
|
virCgroupPtr group = NULL;
|
|
|
|
virDomainObjPtr vm = NULL;
|
2009-07-09 13:11:21 +00:00
|
|
|
unsigned long long val;
|
2008-12-04 21:11:41 +00:00
|
|
|
int ret = -1;
|
2008-10-08 16:28:48 +00:00
|
|
|
|
2011-05-17 22:33:53 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2009-07-10 10:40:04 +00:00
|
|
|
if (driver->cgroup == NULL)
|
2008-12-04 21:12:41 +00:00
|
|
|
return -1;
|
2008-10-08 16:28:48 +00:00
|
|
|
|
2011-05-18 08:52:57 +00:00
|
|
|
if (*nparams < 1) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_INVALID_ARG,
|
avoid many format string warnings
Building with --disable-nls exposed many new warnings like these:
virsh.c:4952: warning: format not a string literal and no format ...
util.c:163: warning: format not a string literal and no format arguments
All but one of the following changes add a "%s" argument before
the offending _(...) argument.
This was the only manual change:
* src/lxc_driver.c (lxcVersion): Use %s and strerror(errno)
rather than %m, to avoid a warning from gcc -Wformat-security.
Add "%s" before each warned about format-string-with-no-%-directive:
* src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML)
(virDomainDefParseString, virDomainDefParseFile):
* src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain)
(__virGetNetwork, virReleaseNetwork, __virGetStoragePool)
(virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol):
* src/lxc_container.c (lxcContainerChild):
* src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine)
(lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML)
(lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart)
(lxcVersion, lxcGetSchedulerParameters):
* src/network_conf.c (virNetworkDefParseString)
(virNetworkDefParseFile):
* src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains):
* src/openvz_driver.c (openvzDomainDefineCmd)
(openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown)
(openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML)
(openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine)
(openvzDomainSetAutostart, openvzDomainGetAutostart)
(openvzDomainSetVcpus):
* src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek):
* src/remote_internal.c (remoteDomainBlockPeek)
(remoteDomainMemoryPeek, remoteAuthPolkit):
* src/sexpr.c (sexpr_new, _string2sexpr):
* src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol)
(virStorageBackendDiskCreateVol):
* src/storage_backend_fs.c
(virStorageBackendFileSystemNetFindPoolSources):
* src/storage_backend_logical.c (virStorageBackendLogicalFindLVs)
(virStorageBackendLogicalFindPoolSources):
* src/test.c (testOpenDefault, testOpenFromFile, testOpen)
(testGetDomainInfo, testDomainRestore)
(testNodeGetCellsFreeMemory):
* src/util.c (virExec):
* src/virsh.c (cmdAttachDevice, cmdDetachDevice)
(cmdAttachInterface, cmdDetachInterface, cmdAttachDisk)
(cmdDetachDisk, cmdEdit):
* src/xend_internal.c (do_connect, wr_sync, xend_op_ext)
(urlencode, xenDaemonDomainCreateXML)
(xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID)
(xenDaemonParseSxprOS, xend_parse_sexp_desc_char)
(xenDaemonParseSxprChar, xenDaemonParseSxprDisks)
(xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain)
(xenDaemonDomainFetch, xenDaemonDomainGetAutostart)
(xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform)
(xenDaemonDomainDefineXML, xenDaemonGetSchedulerType)
(xenDaemonGetSchedulerParameters)
(xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek)
(xenDaemonFormatSxprChr, virDomainXMLDevID):
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu)
(xenXMDomainCreate, xenXMDomainDefineXML)
(xenXMDomainAttachDevice, xenXMDomainDetachDevice):
* src/xml.c (virXPathString, virXPathNumber, virXPathLong)
(virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet):
* src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
|
|
|
"%s", _("Invalid parameter count"));
|
2008-12-04 21:12:41 +00:00
|
|
|
return -1;
|
2008-10-08 16:28:48 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 21:12:41 +00:00
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
|
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
if (vm == NULL) {
|
2010-05-03 11:59:03 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(domain->uuid, uuidstr);
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-10-08 16:28:48 +00:00
|
|
|
}
|
|
|
|
|
2009-07-10 10:40:04 +00:00
|
|
|
if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0)
|
2008-12-04 21:11:41 +00:00
|
|
|
goto cleanup;
|
2008-10-08 16:28:48 +00:00
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
if (virCgroupGetCpuShares(group, &val) != 0)
|
|
|
|
goto cleanup;
|
2008-10-24 11:20:08 +00:00
|
|
|
params[0].value.ul = val;
|
2009-08-03 12:37:44 +00:00
|
|
|
if (virStrcpyStatic(params[0].field, "cpu_shares") == NULL) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
2009-08-03 12:37:44 +00:00
|
|
|
"%s", _("Field cpu_shares too big for destination"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2011-05-26 17:39:04 +00:00
|
|
|
params[0].type = VIR_TYPED_PARAM_ULLONG;
|
2008-10-08 16:28:48 +00:00
|
|
|
|
2011-05-18 08:52:57 +00:00
|
|
|
*nparams = 1;
|
2008-12-04 21:11:41 +00:00
|
|
|
ret = 0;
|
2008-10-08 16:28:48 +00:00
|
|
|
|
2008-12-04 21:11:41 +00:00
|
|
|
cleanup:
|
2009-09-02 13:02:06 +00:00
|
|
|
lxcDriverUnlock(driver);
|
2008-12-04 21:11:41 +00:00
|
|
|
virCgroupFree(&group);
|
2008-12-04 21:12:41 +00:00
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
2008-12-04 21:11:41 +00:00
|
|
|
return ret;
|
2008-10-08 16:28:48 +00:00
|
|
|
}
|
|
|
|
|
2011-05-17 22:33:53 +00:00
|
|
|
static int
|
|
|
|
lxcGetSchedulerParameters(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int *nparams)
|
|
|
|
{
|
|
|
|
return lxcGetSchedulerParametersFlags(domain, params, nparams, 0);
|
|
|
|
}
|
|
|
|
|
2009-11-12 13:55:44 +00:00
|
|
|
#ifdef __linux__
|
|
|
|
static int
|
|
|
|
lxcDomainInterfaceStats(virDomainPtr dom,
|
|
|
|
const char *path,
|
|
|
|
struct _virDomainInterfaceStats *stats)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
int i;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
|
|
|
if (!vm) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
2009-11-12 13:55:44 +00:00
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!virDomainObjIsActive(vm)) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_OPERATION_INVALID,
|
2009-11-12 13:55:44 +00:00
|
|
|
"%s", _("Domain is not running"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check the path is one of the domain's network interfaces. */
|
|
|
|
for (i = 0 ; i < vm->def->nnets ; i++) {
|
|
|
|
if (vm->def->nets[i]->ifname &&
|
|
|
|
STREQ(vm->def->nets[i]->ifname, path)) {
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret == 0)
|
2010-02-04 23:02:10 +00:00
|
|
|
ret = linuxDomainInterfaceStats(path, stats);
|
2009-11-12 13:55:44 +00:00
|
|
|
else
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_INVALID_ARG,
|
2009-11-12 13:55:44 +00:00
|
|
|
_("Invalid path, '%s' is not a known interface"), path);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static int
|
|
|
|
lxcDomainInterfaceStats(virDomainPtr dom,
|
|
|
|
const char *path ATTRIBUTE_UNUSED,
|
|
|
|
struct _virDomainInterfaceStats *stats ATTRIBUTE_UNUSED)
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_NO_SUPPORT, "%s", __FUNCTION__);
|
2009-11-12 13:55:44 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-07-06 15:05:32 +00:00
|
|
|
static int lxcDomainGetAutostart(virDomainPtr dom,
|
|
|
|
int *autostart) {
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
|
|
|
|
if (!vm) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2009-07-06 15:05:32 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
*autostart = vm->autostart;
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lxcDomainSetAutostart(virDomainPtr dom,
|
|
|
|
int autostart) {
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
char *configFile = NULL, *autostartLink = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
|
|
|
|
if (!vm) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2009-07-06 15:05:32 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!vm->persistent) {
|
2011-01-15 15:57:33 +00:00
|
|
|
lxcError(VIR_ERR_OPERATION_INVALID,
|
2009-11-05 12:39:09 +00:00
|
|
|
"%s", _("Cannot set autostart for transient domain"));
|
2009-07-06 15:05:32 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
autostart = (autostart != 0);
|
|
|
|
|
2009-11-05 12:41:14 +00:00
|
|
|
if (vm->autostart == autostart) {
|
|
|
|
ret = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-07-06 15:05:32 +00:00
|
|
|
|
2010-02-09 18:58:01 +00:00
|
|
|
configFile = virDomainConfigFile(driver->configDir,
|
2009-11-05 12:41:14 +00:00
|
|
|
vm->def->name);
|
|
|
|
if (configFile == NULL)
|
|
|
|
goto cleanup;
|
2010-02-09 18:58:01 +00:00
|
|
|
autostartLink = virDomainConfigFile(driver->autostartDir,
|
2009-11-05 12:41:14 +00:00
|
|
|
vm->def->name);
|
|
|
|
if (autostartLink == NULL)
|
|
|
|
goto cleanup;
|
2009-07-06 15:05:32 +00:00
|
|
|
|
2009-11-05 12:41:14 +00:00
|
|
|
if (autostart) {
|
|
|
|
int err;
|
2009-07-06 15:05:32 +00:00
|
|
|
|
2009-11-05 12:41:14 +00:00
|
|
|
if ((err = virFileMakePath(driver->autostartDir))) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(err,
|
2009-11-05 12:41:14 +00:00
|
|
|
_("Cannot create autostart directory %s"),
|
|
|
|
driver->autostartDir);
|
|
|
|
goto cleanup;
|
2009-07-06 15:05:32 +00:00
|
|
|
}
|
|
|
|
|
2009-11-05 12:41:14 +00:00
|
|
|
if (symlink(configFile, autostartLink) < 0) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-11-05 12:41:14 +00:00
|
|
|
_("Failed to create symlink '%s to '%s'"),
|
|
|
|
autostartLink, configFile);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-11-05 12:41:14 +00:00
|
|
|
_("Failed to delete symlink '%s'"),
|
|
|
|
autostartLink);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-07-06 15:05:32 +00:00
|
|
|
}
|
2009-11-05 12:41:14 +00:00
|
|
|
|
|
|
|
vm->autostart = autostart;
|
2009-07-06 15:05:32 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(configFile);
|
|
|
|
VIR_FREE(autostartLink);
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-09-21 14:31:22 +00:00
|
|
|
static int lxcFreezeContainer(lxc_driver_t *driver, virDomainObjPtr vm)
|
|
|
|
{
|
|
|
|
int timeout = 1000; /* In milliseconds */
|
|
|
|
int check_interval = 1; /* In milliseconds */
|
|
|
|
int exp = 10;
|
|
|
|
int waited_time = 0;
|
|
|
|
int ret = -1;
|
|
|
|
char *state = NULL;
|
|
|
|
virCgroupPtr cgroup = NULL;
|
|
|
|
|
|
|
|
if (!(driver->cgroup &&
|
2010-05-17 17:18:12 +00:00
|
|
|
virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) == 0))
|
2009-09-21 14:31:22 +00:00
|
|
|
return -1;
|
|
|
|
|
2010-05-17 17:18:12 +00:00
|
|
|
/* From here on, we know that cgroup != NULL. */
|
|
|
|
|
2009-09-21 14:31:22 +00:00
|
|
|
while (waited_time < timeout) {
|
|
|
|
int r;
|
|
|
|
/*
|
|
|
|
* Writing "FROZEN" to the "freezer.state" freezes the group,
|
|
|
|
* i.e., the container, temporarily transiting "FREEZING" state.
|
|
|
|
* Once the freezing is completed, the state of the group transits
|
|
|
|
* to "FROZEN".
|
|
|
|
* (see linux-2.6/Documentation/cgroups/freezer-subsystem.txt)
|
|
|
|
*/
|
|
|
|
r = virCgroupSetFreezerState(cgroup, "FROZEN");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Returning EBUSY explicitly indicates that the group is
|
|
|
|
* being freezed but incomplete and other errors are true
|
|
|
|
* errors.
|
|
|
|
*/
|
|
|
|
if (r < 0 && r != -EBUSY) {
|
|
|
|
VIR_DEBUG("Writing freezer.state failed with errno: %d", r);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (r == -EBUSY)
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("Writing freezer.state gets EBUSY");
|
2009-09-21 14:31:22 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Unfortunately, returning 0 (success) is likely to happen
|
|
|
|
* even when the freezing has not been completed. Sometimes
|
|
|
|
* the state of the group remains "FREEZING" like when
|
|
|
|
* returning -EBUSY and even worse may never transit to
|
|
|
|
* "FROZEN" even if writing "FROZEN" again.
|
|
|
|
*
|
|
|
|
* So we don't trust the return value anyway and always
|
|
|
|
* decide that the freezing has been complete only with
|
|
|
|
* the state actually transit to "FROZEN".
|
|
|
|
*/
|
|
|
|
usleep(check_interval * 1000);
|
|
|
|
|
|
|
|
r = virCgroupGetFreezerState(cgroup, &state);
|
|
|
|
|
|
|
|
if (r < 0) {
|
|
|
|
VIR_DEBUG("Reading freezer.state failed with errno: %d", r);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_DEBUG("Read freezer.state: %s", state);
|
|
|
|
|
|
|
|
if (STREQ(state, "FROZEN")) {
|
|
|
|
ret = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
waited_time += check_interval;
|
|
|
|
/*
|
|
|
|
* Increasing check_interval exponentially starting with
|
|
|
|
* small initial value treats nicely two cases; One is
|
|
|
|
* a container is under no load and waiting for long period
|
|
|
|
* makes no sense. The other is under heavy load. The container
|
|
|
|
* may stay longer time in FREEZING or never transit to FROZEN.
|
|
|
|
* In that case, eager polling will just waste CPU time.
|
|
|
|
*/
|
|
|
|
check_interval *= exp;
|
|
|
|
VIR_FREE(state);
|
|
|
|
}
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("lxcFreezeContainer timeout");
|
2009-09-21 14:31:22 +00:00
|
|
|
error:
|
|
|
|
/*
|
|
|
|
* If timeout or an error on reading the state occurs,
|
|
|
|
* activate the group again and return an error.
|
|
|
|
* This is likely to fall the group back again gracefully.
|
|
|
|
*/
|
|
|
|
virCgroupSetFreezerState(cgroup, "THAWED");
|
|
|
|
ret = -1;
|
|
|
|
|
|
|
|
cleanup:
|
2010-05-17 17:18:12 +00:00
|
|
|
virCgroupFree(&cgroup);
|
2009-09-21 14:31:22 +00:00
|
|
|
VIR_FREE(state);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lxcDomainSuspend(virDomainPtr dom)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
virDomainEventPtr event = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
|
|
|
|
if (!vm) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2009-09-21 14:31:22 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
Rename internal APis
Rename virDomainIsActive to virDomainObjIsActive, and
virInterfaceIsActive to virInterfaceObjIsActive and finally
virNetworkIsActive to virNetworkObjIsActive.
* src/conf/domain_conf.c, src/conf/domain_conf.h,
src/conf/interface_conf.h, src/conf/network_conf.c,
src/conf/network_conf.h, src/lxc/lxc_driver.c,
src/network/bridge_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_driver.c, src/qemu/qemu_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c: Update for
renamed APIs.
2009-10-20 14:51:03 +00:00
|
|
|
if (!virDomainObjIsActive(vm)) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_OPERATION_INVALID,
|
2009-11-05 12:39:09 +00:00
|
|
|
"%s", _("Domain is not running"));
|
2009-09-21 14:31:22 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-05-04 09:07:01 +00:00
|
|
|
if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) {
|
2009-09-21 14:31:22 +00:00
|
|
|
if (lxcFreezeContainer(driver, vm) < 0) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_OPERATION_FAILED,
|
2009-11-05 12:39:09 +00:00
|
|
|
"%s", _("Suspend operation failed"));
|
2009-09-21 14:31:22 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2011-05-04 09:07:01 +00:00
|
|
|
virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER);
|
2009-09-21 14:31:22 +00:00
|
|
|
|
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_SUSPENDED,
|
|
|
|
VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
|
|
|
|
}
|
|
|
|
|
2010-02-09 18:58:01 +00:00
|
|
|
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
|
2009-09-21 14:31:22 +00:00
|
|
|
goto cleanup;
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (event)
|
|
|
|
lxcDomainEventQueue(driver, event);
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lxcUnfreezeContainer(lxc_driver_t *driver, virDomainObjPtr vm)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
virCgroupPtr cgroup = NULL;
|
|
|
|
|
|
|
|
if (!(driver->cgroup &&
|
|
|
|
virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) == 0))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
ret = virCgroupSetFreezerState(cgroup, "THAWED");
|
|
|
|
|
|
|
|
virCgroupFree(&cgroup);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lxcDomainResume(virDomainPtr dom)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm;
|
|
|
|
virDomainEventPtr event = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
|
|
|
|
if (!vm) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
2009-11-05 12:39:09 +00:00
|
|
|
_("No domain with matching uuid '%s'"), uuidstr);
|
2009-09-21 14:31:22 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
Rename internal APis
Rename virDomainIsActive to virDomainObjIsActive, and
virInterfaceIsActive to virInterfaceObjIsActive and finally
virNetworkIsActive to virNetworkObjIsActive.
* src/conf/domain_conf.c, src/conf/domain_conf.h,
src/conf/interface_conf.h, src/conf/network_conf.c,
src/conf/network_conf.h, src/lxc/lxc_driver.c,
src/network/bridge_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_driver.c, src/qemu/qemu_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c: Update for
renamed APIs.
2009-10-20 14:51:03 +00:00
|
|
|
if (!virDomainObjIsActive(vm)) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_OPERATION_INVALID,
|
2009-11-05 12:39:09 +00:00
|
|
|
"%s", _("Domain is not running"));
|
2009-09-21 14:31:22 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-05-04 09:07:01 +00:00
|
|
|
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
|
2009-09-21 14:31:22 +00:00
|
|
|
if (lxcUnfreezeContainer(driver, vm) < 0) {
|
2010-02-09 18:22:56 +00:00
|
|
|
lxcError(VIR_ERR_OPERATION_FAILED,
|
2009-11-05 12:39:09 +00:00
|
|
|
"%s", _("Resume operation failed"));
|
2009-09-21 14:31:22 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2011-05-04 09:07:01 +00:00
|
|
|
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
|
|
|
|
VIR_DOMAIN_RUNNING_UNPAUSED);
|
2009-09-21 14:31:22 +00:00
|
|
|
|
|
|
|
event = virDomainEventNewFromObj(vm,
|
|
|
|
VIR_DOMAIN_EVENT_RESUMED,
|
|
|
|
VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
|
|
|
|
}
|
|
|
|
|
2010-02-09 18:58:01 +00:00
|
|
|
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
|
2009-09-21 14:31:22 +00:00
|
|
|
goto cleanup;
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (event)
|
|
|
|
lxcDomainEventQueue(driver, event);
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-10-22 13:40:26 +00:00
|
|
|
static int
|
|
|
|
lxcDomainOpenConsole(virDomainPtr dom,
|
|
|
|
const char *devname,
|
|
|
|
virStreamPtr st,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
lxc_driver_t *driver = dom->conn->privateData;
|
|
|
|
virDomainObjPtr vm = NULL;
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
int ret = -1;
|
|
|
|
virDomainChrDefPtr chr = NULL;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
|
|
|
lxcDriverLock(driver);
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
|
|
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
|
|
if (!vm) {
|
|
|
|
lxcError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching uuid '%s'"), uuidstr);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!virDomainObjIsActive(vm)) {
|
|
|
|
lxcError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
"%s", _("domain is not running"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (devname) {
|
|
|
|
/* XXX support device aliases in future */
|
|
|
|
lxcError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("Named device aliases are not supported"));
|
|
|
|
goto cleanup;
|
|
|
|
} else {
|
|
|
|
if (vm->def->console)
|
|
|
|
chr = vm->def->console;
|
|
|
|
else if (vm->def->nserials)
|
|
|
|
chr = vm->def->serials[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!chr) {
|
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("cannot find default console device"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
if (chr->source.type != VIR_DOMAIN_CHR_TYPE_PTY) {
|
2010-10-22 13:40:26 +00:00
|
|
|
lxcError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("character device %s is not using a PTY"), devname);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-04-05 10:27:35 +00:00
|
|
|
if (virFDStreamOpenFile(st, chr->source.data.file.path,
|
|
|
|
0, 0, O_RDWR, false) < 0)
|
2010-10-22 13:40:26 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
if (vm)
|
|
|
|
virDomainObjUnlock(vm);
|
|
|
|
lxcDriverUnlock(driver);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-09-21 14:31:22 +00:00
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
/* Function Tables */
|
|
|
|
static virDriver lxcDriver = {
|
Convert all driver struct intializers to C99 style
Change all the driver struct initializers to use the
C99 style, leaving out unused fields. This will make
it possible to add new APIs without changing every
driver. eg change:
qemudDomainResume, /* domainResume */
qemudDomainShutdown, /* domainShutdown */
NULL, /* domainReboot */
qemudDomainDestroy, /* domainDestroy */
to
.domainResume = qemudDomainResume,
.domainShutdown = qemudDomainShutdown,
.domainDestroy = qemudDomainDestroy,
And get rid of any existing C99 style initializersr which
set NULL, eg change
.listPools = vboxStorageListPools,
.numOfDefinedPools = NULL,
.listDefinedPools = NULL,
.findPoolSources = NULL,
.poolLookupByName = vboxStoragePoolLookupByName,
to
.listPools = vboxStorageListPools,
.poolLookupByName = vboxStoragePoolLookupByName,
2011-05-13 10:16:31 +00:00
|
|
|
.no = VIR_DRV_LXC,
|
|
|
|
.name = "LXC",
|
2011-05-13 13:35:01 +00:00
|
|
|
.open = lxcOpen, /* 0.4.2 */
|
|
|
|
.close = lxcClose, /* 0.4.2 */
|
|
|
|
.version = lxcVersion, /* 0.4.6 */
|
|
|
|
.getHostname = virGetHostname, /* 0.6.3 */
|
|
|
|
.nodeGetInfo = nodeGetInfo, /* 0.6.5 */
|
|
|
|
.getCapabilities = lxcGetCapabilities, /* 0.6.5 */
|
|
|
|
.listDomains = lxcListDomains, /* 0.4.2 */
|
|
|
|
.numOfDomains = lxcNumDomains, /* 0.4.2 */
|
|
|
|
.domainCreateXML = lxcDomainCreateAndStart, /* 0.4.4 */
|
|
|
|
.domainLookupByID = lxcDomainLookupByID, /* 0.4.2 */
|
|
|
|
.domainLookupByUUID = lxcDomainLookupByUUID, /* 0.4.2 */
|
|
|
|
.domainLookupByName = lxcDomainLookupByName, /* 0.4.2 */
|
|
|
|
.domainSuspend = lxcDomainSuspend, /* 0.7.2 */
|
|
|
|
.domainResume = lxcDomainResume, /* 0.7.2 */
|
|
|
|
.domainDestroy = lxcDomainDestroy, /* 0.4.4 */
|
|
|
|
.domainGetOSType = lxcGetOSType, /* 0.4.2 */
|
|
|
|
.domainGetMaxMemory = lxcDomainGetMaxMemory, /* 0.7.2 */
|
|
|
|
.domainSetMaxMemory = lxcDomainSetMaxMemory, /* 0.7.2 */
|
|
|
|
.domainSetMemory = lxcDomainSetMemory, /* 0.7.2 */
|
|
|
|
.domainSetMemoryParameters = lxcDomainSetMemoryParameters, /* 0.8.5 */
|
|
|
|
.domainGetMemoryParameters = lxcDomainGetMemoryParameters, /* 0.8.5 */
|
|
|
|
.domainGetInfo = lxcDomainGetInfo, /* 0.4.2 */
|
|
|
|
.domainGetState = lxcDomainGetState, /* 0.9.2 */
|
|
|
|
.domainGetXMLDesc = lxcDomainGetXMLDesc, /* 0.4.2 */
|
|
|
|
.listDefinedDomains = lxcListDefinedDomains, /* 0.4.2 */
|
|
|
|
.numOfDefinedDomains = lxcNumDefinedDomains, /* 0.4.2 */
|
|
|
|
.domainCreate = lxcDomainStart, /* 0.4.4 */
|
|
|
|
.domainCreateWithFlags = lxcDomainStartWithFlags, /* 0.8.2 */
|
|
|
|
.domainDefineXML = lxcDomainDefine, /* 0.4.2 */
|
|
|
|
.domainUndefine = lxcDomainUndefine, /* 0.4.2 */
|
|
|
|
.domainGetAutostart = lxcDomainGetAutostart, /* 0.7.0 */
|
|
|
|
.domainSetAutostart = lxcDomainSetAutostart, /* 0.7.0 */
|
|
|
|
.domainGetSchedulerType = lxcGetSchedulerType, /* 0.5.0 */
|
|
|
|
.domainGetSchedulerParameters = lxcGetSchedulerParameters, /* 0.5.0 */
|
2011-05-17 22:33:53 +00:00
|
|
|
.domainGetSchedulerParametersFlags = lxcGetSchedulerParametersFlags, /* 0.9.2 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainSetSchedulerParameters = lxcSetSchedulerParameters, /* 0.5.0 */
|
2011-05-17 22:33:53 +00:00
|
|
|
.domainSetSchedulerParametersFlags = lxcSetSchedulerParametersFlags, /* 0.9.2 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainInterfaceStats = lxcDomainInterfaceStats, /* 0.7.3 */
|
|
|
|
.nodeGetCellsFreeMemory = nodeGetCellsFreeMemory, /* 0.6.5 */
|
|
|
|
.nodeGetFreeMemory = nodeGetFreeMemory, /* 0.6.5 */
|
|
|
|
.domainEventRegister = lxcDomainEventRegister, /* 0.7.0 */
|
|
|
|
.domainEventDeregister = lxcDomainEventDeregister, /* 0.7.0 */
|
|
|
|
.isEncrypted = lxcIsEncrypted, /* 0.7.3 */
|
|
|
|
.isSecure = lxcIsSecure, /* 0.7.3 */
|
|
|
|
.domainIsActive = lxcDomainIsActive, /* 0.7.3 */
|
|
|
|
.domainIsPersistent = lxcDomainIsPersistent, /* 0.7.3 */
|
|
|
|
.domainIsUpdated = lxcDomainIsUpdated, /* 0.8.6 */
|
|
|
|
.domainEventRegisterAny = lxcDomainEventRegisterAny, /* 0.8.0 */
|
|
|
|
.domainEventDeregisterAny = lxcDomainEventDeregisterAny, /* 0.8.0 */
|
|
|
|
.domainOpenConsole = lxcDomainOpenConsole, /* 0.8.6 */
|
2008-03-21 15:03:37 +00:00
|
|
|
};
|
|
|
|
|
2008-03-27 09:34:06 +00:00
|
|
|
static virStateDriver lxcStateDriver = {
|
Fix return value in virStateInitialize impl for LXC
The LXC driver was mistakenly returning -1 for lxcStartup()
in scenarios that are not an error. This caused the libvirtd
to quit for unprivileged users. This fixes the return code
of LXC driver, and also adds a "name" field to the virStateDriver
struct and logging to make it easier to find these problems
in the future
* src/driver.h: Add a 'name' field to state driver to allow
easy identification during failures
* src/libvirt.c: Log name of failed driver for virStateInit
failures
* src/lxc/lxc_driver.c: Don't return a failure code for
lxcStartup() if LXC is not available on this host, simply
disable the driver.
* src/network/bridge_driver.c, src/node_device/node_device_devkit.c,
src/node_device/node_device_hal.c, src/opennebula/one_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/secret/secret_driver.c, src/storage/storage_driver.c,
src/uml/uml_driver.c, src/xen/xen_driver.c: Fill in name
field in virStateDriver struct
2009-11-02 23:18:19 +00:00
|
|
|
.name = "LXC",
|
2008-10-06 15:40:37 +00:00
|
|
|
.initialize = lxcStartup,
|
|
|
|
.cleanup = lxcShutdown,
|
|
|
|
.active = lxcActive,
|
2009-07-06 15:05:32 +00:00
|
|
|
.reload = lxcReload,
|
2008-03-27 09:34:06 +00:00
|
|
|
};
|
|
|
|
|
2008-03-21 15:03:37 +00:00
|
|
|
int lxcRegister(void)
|
|
|
|
{
|
|
|
|
virRegisterDriver(&lxcDriver);
|
2008-03-27 09:34:06 +00:00
|
|
|
virRegisterStateDriver(&lxcStateDriver);
|
2008-03-21 15:03:37 +00:00
|
|
|
return 0;
|
|
|
|
}
|