[libvirt] [PATCH] doc: update option force to subcommand change-media
by Guannan Ren
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=837761
---
tools/virsh-domain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index dbcaa25..10361cd 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -8236,7 +8236,7 @@ static const vshCmdOptDef opts_change_media[] = {
"depends on implementation of hypervisor driver")},
{"live", VSH_OT_BOOL, 0, N_("alter live configuration of running domain")},
{"config", VSH_OT_BOOL, 0, N_("alter persistent configuration, effect observed on next boot")},
- {"force", VSH_OT_BOOL, 0, N_("force media insertion")},
+ {"force", VSH_OT_BOOL, 0, N_("force media operation")},
{NULL, 0, 0, NULL}
};
--
1.7.11.4
12 years, 2 months
[libvirt] [PATCH 1/3] cgroup: read more data from cgroup cpuacct.usage_percpu
by Guannan Ren
On NUMA machine, the length of string got from file
cpuacct.usage_percpu is quite large, so expand the
limit of 1024 bytes.
errors like:
Failed to read file \
'/cgroup/cpuacct/libvirt/qemu/rhel6q/cpuacct.usage_percpu': \
Value too large for defined data type
---
src/util/cgroup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/util/cgroup.c b/src/util/cgroup.c
index 8541c7f..5dc0764 100644
--- a/src/util/cgroup.c
+++ b/src/util/cgroup.c
@@ -360,7 +360,7 @@ static int virCgroupGetValueStr(virCgroupPtr group,
VIR_DEBUG("Get value %s", keypath);
- rc = virFileReadAll(keypath, 1024, value);
+ rc = virFileReadAll(keypath, 1024*1024, value);
if (rc < 0) {
rc = -errno;
VIR_DEBUG("Failed to read %s: %m\n", keypath);
--
1.7.11.4
12 years, 2 months
[libvirt] [PATCH V3] implement offline migration
by liguang
Signed-off-by: liguang <lig.fnst(a)cn.fujitsu.com>
---
daemon/remote.c | 46 +++++++++++++++++++++++++++
docs/hvsupport.pl | 2 +
include/libvirt/libvirt.h.in | 6 +++
python/generator.py | 1 +
src/driver.h | 5 +++
src/libvirt.c | 22 +++++++++++++
src/libvirt_public.syms | 1 +
src/remote/remote_driver.c | 70 ++++++++++++++++++++++++++++++++++++++++++
src/remote/remote_protocol.x | 10 +++++-
tools/virsh-domain.c | 69 +++++++++++++++++++++++++++++++++++++++++
10 files changed, 231 insertions(+), 1 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 24928f4..c47a580 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -21,6 +21,9 @@
*/
#include <config.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include "virterror_internal.h"
@@ -48,6 +51,7 @@
#include "virdbus.h"
#include "remote_protocol.h"
#include "qemu_protocol.h"
+#include "fdstream.h"
#define VIR_FROM_THIS VIR_FROM_RPC
@@ -1768,6 +1772,48 @@ no_memory:
goto cleanup;
}
+static int remoteDispatchDomainMigrateOffline(
+ virNetServerPtr server ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client,
+ virNetMessagePtr msg ATTRIBUTE_UNUSED,
+ virNetMessageErrorPtr rerr,
+ remote_domain_migrate_offline_args *args,
+ remote_domain_migrate_offline_ret *ret ATTRIBUTE_UNUSED)
+{
+ int rv = -1;
+ virStreamPtr st = NULL;
+ daemonClientStreamPtr stream = NULL;
+ daemonClientPrivatePtr priv =
+ virNetServerClientGetPrivateData(client);
+
+ if (!priv->conn) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+ goto cleanup;
+ }
+
+ st = virStreamNew(priv->conn, VIR_STREAM_NONBLOCK);
+
+ if (!(stream = daemonCreateClientStream(client, st, remoteProgram, &msg->header)))
+ goto cleanup;
+
+ if (virFDStreamCreateFile(st,
+ args->name,
+ 0, 0,
+ O_WRONLY, 0) < 0)
+ goto cleanup;
+
+
+ if (daemonAddClientStream(client, stream, false) < 0)
+ goto cleanup;
+
+ rv = 0;
+
+cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ return rv;
+}
+
static int
remoteDispatchDomainMigratePrepare(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client ATTRIBUTE_UNUSED,
diff --git a/docs/hvsupport.pl b/docs/hvsupport.pl
index 4871739..47fc505 100755
--- a/docs/hvsupport.pl
+++ b/docs/hvsupport.pl
@@ -128,6 +128,8 @@ $apis{virDomainMigratePrepareTunnel3} = "0.9.2";
$apis{virDomainMigratePerform3} = "0.9.2";
$apis{virDomainMigrateFinish3} = "0.9.2";
$apis{virDomainMigrateConfirm3} = "0.9.2";
+$apis{virDomainMigrateOffline} = "0.10.1";
+
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index cfe5047..7c9cf3c 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -995,6 +995,7 @@ typedef enum {
* whole migration process; this will be used automatically
* when supported */
VIR_MIGRATE_UNSAFE = (1 << 9), /* force migration even if it is considered unsafe */
+ VIR_MIGRATE_OFFLINE = (1 << 10), /* offline migration */
} virDomainMigrateFlags;
/* Domain migration. */
@@ -1030,6 +1031,11 @@ int virDomainMigrateGetMaxSpeed(virDomainPtr domain,
unsigned long *bandwidth,
unsigned int flags);
+int
+virDomainMigrateOffline(virConnectPtr dconn,
+ char *file);
+
+
/**
* VIR_NODEINFO_MAXCPUS:
* @nodeinfo: virNodeInfo instance
diff --git a/python/generator.py b/python/generator.py
index 7beb361..a1b1203 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -427,6 +427,7 @@ skip_impl = (
'virDomainGetDiskErrors',
'virConnectUnregisterCloseCallback',
'virConnectRegisterCloseCallback',
+ 'virDomainMigrateOffline',
)
qemu_skip_impl = (
diff --git a/src/driver.h b/src/driver.h
index e88ab28..9041005 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -881,6 +881,10 @@ typedef char *
int type,
const char *uri,
unsigned int flags);
+typedef int
+ (*virDrvDomainMigrateOffline)(virConnectPtr dconn,
+ const char *file);
+
/**
* _virDriver:
@@ -1068,6 +1072,7 @@ struct _virDriver {
virDrvDomainGetDiskErrors domainGetDiskErrors;
virDrvDomainSetMetadata domainSetMetadata;
virDrvDomainGetMetadata domainGetMetadata;
+ virDrvDomainMigrateOffline domainMigrateOffline;
};
typedef int
diff --git a/src/libvirt.c b/src/libvirt.c
index b034ed6..2878384 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -5001,6 +5001,28 @@ virDomainMigratePeer2Peer (virDomainPtr domain,
}
}
+/**
+ * virDomainMigrateOffline:
+ * @dconn: target connection handler
+ * @file: the file to push to target
+ *
+ * to handle offline migration
+ * Returns -1 if error, else 0
+ */
+int
+virDomainMigrateOffline(virConnectPtr dconn,
+ char *file)
+{
+ VIR_DEBUG("dconn=%p, file=%s", dconn, NULLSTR(file));
+
+ if (!VIR_IS_CONNECT (dconn)) {
+ virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ return dconn->driver->domainMigrateOffline(dconn, file);
+}
/*
* In normal migration, the libvirt client co-ordinates communication
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 92ae95a..e6a7de7 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -550,6 +550,7 @@ LIBVIRT_0.10.0 {
virConnectRegisterCloseCallback;
virConnectUnregisterCloseCallback;
virDomainGetSecurityLabelList;
+ virDomainMigrateOffline;
virDomainPinEmulator;
virDomainGetEmulatorPinInfo;
} LIBVIRT_0.9.13;
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index cf1f079..0952783 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -22,8 +22,12 @@
*/
#include <config.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include <unistd.h>
+#include <stdio.h>
#include <assert.h>
#include "virnetclient.h"
@@ -5247,6 +5251,71 @@ done:
return rv;
}
+static int
+doRemoteReadFile(virStreamPtr st ATTRIBUTE_UNUSED,
+ char *buf, size_t nbytes, void *opaque)
+{
+ int *fd = opaque;
+
+ return read(*fd, buf, nbytes);
+}
+
+static int
+remoteDomainMigrateOffline(virConnectPtr dconn,
+ const char *name)
+{
+ int rv = -1, fd = -1;
+ virStreamPtr st = virStreamNew(dconn, 0);
+ remote_domain_migrate_offline_args args;
+ remote_domain_migrate_offline_ret ret;
+ struct private_data *priv = dconn->privateData;
+ virNetClientStreamPtr netst = NULL;
+
+ remoteDriverLock(priv);
+
+ args.name = (char *)name;
+ memset(&ret, 0, sizeof(ret));
+
+ if (!(netst = virNetClientStreamNew(priv->remoteProgram, REMOTE_PROC_DOMAIN_MIGRATE_OFFLINE, priv->counter)))
+ goto done;
+ if (virNetClientAddStream(priv->client, netst) < 0) {
+ virObjectUnref(netst);
+ goto done;
+ }
+ st->driver = &remoteStreamDrv;
+ st->privateData = netst;
+
+ if ((fd = open(name, O_RDONLY)) < 0)
+ goto done;
+ if (fd == -1)
+ goto done;
+
+ if (call (dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_OFFLINE,
+ (xdrproc_t) xdr_remote_domain_migrate_offline_args, (char *) &args,
+ (xdrproc_t) xdr_remote_domain_migrate_offline_ret, (char *) &ret) == -1) {
+ virNetClientRemoveStream(priv->client, netst);
+ virObjectUnref(netst);
+ st->driver = NULL;
+ st->privateData = NULL;
+ goto done;
+ }
+
+ remoteDriverUnlock(priv);
+
+ if (virStreamSendAll(st, doRemoteReadFile, &fd) < 0)
+ goto done;
+ if (virStreamFinish(st) < 0)
+ goto done;
+ if (VIR_CLOSE(fd) < 0)
+ goto done;
+
+ rv = 0;
+
+done:
+ return rv;
+}
+
+
static void
remoteDomainEventQueue(struct private_data *priv, virDomainEventPtr event)
{
@@ -5491,6 +5560,7 @@ static virDriver remote_driver = {
.domainEventDeregister = remoteDomainEventDeregister, /* 0.5.0 */
.domainMigratePrepare2 = remoteDomainMigratePrepare2, /* 0.5.0 */
.domainMigrateFinish2 = remoteDomainMigrateFinish2, /* 0.5.0 */
+ .domainMigrateOffline = remoteDomainMigrateOffline, /* 0.10.1 */
.nodeDeviceDettach = remoteNodeDeviceDettach, /* 0.6.1 */
.nodeDeviceReAttach = remoteNodeDeviceReAttach, /* 0.6.1 */
.nodeDeviceReset = remoteNodeDeviceReset, /* 0.6.1 */
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 085d5d9..c845737 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2558,6 +2558,13 @@ struct remote_connect_list_all_domains_ret {
unsigned int ret;
};
+struct remote_domain_migrate_offline_args {
+ remote_nonnull_string name;
+};
+
+struct remote_domain_migrate_offline_ret {
+ int retval;
+};
/*----- Protocol. -----*/
@@ -2888,7 +2895,8 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_GET_HOSTNAME = 277, /* autogen autogen */
REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL_LIST = 278, /* skipgen skipgen priority:high */
REMOTE_PROC_DOMAIN_PIN_EMULATOR = 279, /* skipgen skipgen */
- REMOTE_PROC_DOMAIN_GET_EMULATOR_PIN_INFO = 280 /* skipgen skipgen */
+ REMOTE_PROC_DOMAIN_GET_EMULATOR_PIN_INFO = 280, /* skipgen skipgen */
+ REMOTE_PROC_DOMAIN_MIGRATE_OFFLINE = 281 /* skipgen skipgen priority:low*/
/*
* Notice how the entries are grouped in sets of 10 ?
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index dbcaa25..70f7694 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -6698,9 +6698,66 @@ static const vshCmdOptDef opts_migrate[] = {
{"dname", VSH_OT_DATA, 0, N_("rename to new name during migration (if supported)")},
{"timeout", VSH_OT_INT, 0, N_("force guest to suspend if live migration exceeds timeout (in seconds)")},
{"xml", VSH_OT_STRING, 0, N_("filename containing updated XML for the target")},
+ {"offline", VSH_OT_BOOL, 0, N_("migration when there's no domain active")},
{NULL, 0, 0, NULL}
};
+static int
+push_file(char dst[] ATTRIBUTE_UNUSED, char *file, virConnectPtr dconn)
+{
+ int ret = -1;
+
+ ret = virDomainMigrateOffline(dconn, file);
+
+ return ret;
+}
+
+static void
+vshMigrateOffline(vshControl *ctl, char *file, char dst[])
+{
+ xmlDocPtr xml = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ xmlNodePtr *disks = NULL;
+ virConnectPtr dconn = NULL;
+ int i = 0, ret = 0;
+ char *src[] = {NULL};
+
+ if (!vshConnectionUsability(ctl, ctl->conn))
+ return;
+
+ xml = virXMLParseFileCtxt(file, &ctxt);
+ if (!xml) {
+ vshError(NULL, "%s", _("Fail to get domain information from"));
+ goto cleanup;
+ }
+
+ ret = virXPathNodeSet("./devices/disk", ctxt, &disks);
+ if (ret < 0) {
+ vshError(NULL, "%s", _("Fail to get disk node"));
+ goto cleanup;
+ }
+
+ dconn = virConnectOpen(dst);
+ if (!dconn)
+ goto cleanup;
+ vshPrint(ctl, "pushing %s to %s\n", file, dst);
+ if (push_file(dst, file, dconn) < 0)
+ goto cleanup;
+ for (i = 0 ; i < ret ; i++) {
+ ctxt->node = disks[i];
+ src[i] = virXPathString("string(./source/@file"
+ "|./source/@dir"
+ "|./source/@name)", ctxt);
+ vshPrint(ctl, "pushing %s to %s\n", src[i], dst);
+ if (push_file(dst, src[i], dconn) < 0)
+ break;
+ }
+
+cleanup:
+ xmlXPathFreeContext(ctxt);
+ xmlFreeDoc(xml);
+}
+
static void
doMigrate(void *opaque)
{
@@ -6767,12 +6824,24 @@ doMigrate(void *opaque)
if (vshCommandOptBool(cmd, "unsafe"))
flags |= VIR_MIGRATE_UNSAFE;
+ if (vshCommandOptBool(cmd, "offline")) {
+ flags |= VIR_MIGRATE_OFFLINE;
+ if (xmlfile == NULL)
+ vshError(ctl, _("please specify xmlfile for offline migration"));
+ }
+
if (xmlfile &&
virFileReadAll(xmlfile, 8192, &xml) < 0) {
vshError(ctl, _("file '%s' doesn't exist"), xmlfile);
goto out;
}
+ if (flags & VIR_MIGRATE_OFFLINE) {
+ vshMigrateOffline(ctl, (char *)xmlfile, (char *)desturi);
+ goto out;
+ }
+
+
if ((flags & VIR_MIGRATE_PEER2PEER) ||
vshCommandOptBool(cmd, "direct")) {
/* For peer2peer migration or direct migration we only expect one URI
--
1.7.2.5
12 years, 2 months
[libvirt] [PATCH] docs: Fix typo in CPU tuning
by Jiri Denemark
---
docs/formatdomain.html.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index be8489a..bb842f9 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -385,7 +385,7 @@
<vcpupin vcpu="1" cpuset="0,1"/>
<vcpupin vcpu="2" cpuset="2,3"/>
<vcpupin vcpu="3" cpuset="0,4"/>
- <emulatorpin cpuset="1-3"/%gt;
+ <emulatorpin cpuset="1-3"/>
<shares>2048</shares>
<period>1000000</period>
<quota>-1</quota>
--
1.7.12
12 years, 2 months
[libvirt] [PATCH] doc: Fix emulator pinning example in formatdomain.html
by Peter Krempa
Add correct closing tags.
---
Pushing under trivial rule.
---
docs/formatdomain.html.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index be8489a..fbdf36b 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -389,8 +389,8 @@
<shares>2048</shares>
<period>1000000</period>
<quota>-1</quota>
- <emulator_period>1000000</period>
- <emulator_quota>-1</quota>
+ <emulator_period>1000000</emulator_period>
+ <emulator_quota>-1</emulator_quota>
</cputune>
...
</domain>
--
1.7.12
12 years, 2 months
[libvirt] [PATCH v2] conf: Fix parsing of seclabels without model
by Marcelo Cerri
With this patch libvirt tries to assign a model to a single seclabel
when model is missing. Libvirt will look up at host's capabilities and
assign the first model to seclabel.
This patch fixes:
1. The problem with existing guests that have a seclabel defined in its XML.
2. A XML parse error when a guest is restored.
Signed-off-by: Marcelo Cerri <mhcerri(a)linux.vnet.ibm.com>
---
src/conf/domain_conf.c | 64 +++++++++++++++++++++++++++++---------------------
1 file changed, 37 insertions(+), 27 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 224aec5..42c3900 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3102,22 +3102,10 @@ virSecurityLabelDefParseXML(xmlXPathContextPtr ctxt,
def->baselabel = p;
}
- /* Only parse model, if static labelling, or a base
- * label is set, or doing active XML
- */
- if (def->type == VIR_DOMAIN_SECLABEL_STATIC ||
- def->baselabel ||
- (!(flags & VIR_DOMAIN_XML_INACTIVE) &&
- def->type != VIR_DOMAIN_SECLABEL_NONE)) {
-
- p = virXPathStringLimit("string(./@model)",
- VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
- if (p == NULL && def->type != VIR_DOMAIN_SECLABEL_NONE) {
- virReportError(VIR_ERR_XML_ERROR,
- "%s", _("missing security model"));
- }
- def->model = p;
- }
+ /* Always parse model */
+ p = virXPathStringLimit("string(./@model)",
+ VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
+ def->model = p;
return def;
@@ -3129,10 +3117,12 @@ error:
static int
virSecurityLabelDefsParseXML(virDomainDefPtr def,
xmlXPathContextPtr ctxt,
+ virCapsPtr caps,
unsigned int flags)
{
int i = 0, n;
xmlNodePtr *list = NULL, saved_node;
+ virCapsHostPtr host = &caps->host;
/* Check args and save context */
if (def == NULL || ctxt == NULL)
@@ -3159,18 +3149,38 @@ virSecurityLabelDefsParseXML(virDomainDefPtr def,
ctxt->node = saved_node;
VIR_FREE(list);
- /* Checking missing model information
- * when there is more than one seclabel */
- if (n > 1) {
- for(; n; n--) {
- if (def->seclabels[n - 1]->model == NULL) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("missing security model "
- "when using multiple labels"));
- goto error;
- }
+ /* libvirt versions prior to 0.10.0 support just a single seclabel element
+ * in guest's XML and model attribute can be suppressed if type is none or
+ * type is dynamic, baselabel is not defined and INACTIVE flag is set.
+ *
+ * To avoid compatibility issues, for this specific case the first model
+ * defined in host's capabilities is used as model for the seclabel.
+ */
+ if (def->nseclabels == 1 &&
+ def->seclabels[0]->model == NULL &&
+ def->seclabels[0]->type != VIR_DOMAIN_SECLABEL_STATIC &&
+ def->seclabels[0]->baselabel == NULL &&
+ (flags & VIR_DOMAIN_XML_INACTIVE) &&
+ host->nsecModels > 0) {
+
+ /* Copy model from host. */
+ def->seclabels[0]->model = strdup(host->secModels[0].model);
+ if (def->seclabels[0]->model == NULL) {
+ virReportOOMError();
+ goto error;
}
}
+
+ /* Checking missing model information */
+ for(; n; n--) {
+ if (def->seclabels[n - 1]->model == NULL) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing security model "
+ "when using multiple labels"));
+ goto error;
+ }
+ }
+
return 0;
error:
@@ -8166,7 +8176,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
/* analysis of security label, done early even though we format it
* late, so devices can refer to this for defaults */
- if (virSecurityLabelDefsParseXML(def, ctxt, flags) == -1)
+ if (virSecurityLabelDefsParseXML(def, ctxt, caps, flags) == -1)
goto error;
/* Extract domain memory */
--
1.7.12
12 years, 2 months
[libvirt] [PATCH] Fix xen driver following changes to make it stateful
by Jim Fehlig
Recent work to improve support for loadable driver modules introduced
a regression in the xen driver. The legacy xen driver is now a
stateful, libvirtd driver but was not being registered when building
without driver modules.
A slight behavior change was also noted in the xen drivers when
built as driver modules. Previously, explicitly specifying a
connection URI was not necessary, but now
Compiled against library: libvirt 0.10.0
Using library: libvirt 0.10.0
Using API: QEMU 0.10.0
error: failed to get the hypervisor version
error: internal error Cannot find suitable emulator for x86_64
The xen drivers need to be registered before the qemu driver since
the qemu driver will return success with a null connection URI.
This ordering is safe since the xen drivers will decline when not
running the xen kernel.
---
daemon/Makefile.am | 4 ++++
daemon/libvirtd.c | 18 ++++++++++++------
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index b00fc13..b45349c 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -131,6 +131,10 @@ if WITH_LXC
libvirtd_LDADD += ../src/libvirt_driver_lxc.la
endif
+if WITH_XEN
+ libvirtd_LDADD += ../src/libvirt_driver_xen.la
+endif
+
if WITH_LIBXL
libvirtd_LDADD += ../src/libvirt_driver_libxl.la
endif
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 352d4fe..6973df6 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -66,6 +66,9 @@
# ifdef WITH_LXC
# include "lxc/lxc_driver.h"
# endif
+# ifdef WITH_XEN
+# include "xen/xen_driver.h"
+# endif
# ifdef WITH_LIBXL
# include "libxl/libxl_driver.h"
# endif
@@ -382,6 +385,12 @@ static void daemonInitialize(void)
# ifdef WITH_NETCF
virDriverLoadModule("interface");
# endif
+# ifdef WITH_XEN
+ virDriverLoadModule("xen");
+# endif
+# ifdef WITH_LIBXL
+ virDriverLoadModule("libxl");
+# endif
# ifdef WITH_QEMU
virDriverLoadModule("qemu");
# endif
@@ -391,12 +400,6 @@ static void daemonInitialize(void)
# ifdef WITH_UML
virDriverLoadModule("uml");
# endif
-# ifdef WITH_XEN
- virDriverLoadModule("xen");
-# endif
-# ifdef WITH_LIBXL
- virDriverLoadModule("libxl");
-# endif
#else
# ifdef WITH_NETWORK
networkRegister();
@@ -416,6 +419,9 @@ static void daemonInitialize(void)
# ifdef WITH_NWFILTER
nwfilterRegister();
# endif
+# ifdef WITH_XEN
+ xenRegister();
+# endif
# ifdef WITH_LIBXL
libxlRegister();
# endif
--
1.7.9.2
12 years, 2 months
[libvirt] [PATCH] format: suppress auto-generated DAC labels
by Marcelo Cerri
To avoid backward compatibility issues, this patch suppresses
auto-generated DAC labels from XML. This change affects commands such as
dumpxml and save.
Signed-off-by: Marcelo Cerri <mhcerri(a)linux.vnet.ibm.com>
---
src/conf/domain_conf.c | 13 ++++++++++++-
src/conf/domain_conf.h | 1 +
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 42c3900..516821f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11231,6 +11231,12 @@ virSecurityLabelDefFormat(virBufferPtr buf, virSecurityLabelDefPtr def)
if (def->type == VIR_DOMAIN_SECLABEL_DEFAULT)
return;
+ /* To avoid backward compatibility issues, suppress DAC labels that are
+ * automatically generated.
+ */
+ if (STREQ_NULLABLE(def->model, "dac") && def->implicit)
+ return;
+
virBufferAsprintf(buf, "<seclabel type='%s'",
sectype);
@@ -14982,6 +14988,7 @@ virSecurityLabelDefPtr
virDomainDefGetSecurityLabelDef(virDomainDefPtr def, const char *model)
{
int i;
+ virSecurityLabelDefPtr seclabel = NULL;
if (def == NULL || model == NULL)
return NULL;
@@ -14993,7 +15000,11 @@ virDomainDefGetSecurityLabelDef(virDomainDefPtr def, const char *model)
return def->seclabels[i];
}
- return virDomainDefAddSecurityLabelDef(def, model);
+ seclabel = virDomainDefAddSecurityLabelDef(def, model);
+ if (seclabel)
+ seclabel->implicit = true;
+
+ return seclabel;
}
virSecurityDeviceLabelDefPtr
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9ee57e1..3791e50 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -295,6 +295,7 @@ struct _virSecurityLabelDef {
char *baselabel; /* base name of label string */
int type; /* virDomainSeclabelType */
bool norelabel;
+ bool implicit; /* true if seclabel is auto-added */
};
--
1.7.12
12 years, 2 months
[libvirt] [PATCH v1 1/8] New functions for virBitmap
by Hu Tao
In many places we store bitmap info in a chunk of data
(pointed to by a char *), and have redundant codes to
set/unset bits. This patch extends virBitmap, and convert
those codes to use virBitmap in subsquent patches.
---
.gitignore | 1 +
src/libvirt_private.syms | 10 ++
src/util/bitmap.c | 391 +++++++++++++++++++++++++++++++++++++++++++++-
src/util/bitmap.h | 23 +++
tests/Makefile.am | 8 +-
tests/virbitmaptest.c | 134 ++++++++++++++++
6 files changed, 562 insertions(+), 5 deletions(-)
create mode 100644 tests/virbitmaptest.c
diff --git a/.gitignore b/.gitignore
index 5041ddf..9aaa1f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -155,6 +155,7 @@
/tests/storagebackendsheepdogtest
/tests/utiltest
/tests/viratomictest
+/tests/virbitmaptest
/tests/virauthconfigtest
/tests/virbuftest
/tests/virdrivermoduletest
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 27eb43e..9c27218 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -7,11 +7,21 @@
# bitmap.h
virBitmapAlloc;
+virBitmapAllocFromData;
+virBitmapClearAll;
virBitmapClearBit;
+virBitmapCmp;
+virBitmapCopy;
+virBitmapFormat;
virBitmapFree;
virBitmapGetBit;
+virBitmapIsAllSet;
+virBitmapParse;
+virBitmapSetAll;
virBitmapSetBit;
+virBitmapSize;
virBitmapString;
+virBitmapToData;
# buf.h
diff --git a/src/util/bitmap.c b/src/util/bitmap.c
index 53a8a38..2e668c6 100644
--- a/src/util/bitmap.c
+++ b/src/util/bitmap.c
@@ -33,15 +33,17 @@
#include "bitmap.h"
#include "memory.h"
#include "buf.h"
+#include "util.h"
+#include "c-ctype.h"
struct _virBitmap {
size_t size;
- unsigned long *map;
+ unsigned char *map;
};
-#define VIR_BITMAP_BITS_PER_UNIT ((int) sizeof(unsigned long) * CHAR_BIT)
+#define VIR_BITMAP_BITS_PER_UNIT ((int) sizeof(unsigned char) * CHAR_BIT)
#define VIR_BITMAP_UNIT_OFFSET(b) ((b) / VIR_BITMAP_BITS_PER_UNIT)
#define VIR_BITMAP_BIT_OFFSET(b) ((b) % VIR_BITMAP_BITS_PER_UNIT)
#define VIR_BITMAP_BIT(b) (1UL << VIR_BITMAP_BIT_OFFSET(b))
@@ -129,6 +131,12 @@ int virBitmapClearBit(virBitmapPtr bitmap, size_t b)
return 0;
}
+/* Helper function. caller must ensure b < bitmap->size */
+static bool bitmapIsset(virBitmapPtr bitmap, size_t b)
+{
+ return !!(bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] & VIR_BITMAP_BIT(b));
+}
+
/**
* virBitmapGetBit:
* @bitmap: Pointer to bitmap
@@ -145,7 +153,7 @@ int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result)
if (bitmap->size <= b)
return -1;
- *result = !!(bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] & VIR_BITMAP_BIT(b));
+ *result = bitmapIsset(bitmap, b);
return 0;
}
@@ -168,7 +176,7 @@ char *virBitmapString(virBitmapPtr bitmap)
VIR_BITMAP_BITS_PER_UNIT;
while (sz--) {
- virBufferAsprintf(&buf, "%0*lx",
+ virBufferAsprintf(&buf, "%0*hx",
VIR_BITMAP_BITS_PER_UNIT / 4,
bitmap->map[sz]);
}
@@ -180,3 +188,378 @@ char *virBitmapString(virBitmapPtr bitmap)
return virBufferContentAndReset(&buf);
}
+
+/**
+ * virBitmapFormat:
+ * @bitmap: the bitmap
+ *
+ * This function is the counterpart of virBitmapParse. This function creates
+ * a human-readable string representing the bits in bitmap.
+ *
+ * See virBitmapParse for the format of @str.
+ *
+ * Returns the string on success or NULL otherwise. Caller should call
+ * VIR_FREE to free the string.
+ */
+char *virBitmapFormat(virBitmapPtr bitmap)
+{
+ virBuffer buf =VIR_BUFFER_INITIALIZER;
+ int first = -1;
+ int start, cur;
+ int ret;
+ bool isset;
+
+ if (!bitmap)
+ return NULL;
+
+ cur = 0;
+ start = -1;
+ while (cur < bitmap->size) {
+ ret = virBitmapGetBit(bitmap, cur, &isset);
+ if (ret != 0)
+ goto error;
+ else if (isset) {
+ if (start == -1)
+ start = cur;
+ } else if (start != -1) {
+ if (!first)
+ virBufferAddLit(&buf, ",");
+ else
+ first = 0;
+ if (cur == start + 1)
+ virBufferAsprintf(&buf, "%d", start);
+ else
+ virBufferAsprintf(&buf, "%d-%d", start, cur - 1);
+ start = -1;
+ }
+ cur++;
+ }
+
+ if (start != -1) {
+ if (!first)
+ virBufferAddLit(&buf, ",");
+ if (cur == start + 1)
+ virBufferAsprintf(&buf, "%d", start);
+ else
+ virBufferAsprintf(&buf, "%d-%d", start, cur - 1);
+ }
+
+ if (virBufferError(&buf)) {
+error:
+ virBufferFreeAndReset(&buf);
+ return NULL;
+ }
+
+ return virBufferContentAndReset(&buf);
+}
+
+/**
+ * virBitmapParse:
+ * @str: points to a string representing a human-readable bitmap
+ * @bitmap: a bitmap created from @str
+ * @bitmapSize: the upper limit of num of bits in created bitmap
+ *
+ * This function is the counterpart of virBitmapFormat. This function creates
+ * a bitmap, in which bits are set according to the content of @str.
+ *
+ * @str is a comma separated string of fields N, which means a number of bit
+ * to set, and ^N, which means to unset the bit, and N-M for ranges of bits
+ * to set.
+ *
+ * Returns the number of bits set in @bitmap, or -1 in case of error.
+ */
+
+int virBitmapParse(const char *str,
+ char sep,
+ virBitmapPtr *bitmap,
+ size_t bitmapSize)
+{
+ int ret = 0;
+ int neg = 0;
+ const char *cur;
+ char *tmp;
+ int i, start, last;
+
+ if (!str)
+ return -1;
+
+ cur = str;
+ virSkipSpaces(&cur);
+
+ if (*cur == 0)
+ return -1;
+
+ *bitmap = virBitmapAlloc(bitmapSize);
+ if (!*bitmap)
+ return -1;
+
+ while (*cur != 0 && *cur != sep) {
+ /*
+ * 3 constructs are allowed:
+ * - N : a single CPU number
+ * - N-M : a range of CPU numbers with N < M
+ * - ^N : remove a single CPU number from the current set
+ */
+ if (*cur == '^') {
+ cur++;
+ neg = 1;
+ }
+
+ if (!c_isdigit(*cur))
+ goto parse_error;
+
+ if (virStrToLong_i(cur, &tmp, 10, &start) < 0)
+ goto parse_error;
+ if (start < 0)
+ goto parse_error;
+
+ cur = tmp;
+
+ virSkipSpaces(&cur);
+
+ if (*cur == ',' || *cur == 0 || *cur == sep) {
+ if (neg) {
+ if (bitmapIsset(*bitmap, start)) {
+ ignore_value(virBitmapClearBit(*bitmap, start));
+ ret--;
+ }
+ } else {
+ if (!bitmapIsset(*bitmap, start)) {
+ ignore_value(virBitmapSetBit(*bitmap, start));
+ ret++;
+ }
+ }
+ } else if (*cur == '-') {
+ if (neg)
+ goto parse_error;
+
+ cur++;
+ virSkipSpaces(&cur);
+
+ if (virStrToLong_i(cur, &tmp, 10, &last) < 0)
+ goto parse_error;
+ if (last < start)
+ goto parse_error;
+
+ cur = tmp;
+
+ for (i = start; i <= last; i++) {
+ if (!bitmapIsset(*bitmap, i)) {
+ ignore_value(virBitmapSetBit(*bitmap, i));
+ ret++;
+ }
+ }
+
+ virSkipSpaces(&cur);
+ }
+
+ if (*cur == ',') {
+ cur++;
+ virSkipSpaces(&cur);
+ neg = 0;
+ } else if(*cur == 0 || *cur == sep) {
+ break;
+ } else {
+ goto parse_error;
+ }
+ }
+
+ return ret;
+
+parse_error:
+ virBitmapFree(*bitmap);
+ *bitmap = NULL;
+ return -1;
+}
+
+/**
+ * virBitmapCopy:
+ * @src: the source bitmap.
+ *
+ * Makes a copy of bitmap @src.
+ *
+ * returns the copied bitmap on success, or NULL otherwise. Caller
+ * should call virBitmapFree to free the returned bitmap.
+ */
+virBitmapPtr virBitmapCopy(virBitmapPtr src)
+{
+ virBitmapPtr dst;
+ size_t sz;
+
+ sz = (src->size + VIR_BITMAP_BITS_PER_UNIT - 1) /
+ VIR_BITMAP_BITS_PER_UNIT;
+
+ if (VIR_ALLOC(dst) < 0)
+ return NULL;
+
+ if (VIR_ALLOC_N(dst->map, sz) < 0) {
+ VIR_FREE(dst);
+ return NULL;
+ }
+
+ memcpy(dst->map, src->map, sz);
+ dst->size = src->size;
+
+ return dst;
+}
+
+/**
+ * virBitmapAllocFromData:
+ * @data: the data
+ * @len: len of @data in byte
+ *
+ * Allocate a bitmap from a chunk of data containing bits
+ * information
+ *
+ * Returns a pointer to the allocated bitmap or NULL if
+ * memory cannot be allocated.
+ */
+virBitmapPtr virBitmapAllocFromData(void *data, int len)
+{
+ virBitmapPtr bitmap;
+
+ bitmap = virBitmapAlloc(len * CHAR_BIT);
+ if (!bitmap)
+ return NULL;
+
+ memcpy(bitmap->map, data, len);
+
+ return bitmap;
+}
+
+/**
+ * virBitmapToData:
+ * @data: the data
+ * @len: len of @data in byte
+ *
+ * Convert a bitmap to a chunk of data containing bits information.
+ * Data consists of sequential bytes, with lower bytes containing
+ * lower bits.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int virBitmapToData(virBitmapPtr bitmap, char **data, int *dataLen)
+{
+ size_t sz;
+
+ sz = (bitmap->size + VIR_BITMAP_BITS_PER_UNIT - 1) /
+ VIR_BITMAP_BITS_PER_UNIT;
+
+ if (VIR_ALLOC_N(*data, sz) < 0)
+ return -1;
+
+ memcpy(*data, bitmap->map, sz);
+ *dataLen = sz;
+
+ return 0;
+}
+
+/**
+ * virBitmapCmp:
+ * @b1: bitmap 1
+ * @b2: bitmap 2
+ *
+ * Compares two bitmaps. Returns true if two bitmaps have exactly
+ * the same set of bits set, otherwise false.
+ */
+bool virBitmapCmp(virBitmapPtr b1, virBitmapPtr b2)
+{
+ virBitmapPtr b;
+ size_t sz1, sz2, sz;
+ int i;
+
+ sz1 = (b1->size + VIR_BITMAP_BITS_PER_UNIT - 1) /
+ VIR_BITMAP_BITS_PER_UNIT;
+ sz2 = (b2->size + VIR_BITMAP_BITS_PER_UNIT - 1) /
+ VIR_BITMAP_BITS_PER_UNIT;
+
+ sz = sz1 < sz2 ? sz1 : sz2;
+
+ for (i = 0; i < sz; i++) {
+ if (b1->map[i] != b2->map[i])
+ return false;
+ }
+
+ b = sz1 > sz ? b1 : b2;
+ sz = sz1 > sz ? sz1 : sz2;
+ for (; i < sz; i++) {
+ if (b->map[i])
+ return false;
+ }
+
+ return true;
+}
+
+size_t virBitmapSize(virBitmapPtr bitmap)
+{
+ return bitmap->size;
+}
+
+/**
+ * virBitmapSetAll:
+ * @bitmap: the bitmap
+ *
+ * set all bits in @bitmap.
+ */
+void virBitmapSetAll(virBitmapPtr bitmap)
+{
+ int i;
+ size_t sz;
+
+ sz = (bitmap->size + VIR_BITMAP_BITS_PER_UNIT - 1) /
+ VIR_BITMAP_BITS_PER_UNIT;
+
+ for (i = 0; i < sz; i++)
+ bitmap->map[i] = -1;
+}
+
+/**
+ * virBitmapClearAll:
+ * @bitmap: the bitmap
+ *
+ * clear all bits in @bitmap.
+ */
+void virBitmapClearAll(virBitmapPtr bitmap)
+{
+ int i;
+ size_t sz;
+
+ sz = (bitmap->size + VIR_BITMAP_BITS_PER_UNIT - 1) /
+ VIR_BITMAP_BITS_PER_UNIT;
+
+ for (i = 0; i < sz; i++)
+ bitmap->map[i] = 0;
+}
+
+/**
+ * virBitmapIsAllSet:
+ * @bitmap: the bitmap to check
+ *
+ * check if all bits in @bitmap are set.
+ */
+bool virBitmapIsAllSet(virBitmapPtr bitmap)
+{
+ int i;
+ int unusedBits;
+ size_t sz, tmp;
+
+ sz = (bitmap->size + VIR_BITMAP_BITS_PER_UNIT - 1) /
+ VIR_BITMAP_BITS_PER_UNIT;
+ unusedBits = sz * VIR_BITMAP_BITS_PER_UNIT - bitmap->size;
+
+ tmp = sz;
+ if (unusedBits > 0)
+ tmp = sz - 1;
+
+ for (i = 0; i < tmp; i++)
+ if (bitmap->map[i] != (unsigned char)-1)
+ return false;
+
+ if (unusedBits > 0) {
+ if ((bitmap->map[sz - 1] & ((1 << (VIR_BITMAP_BITS_PER_UNIT - unusedBits + 1)) - 1))
+ != ((1 << (VIR_BITMAP_BITS_PER_UNIT - unusedBits + 1)) - 1))
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/util/bitmap.h b/src/util/bitmap.h
index c3e6222..4823604 100644
--- a/src/util/bitmap.h
+++ b/src/util/bitmap.h
@@ -62,4 +62,27 @@ int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result)
char *virBitmapString(virBitmapPtr bitmap)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+char *virBitmapFormat(virBitmapPtr bitmap);
+
+int virBitmapParse(const char *str,
+ char sep,
+ virBitmapPtr *bitmap,
+ size_t bitmapSize);
+
+virBitmapPtr virBitmapCopy(virBitmapPtr src);
+
+virBitmapPtr virBitmapAllocFromData(void *data, int len);
+
+int virBitmapToData(virBitmapPtr bitmap, char **data, int *dataLen);
+
+bool virBitmapCmp(virBitmapPtr b1, virBitmapPtr b2);
+
+size_t virBitmapSize(virBitmapPtr bitmap);
+
+void virBitmapSetAll(virBitmapPtr bitmap);
+
+void virBitmapClearAll(virBitmapPtr bitmap);
+
+bool virBitmapIsAllSet(virBitmapPtr bitmap);
+
#endif
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8cf8015..ec436df 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -92,7 +92,8 @@ test_programs = virshtest sockettest \
viratomictest \
utiltest virnettlscontexttest shunloadtest \
virtimetest viruritest virkeyfiletest \
- virauthconfigtest
+ virauthconfigtest \
+ virbitmaptest
if WITH_SECDRIVER_SELINUX
test_programs += securityselinuxtest
@@ -562,6 +563,10 @@ viratomictest_SOURCES = \
viratomictest.c testutils.h testutils.c
viratomictest_LDADD = $(LDADDS)
+virbitmaptest_SOURCES = \
+ virbitmaptest.c testutils.h testutils.c
+virbitmaptest_LDADD = $(LDADDS)
+
jsontest_SOURCES = \
jsontest.c testutils.h testutils.c
jsontest_LDADD = $(LDADDS)
@@ -592,6 +597,7 @@ shunloadtest_SOURCES = \
shunloadtest_LDADD = $(LIB_PTHREAD)
shunloadtest_DEPENDENCIES = libshunload.la
+
if WITH_CIL
CILOPTFLAGS =
CILOPTINCS =
diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c
new file mode 100644
index 0000000..c688618
--- /dev/null
+++ b/tests/virbitmaptest.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2012 Fujitsu.
+ *
+ * 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, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <config.h>
+
+#include <time.h>
+#include <sched.h>
+
+#include "testutils.h"
+
+#include "bitmap.h"
+
+static int test1(const void *data ATTRIBUTE_UNUSED)
+{
+ virBitmapPtr bitmap;
+ int size;
+ int bit;
+ bool result;
+
+ size = 1024;
+ bit = 100;
+ bitmap = virBitmapAlloc(size);
+ if (virBitmapSetBit(bitmap, bit) < 0)
+ return -1;
+
+ if (virBitmapGetBit(bitmap, bit, &result) < 0)
+ return -1;
+
+ if (!result)
+ return -1;
+
+ if (virBitmapGetBit(bitmap, bit + 1, &result) < 0)
+ return -1;
+
+ if (result)
+ return -1;
+
+ return 0;
+}
+
+bool testBit(virBitmapPtr bitmap, unsigned int start, unsigned int end)
+{
+ int i;
+ bool result;
+
+ for (i = start; i <= end; i++) {
+ if (virBitmapGetBit(bitmap, i, &result) < 0)
+ return 0;
+ if (!result)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int test2(const void *data ATTRIBUTE_UNUSED)
+{
+ const char *bitsString1 = "1-32,50,88-99,1021-1023";
+ char *bitsString2 = NULL;
+ virBitmapPtr bitmap = NULL;
+ int ret = -1;
+ int size = 1024;
+
+ if (virBitmapParse(bitsString1, 0, &bitmap, size) < 0)
+ goto error;
+
+ if (!testBit(bitmap, 1, 32))
+ goto error;
+ if (!testBit(bitmap, 50, 50))
+ goto error;
+ if (!testBit(bitmap, 88, 99))
+ goto error;
+ if (!testBit(bitmap, 1021, 1023))
+ goto error;
+
+ if (testBit(bitmap, 0, 0))
+ goto error;
+ if (testBit(bitmap, 33,49))
+ goto error;
+ if (testBit(bitmap, 51,87))
+ goto error;
+ if (testBit(bitmap, 100,1020))
+ goto error;
+
+ bitsString2 = virBitmapFormat(bitmap);
+ if (strcmp(bitsString1, bitsString2))
+ goto error;
+
+ virBitmapSetAll(bitmap);
+ if (!testBit(bitmap, 0, size - 1))
+ goto error;
+
+ virBitmapClearAll(bitmap);
+ if (testBit(bitmap, 0, size - 1))
+ goto error;
+
+ ret = 0;
+
+error:
+ virBitmapFree(bitmap);
+ VIR_FREE(bitsString2);
+ return ret;
+}
+
+static int
+mymain(void)
+{
+ int ret = 0;
+
+ if (virtTestRun("test1", 1, test1, NULL) < 0)
+ ret = -1;
+ if (virtTestRun("test2", 1, test2, NULL) < 0)
+ ret = -1;
+
+ return ret;
+}
+
+VIRT_TEST_MAIN(mymain)
--
1.7.10.2
12 years, 2 months
[libvirt] [PATCH] conf: Fix parsing of seclabels without model
by Marcelo Cerri
With this patch libvirt tries to assign a model to seclabels when model
is missing. Libvirt will look up at host's capabilities and assign a
model in order to each seclabel that doesn't have a model assigned.
This patch fixes:
1. The problem with existing guests that have a seclabel defined in its XML.
2. A XML parse error when a guest is restored.
Signed-off-by: Marcelo Cerri <mhcerri(a)linux.vnet.ibm.com>
---
src/conf/domain_conf.c | 56 ++++++++++++++++++++++++++------------------------
1 file changed, 29 insertions(+), 27 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 224aec5..5316b59 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3102,22 +3102,10 @@ virSecurityLabelDefParseXML(xmlXPathContextPtr ctxt,
def->baselabel = p;
}
- /* Only parse model, if static labelling, or a base
- * label is set, or doing active XML
- */
- if (def->type == VIR_DOMAIN_SECLABEL_STATIC ||
- def->baselabel ||
- (!(flags & VIR_DOMAIN_XML_INACTIVE) &&
- def->type != VIR_DOMAIN_SECLABEL_NONE)) {
-
- p = virXPathStringLimit("string(./@model)",
- VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
- if (p == NULL && def->type != VIR_DOMAIN_SECLABEL_NONE) {
- virReportError(VIR_ERR_XML_ERROR,
- "%s", _("missing security model"));
- }
- def->model = p;
- }
+ /* Always parse model */
+ p = virXPathStringLimit("string(./@model)",
+ VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
+ def->model = p;
return def;
@@ -3129,10 +3117,12 @@ error:
static int
virSecurityLabelDefsParseXML(virDomainDefPtr def,
xmlXPathContextPtr ctxt,
+ virCapsPtr caps,
unsigned int flags)
{
- int i = 0, n;
+ int i, j, n;
xmlNodePtr *list = NULL, saved_node;
+ virCapsHostPtr host = &caps->host;
/* Check args and save context */
if (def == NULL || ctxt == NULL)
@@ -3159,14 +3149,26 @@ virSecurityLabelDefsParseXML(virDomainDefPtr def,
ctxt->node = saved_node;
VIR_FREE(list);
- /* Checking missing model information
- * when there is more than one seclabel */
- if (n > 1) {
- for(; n; n--) {
- if (def->seclabels[n - 1]->model == NULL) {
+ /* Check missing model information */
+ for (i = j = 0; i < n; i++) {
+ /* If model is missing, try to assign it based on driver's
+ * capabilities.
+ */
+ if (def->seclabels[i]->model == NULL) {
+ /* Check if there's any host's security model that wasn't
+ * assigned yet.
+ */
+ if (j >= host->nsecModels) {
virReportError(VIR_ERR_XML_ERROR, "%s",
- _("missing security model "
- "when using multiple labels"));
+ _("missing security model and "
+ "it can't be assigned based on "
+ "host's capabilities"));
+ goto error;
+ }
+ /* Copy model from host. */
+ def->seclabels[i]->model = strdup(host->secModels[j++].model);
+ if (def->seclabels[i]->model == NULL) {
+ virReportOOMError();
goto error;
}
}
@@ -3175,8 +3177,8 @@ virSecurityLabelDefsParseXML(virDomainDefPtr def,
error:
ctxt->node = saved_node;
- for (; i > 0; i--) {
- virSecurityLabelDefFree(def->seclabels[i - 1]);
+ for (i = 0; i < n; i++) {
+ virSecurityLabelDefFree(def->seclabels[i]);
}
VIR_FREE(def->seclabels);
def->nseclabels = 0;
@@ -8166,7 +8168,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
/* analysis of security label, done early even though we format it
* late, so devices can refer to this for defaults */
- if (virSecurityLabelDefsParseXML(def, ctxt, flags) == -1)
+ if (virSecurityLabelDefsParseXML(def, ctxt, caps, flags) == -1)
goto error;
/* Extract domain memory */
--
1.7.12
12 years, 2 months