[libvirt] [PATCH 2/2] Ignore backing file errors in FS storage pool (v2)
by Philipp Hahn
Currently a single storage volume with a broken backing file will disable the
whole storage pool. This can happen when the backing file is on some
unavailable network storage or if the backing volume is deleted, while the
storage volumes using it are not.
Since the storage pool then can not be re-activated, re-creating the missing
or
deleting the now useless volumes using libvirt only is impossible.
To "fix" this case, all errors detected during storage pool activation are now
(silently) ignored. Errors are still logged by the called functions, which
have
more knowledge on the detailed error condition.
To reproduce:
dir=$(mktemp -d)
virsh pool-create-as tmp dir '' '' '' '' "$dir"
virsh vol-create-as --format qcow2 tmp back 1G
virsh vol-create-as --format qcow2 --backing-vol-format qcow2 --backing-vol
back tmp cow 1G
virsh vol-delete --pool tmp back
virsh pool-refresh tmp
After the last step, the pool will be gone (because it was not persistent). As
long as the now broken image stays in the directory, you will not be able to
re-create or re-start the pool.
Signed-off-by: Philipp Hahn <hahn(a)univention.de>
---
src/storage/storage_backend_fs.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
13 years, 8 months
[libvirt] [PATCH 2/2] Ignore backing file errors in FS storage pool
by Philipp Hahn
Currently a single storage volume with a broken backing file will disable the
whole storage pool. This can happen when the backing file is on some
unavailable network storage or if the backing volume is deleted, while the
storage volumes using it are not.
Since the storage pool then can not be re-activated, re-creating the missing
or
deleting the now useless volumes using libvirt only is impossible.
To "fix" this case, all errors detected during storage pool activation are now
(silently) ignored. Errors are still logged by the called functions, which
have
more knowledge on the detailed error condition.
To reproduce:
dir=$(mktemp -d)
virsh pool-create-as tmp dir '' '' '' '' "$dir"
virsh vol-create-as --format qcow2 tmp back 1G
virsh vol-create-as --format qcow2 --backing-vol-format qcow2 --backing-vol
back tmp cow 1G
virsh vol-delete --pool tmp back
virsh pool-refresh tmp
After the last step, the pool will be gone (because it was not persistent). As
long as the now broken image stays in the directory, you will not be able to
re-create or re-start the pool.
Signed-off-by: Philipp Hahn <hahn(a)univention.de>
---
src/storage/storage_backend_fs.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
13 years, 8 months
[libvirt] [PATCH] Add APIs for killing off processes inside a cgroup
by Daniel P. Berrange
The virCgroupKill method kills all PIDs found in a cgroup
The virCgroupKillRecursively method does this recursively
for child cgroups.
The virCgroupKillPainfully method does a recursive kill
several times in a row until everything has really died
---
src/libvirt_private.syms | 3 +
src/util/cgroup.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/cgroup.h | 4 +
3 files changed, 236 insertions(+), 0 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 797a670..989b3eb 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -74,6 +74,9 @@ virCgroupGetMemoryHardLimit;
virCgroupGetMemorySoftLimit;
virCgroupGetMemoryUsage;
virCgroupGetSwapHardLimit;
+virCgroupKill;
+virCgroupKillRecursive;
+virCgroupKillPainfully;
virCgroupMounted;
virCgroupRemove;
virCgroupSetBlkioWeight;
diff --git a/src/util/cgroup.c b/src/util/cgroup.c
index b71eef9..2c7efb4 100644
--- a/src/util/cgroup.c
+++ b/src/util/cgroup.c
@@ -23,6 +23,7 @@
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <signal.h>
#include <libgen.h>
#include <dirent.h>
@@ -32,6 +33,7 @@
#include "cgroup.h"
#include "logging.h"
#include "files.h"
+#include "hash.h"
#define CGROUP_MAX_VAL 512
@@ -258,6 +260,19 @@ static int virCgroupPathOfController(virCgroupPtr group,
const char *key,
char **path)
{
+ if (controller == -1) {
+ int i;
+ for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
+ if (group->controllers[i].mountPoint &&
+ group->controllers[i].placement) {
+ controller = i;
+ break;
+ }
+ }
+ }
+ if (controller == -1)
+ return -ENOSYS;
+
if (group->controllers[controller].mountPoint == NULL)
return -ENOENT;
@@ -1291,3 +1306,217 @@ int virCgroupGetFreezerState(virCgroupPtr group, char **state)
VIR_CGROUP_CONTROLLER_CPU,
"freezer.state", state);
}
+
+static int virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids)
+{
+ int rc;
+ int killedAny = 0;
+ char *keypath = NULL;
+ bool done = false;
+ VIR_DEBUG("group=%p path=%s signum=%d pids=%p", group, group->path, signum, pids);
+
+ rc = virCgroupPathOfController(group, -1, "tasks", &keypath);
+ if (rc != 0) {
+ VIR_DEBUG("No path of %s, tasks", group->path);
+ return rc;
+ }
+
+ /* PIDs may be forking as we kill them, so loop
+ * until there are no new PIDs found
+ */
+ while (!done) {
+ done = true;
+ FILE *fp;
+ if (!(fp = fopen(keypath, "r"))) {
+ rc = -errno;
+ VIR_DEBUG("Failed to read %s: %m\n", keypath);
+ goto cleanup;
+ } else {
+ while (!feof(fp)) {
+ unsigned long pid;
+ if (fscanf(fp, "%lu", &pid) != 1) {
+ if (feof(fp))
+ break;
+ rc = -errno;
+ break;
+ }
+ if (virHashLookup(pids, (void*)pid))
+ continue;
+
+ VIR_DEBUG("pid=%lu", pid);
+ if (kill((pid_t)pid, signum) < 0) {
+ if (errno != ESRCH) {
+ rc = -errno;
+ goto cleanup;
+ }
+ /* Leave RC == 0 since we didn't kill one */
+ } else {
+ killedAny = 1;
+ done = false;
+ }
+
+ virHashAddEntry(pids, (void*)pid, (void*)1);
+ }
+ fclose(fp);
+ }
+ }
+
+ rc = killedAny ? 1 : 0;
+
+cleanup:
+ VIR_FREE(keypath);
+
+ return rc;
+}
+
+
+static unsigned long virCgroupPidCode(const void *name)
+{
+ return (unsigned long)name;
+}
+static bool virCgroupPidEqual(const void *namea, const void *nameb)
+{
+ return namea == nameb;
+}
+static void *virCgroupPidCopy(const void *name)
+{
+ return (void*)name;
+}
+
+/*
+ * Returns
+ * < 0 : errno that occurred
+ * 0 : no PIDs killed
+ * 1 : at least one PID killed
+ */
+int virCgroupKill(virCgroupPtr group, int signum)
+{
+ VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum);
+ int rc;
+ /* The 'tasks' file in cgroups can contain duplicated
+ * pids, so we use a hash to track which we've already
+ * killed.
+ */
+ virHashTablePtr pids = virHashCreateFull(100,
+ NULL,
+ virCgroupPidCode,
+ virCgroupPidEqual,
+ virCgroupPidCopy,
+ NULL);
+
+ rc = virCgroupKillInternal(group, signum, pids);
+
+ virHashFree(pids);
+
+ return rc;
+}
+
+
+static int virCgroupKillRecursiveInternal(virCgroupPtr group, int signum, virHashTablePtr pids, bool dormdir)
+{
+ int rc;
+ int killedAny = 0;
+ char *keypath = NULL;
+ DIR *dp;
+ virCgroupPtr subgroup = NULL;
+ struct dirent *ent;
+ VIR_DEBUG("group=%p path=%s signum=%d pids=%p", group, group->path, signum, pids);
+
+ rc = virCgroupPathOfController(group, -1, "", &keypath);
+ if (rc != 0) {
+ VIR_DEBUG("No path of %s, tasks", group->path);
+ return rc;
+ }
+
+ if ((rc = virCgroupKillInternal(group, signum, pids)) != 0)
+ return rc;
+
+ VIR_DEBUG("Iterate over children of %s", keypath);
+ if (!(dp = opendir(keypath))) {
+ rc = -errno;
+ return rc;
+ }
+
+ while ((ent = readdir(dp))) {
+ char *subpath;
+
+ if (STREQ(ent->d_name, "."))
+ continue;
+ if (STREQ(ent->d_name, ".."))
+ continue;
+ if (ent->d_type != DT_DIR)
+ continue;
+
+ VIR_DEBUG("Process subdir %s", ent->d_name);
+ if (virAsprintf(&subpath, "%s/%s", group->path, ent->d_name) < 0) {
+ rc = -ENOMEM;
+ goto cleanup;
+ }
+
+ if ((rc = virCgroupNew(subpath, &subgroup)) != 0)
+ goto cleanup;
+
+ if ((rc = virCgroupKillRecursiveInternal(subgroup, signum, pids, true)) < 0)
+ goto cleanup;
+ if (rc == 1)
+ killedAny = 1;
+
+ if (dormdir)
+ virCgroupRemove(subgroup);
+
+ virCgroupFree(&subgroup);
+ }
+
+ rc = killedAny;
+
+cleanup:
+ virCgroupFree(&subgroup);
+ closedir(dp);
+
+ return rc;
+}
+
+int virCgroupKillRecursive(virCgroupPtr group, int signum)
+{
+ int rc;
+ VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum);
+ virHashTablePtr pids = virHashCreateFull(100,
+ NULL,
+ virCgroupPidCode,
+ virCgroupPidEqual,
+ virCgroupPidCopy,
+ NULL);
+
+ rc = virCgroupKillRecursiveInternal(group, signum, pids, false);
+
+ virHashFree(pids);
+
+ return rc;
+}
+
+
+int virCgroupKillPainfully(virCgroupPtr group)
+{
+ int i;
+ int rc;
+ VIR_DEBUG("cgroup=%p path=%s", group, group->path);
+ for (i = 0 ; i < 15 ; i++) {
+ int signum;
+ if (i == 0)
+ signum = SIGTERM;
+ else if (i == 8)
+ signum = SIGKILL;
+ else
+ signum = 0; /* Just check for existance */
+
+ rc = virCgroupKillRecursive(group, signum);
+ VIR_DEBUG("Iteration %d rc=%d", i, rc);
+ /* If rc == -1 we hit error, if 0 we ran out of PIDs */
+ if (rc <= 0)
+ break;
+
+ usleep(200 * 1000);
+ }
+ VIR_DEBUG("Complete %d", rc);
+ return rc;
+}
diff --git a/src/util/cgroup.h b/src/util/cgroup.h
index f1bdd0f..d468cb3 100644
--- a/src/util/cgroup.h
+++ b/src/util/cgroup.h
@@ -90,4 +90,8 @@ int virCgroupRemove(virCgroupPtr group);
void virCgroupFree(virCgroupPtr *group);
bool virCgroupMounted(virCgroupPtr cgroup, int controller);
+int virCgroupKill(virCgroupPtr group, int signum);
+int virCgroupKillRecursive(virCgroupPtr group, int signum);
+int virCgroupKillPainfully(virCgroupPtr group);
+
#endif /* CGROUP_H */
--
1.7.4
13 years, 8 months
[libvirt] [PATCH 1/2] libvirt/qemu : allow persistent modification of disks via A(De)ttachDeviceFlags
by KAMEZAWA Hiroyuki
Sorry, pervious mail was sent to wrong list...
==
>From 030135224dd6563af0fb8615dc6a4b8e6084410d Mon Sep 17 00:00:00 2001
From: KAMEZAWA Hiroyuki <kamezawa(a)bluextal.(none)>
Date: Wed, 23 Feb 2011 15:25:26 +0900
Subject: [PATCH 1/2] libvirt/qemu : support attach/detach-disk --persistent
Now, only Xen supports 'virsh attach/detach-disk XXXX --persistent',
modifying inactive domain definition via virsh.
This patch adds a support for qemu. With this patch,
virsh attach/detach-disk --persistent works well with qemu.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu(a)jp.fujitsu.com>
---
src/qemu/qemu_driver.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 163 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0f25a2a..703f86a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4082,16 +4082,174 @@ cleanup:
return ret;
}
+static int qemuDomainFindDiskByName(virDomainDefPtr vmdef, const char *name)
+{
+ virDomainDiskDefPtr vdisk;
+ int i;
+
+ for (i = 0; i < vmdef->ndisks; i++) {
+ vdisk = vmdef->disks[i];
+ if (!strcmp(vdisk->dst, name))
+ return i;
+ }
+ return -1;
+}
+/*
+ * Attach a device given by XML, the change will be persistent
+ * and domain XML definition file is updated.
+ */
+static int qemuDomainAttachDevicePersistent(virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr newdev)
+{
+ virDomainDiskDefPtr disk;
+
+ /* At first, check device confliction */
+ switch(newdev->type) {
+ case VIR_DOMAIN_DEVICE_DISK:
+ disk = newdev->data.disk;
+ if (qemuDomainFindDiskByName(vmdef, disk->dst) >= 0) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("target %s already exists."), disk->dst);
+ return -1;
+ }
+
+ if (virDomainDiskInsert(vmdef, disk)) {
+ virReportOOMError();
+ return -1;
+ }
+ if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+ /*
+ * Address/Drive information is NULL. If virtio, PCI address
+ * shoule be fixed. Other devices as IDE, SCSI...will get ID
+ * automatically
+ */
+ qemuDomainAssignPCIAddresses(vmdef);
+
+ }
+ newdev->data.disk = NULL;
+ break;
+ default:
+ qemuReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("Sorry, the device is not suppored for now"));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int qemuDomainDetachDevicePersistent(virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr device)
+{
+ int x;
+ virDomainDiskDefPtr disk;
+
+ switch(device->type) {
+ case VIR_DOMAIN_DEVICE_DISK:
+ disk = device->data.disk;
+ x = qemuDomainFindDiskByName(vmdef, disk->dst);
+ if (x < 0) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("target %s doesn't exist."), disk->dst);
+ return -1;
+ }
+ virDomainDiskRemove(vmdef, x);
+ break;
+ default:
+ qemuReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("Sorry, the device is not suppored for now"));
+ return -1;
+ }
+ return 0;
+}
+
+static int qemuDomainModifyDevicePersistent(virDomainPtr dom,
+ const char *xml,
+ unsigned int attach)
+{
+ struct qemud_driver *driver;
+ virDomainDeviceDefPtr device;
+ virDomainDefPtr vmdef;
+ virDomainObjPtr vm;
+ int ret = -1;
+
+ if (!dom || !dom->conn || !dom->name || !xml) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("internal error : %s"), __FUNCTION__);
+ return -1;
+ }
+
+ if (dom->conn->flags & VIR_CONNECT_RO)
+ return -1;
+
+ driver = dom->conn->privateData;
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ if (!vm) {
+ qemuReportError(VIR_ERR_NO_DOMAIN, _("cannot find domain '%s'"),
+ dom->name);
+ goto unlock_out;
+ }
+
+ if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) {
+ /*
+ * For now, just allow updating inactive domains. Further development
+ * will allow updating both active domain and its config file at
+ * the same time.
+ */
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("cannot update alive domain : %s"), __FUNCTION__);
+ goto endjob;
+ }
+ vmdef = virDomainObjGetPersistentDef(driver->caps, vm);
+
+ if (!vmdef)
+ goto endjob;
+
+ device = virDomainDeviceDefParse(driver->caps,
+ vmdef, xml, VIR_DOMAIN_XML_INACTIVE);
+ if (!device)
+ goto endjob;
+
+ if (attach) {
+ ret = qemuDomainAttachDevicePersistent(vmdef, device);
+ if (ret < 0)
+ goto out;
+ } else {
+ ret = qemuDomainDetachDevicePersistent(vmdef, device);
+ if (ret < 0)
+ goto out;
+ }
+ ret = virDomainSaveConfig(driver->configDir, vmdef);
+
+out:
+ virDomainDeviceDefFree(device);
+endjob:
+ if (qemuDomainObjEndJob(vm) == 0)
+ vm = NULL;
+ if (vm)
+ virDomainObjUnlock(vm);
+ /* Note: insert of newdev is done by copy */
+unlock_out:
+ qemuDriverUnlock(driver);
+ return ret;
+}
+
static int qemudDomainAttachDeviceFlags(virDomainPtr dom,
const char *xml,
unsigned int flags) {
if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) {
- qemuReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("cannot modify the persistent configuration of a domain"));
- return -1;
+ /*
+ * Because we can't update the live guest and XML
+ * in atomic, limiting modification as only-acrive and
+ * only-inactive. Need some idea to update both at the same time.
+ */
+ return qemuDomainModifyDevicePersistent(dom, xml, 1);
}
- return qemudDomainAttachDevice(dom, xml);
+ if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE)
+ return qemudDomainAttachDevice(dom, xml);
+
+ return -1;
}
@@ -4304,9 +4462,7 @@ static int qemudDomainDetachDeviceFlags(virDomainPtr dom,
const char *xml,
unsigned int flags) {
if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) {
- qemuReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("cannot modify the persistent configuration of a domain"));
- return -1;
+ return qemuDomainModifyDevicePersistent(dom, xml, 0);
}
return qemudDomainDetachDevice(dom, xml);
--
1.7.1
13 years, 8 months
[libvirt] [PATCH] Allow hash tables to use generic pointers as keys
by Daniel P. Berrange
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
---
src/conf/domain_conf.c | 24 ++++----
src/conf/nwfilter_params.c | 12 ++--
src/internal.h | 1 +
src/lxc/lxc_driver.c | 4 +-
src/nwfilter/nwfilter_gentech_driver.c | 2 +-
src/nwfilter/nwfilter_gentech_driver.h | 2 +-
src/nwfilter/nwfilter_learnipaddr.c | 4 +-
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_driver.c | 8 ++--
src/qemu/qemu_process.c | 4 +-
src/uml/uml_driver.c | 4 +-
src/util/hash.c | 92 +++++++++++++++++++++++---------
src/util/hash.h | 24 ++++++---
src/xen/xm_internal.c | 8 ++--
14 files changed, 122 insertions(+), 69 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b97c1f0..651e2dc 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -392,7 +392,7 @@ VIR_ENUM_IMPL(virDomainTimerMode, VIR_DOMAIN_TIMER_MODE_LAST,
#define VIR_DOMAIN_XML_READ_FLAGS VIR_DOMAIN_XML_INACTIVE
static void
-virDomainObjListDeallocator(void *payload, const char *name ATTRIBUTE_UNUSED)
+virDomainObjListDeallocator(void *payload, const void *name ATTRIBUTE_UNUSED)
{
virDomainObjPtr obj = payload;
virDomainObjLock(obj);
@@ -416,7 +416,7 @@ void virDomainObjListDeinit(virDomainObjListPtr doms)
static int virDomainObjListSearchID(const void *payload,
- const char *name ATTRIBUTE_UNUSED,
+ const void *name ATTRIBUTE_UNUSED,
const void *data)
{
virDomainObjPtr obj = (virDomainObjPtr)payload;
@@ -457,7 +457,7 @@ virDomainObjPtr virDomainFindByUUID(const virDomainObjListPtr doms,
}
static int virDomainObjListSearchName(const void *payload,
- const char *name ATTRIBUTE_UNUSED,
+ const void *name ATTRIBUTE_UNUSED,
const void *data)
{
virDomainObjPtr obj = (virDomainObjPtr)payload;
@@ -8435,7 +8435,7 @@ void virDomainObjUnlock(virDomainObjPtr obj)
}
-static void virDomainObjListCountActive(void *payload, const char *name ATTRIBUTE_UNUSED, void *data)
+static void virDomainObjListCountActive(void *payload, const void *name ATTRIBUTE_UNUSED, void *data)
{
virDomainObjPtr obj = payload;
int *count = data;
@@ -8445,7 +8445,7 @@ static void virDomainObjListCountActive(void *payload, const char *name ATTRIBUT
virDomainObjUnlock(obj);
}
-static void virDomainObjListCountInactive(void *payload, const char *name ATTRIBUTE_UNUSED, void *data)
+static void virDomainObjListCountInactive(void *payload, const void *name ATTRIBUTE_UNUSED, void *data)
{
virDomainObjPtr obj = payload;
int *count = data;
@@ -8471,7 +8471,7 @@ struct virDomainIDData {
int *ids;
};
-static void virDomainObjListCopyActiveIDs(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
+static void virDomainObjListCopyActiveIDs(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr obj = payload;
struct virDomainIDData *data = opaque;
@@ -8497,7 +8497,7 @@ struct virDomainNameData {
char **const names;
};
-static void virDomainObjListCopyInactiveNames(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
+static void virDomainObjListCopyInactiveNames(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr obj = payload;
struct virDomainNameData *data = opaque;
@@ -8754,7 +8754,7 @@ virDomainSnapshotObjPtr virDomainSnapshotAssignDef(virDomainSnapshotObjListPtr s
/* Snapshot Obj List functions */
static void
virDomainSnapshotObjListDeallocator(void *payload,
- const char *name ATTRIBUTE_UNUSED)
+ const void *name ATTRIBUTE_UNUSED)
{
virDomainSnapshotObjPtr obj = payload;
@@ -8783,7 +8783,7 @@ struct virDomainSnapshotNameData {
};
static void virDomainSnapshotObjListCopyNames(void *payload,
- const char *name ATTRIBUTE_UNUSED,
+ const void *name ATTRIBUTE_UNUSED,
void *opaque)
{
virDomainSnapshotObjPtr obj = payload;
@@ -8821,7 +8821,7 @@ cleanup:
}
static void virDomainSnapshotObjListCount(void *payload ATTRIBUTE_UNUSED,
- const char *name ATTRIBUTE_UNUSED,
+ const void *name ATTRIBUTE_UNUSED,
void *data)
{
int *count = data;
@@ -8839,7 +8839,7 @@ int virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots)
}
static int virDomainSnapshotObjListSearchName(const void *payload,
- const char *name ATTRIBUTE_UNUSED,
+ const void *name ATTRIBUTE_UNUSED,
const void *data)
{
virDomainSnapshotObjPtr obj = (virDomainSnapshotObjPtr)payload;
@@ -8870,7 +8870,7 @@ struct snapshot_has_children {
};
static void virDomainSnapshotCountChildren(void *payload,
- const char *name ATTRIBUTE_UNUSED,
+ const void *name ATTRIBUTE_UNUSED,
void *data)
{
virDomainSnapshotObjPtr obj = payload;
diff --git a/src/conf/nwfilter_params.c b/src/conf/nwfilter_params.c
index cd94b30..fbd42cd 100644
--- a/src/conf/nwfilter_params.c
+++ b/src/conf/nwfilter_params.c
@@ -35,7 +35,7 @@
#define VIR_FROM_THIS VIR_FROM_NWFILTER
static void
-hashDealloc(void *payload, const char *name ATTRIBUTE_UNUSED)
+hashDealloc(void *payload, const void *name ATTRIBUTE_UNUSED)
{
VIR_FREE(payload);
}
@@ -157,7 +157,7 @@ struct addToTableStruct {
static void
-addToTable(void *payload, const char *name, void *data)
+addToTable(void *payload, const void *name, void *data)
{
struct addToTableStruct *atts = (struct addToTableStruct *)data;
char *val;
@@ -172,10 +172,10 @@ addToTable(void *payload, const char *name, void *data)
return;
}
- if (virNWFilterHashTablePut(atts->target, name, val, 1) != 0) {
+ if (virNWFilterHashTablePut(atts->target, (const char *)name, val, 1) != 0) {
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
_("Could not put variable '%s' into hashmap"),
- name);
+ (const char *)name);
atts->errOccurred = 1;
VIR_FREE(val);
}
@@ -265,13 +265,13 @@ struct formatterParam {
static void
-_formatParameterAttrs(void *payload, const char *name, void *data)
+_formatParameterAttrs(void *payload, const void *name, void *data)
{
struct formatterParam *fp = (struct formatterParam *)data;
virBufferVSprintf(fp->buf, "%s<parameter name='%s' value='%s'/>\n",
fp->indent,
- name,
+ (const char *)name,
(char *)payload);
}
diff --git a/src/internal.h b/src/internal.h
index e263684..be97801 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -8,6 +8,7 @@
# include <errno.h>
# include <limits.h>
# include <verify.h>
+# include <stdbool.h>
# if STATIC_ANALYSIS
# undef NDEBUG /* Don't let a prior NDEBUG definition cause trouble. */
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index a17b0b6..625777a 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1968,7 +1968,7 @@ struct lxcAutostartData {
};
static void
-lxcAutostartDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
+lxcAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr vm = payload;
const struct lxcAutostartData *data = opaque;
@@ -2015,7 +2015,7 @@ lxcAutostartConfigs(lxc_driver_t *driver) {
}
static void
-lxcReconnectVM(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
+lxcReconnectVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr vm = payload;
lxc_driver_t *driver = opaque;
diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c
index d81aac8..facad13 100644
--- a/src/nwfilter/nwfilter_gentech_driver.c
+++ b/src/nwfilter/nwfilter_gentech_driver.c
@@ -1012,7 +1012,7 @@ virNWFilterTeardownFilter(const virDomainNetDefPtr net)
void
virNWFilterDomainFWUpdateCB(void *payload,
- const char *name ATTRIBUTE_UNUSED,
+ const void *name ATTRIBUTE_UNUSED,
void *data)
{
virDomainObjPtr obj = payload;
diff --git a/src/nwfilter/nwfilter_gentech_driver.h b/src/nwfilter/nwfilter_gentech_driver.h
index 271bf85..fa86030 100644
--- a/src/nwfilter/nwfilter_gentech_driver.h
+++ b/src/nwfilter/nwfilter_gentech_driver.h
@@ -64,7 +64,7 @@ virNWFilterHashTablePtr virNWFilterCreateVarHashmap(char *macaddr,
char *ipaddr);
void virNWFilterDomainFWUpdateCB(void *payload,
- const char *name ATTRIBUTE_UNUSED,
+ const void *name,
void *data);
#endif
diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c
index 8bd7b50..0e0370a 100644
--- a/src/nwfilter/nwfilter_learnipaddr.c
+++ b/src/nwfilter/nwfilter_learnipaddr.c
@@ -189,7 +189,7 @@ virNWFilterLockIface(const char *ifname) {
static void
-freeIfaceLock(void *payload, const char *name ATTRIBUTE_UNUSED) {
+freeIfaceLock(void *payload, const void *name ATTRIBUTE_UNUSED) {
VIR_FREE(payload);
}
@@ -287,7 +287,7 @@ virNWFilterLookupLearnReq(int ifindex) {
static void
-freeLearnReqEntry(void *payload, const char *name ATTRIBUTE_UNUSED) {
+freeLearnReqEntry(void *payload, const void *name ATTRIBUTE_UNUSED) {
virNWFilterIPAddrLearnReqFree(payload);
}
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a41859c..e68a698 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -747,7 +747,7 @@ cleanup:
static void
qemuDomainPCIAddressSetFreeEntry(void *payload,
- const char *name ATTRIBUTE_UNUSED)
+ const void *name ATTRIBUTE_UNUSED)
{
VIR_FREE(payload);
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0f25a2a..fa96094 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -133,7 +133,7 @@ struct qemuAutostartData {
};
static void
-qemuAutostartDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
+qemuAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr vm = payload;
struct qemuAutostartData *data = opaque;
@@ -273,7 +273,7 @@ err_exit:
}
static void qemuDomainSnapshotLoad(void *payload,
- const char *name ATTRIBUTE_UNUSED,
+ const void *name ATTRIBUTE_UNUSED,
void *data)
{
virDomainObjPtr vm = (virDomainObjPtr)payload;
@@ -6502,7 +6502,7 @@ struct snap_remove {
};
static void qemuDomainSnapshotDiscardChildren(void *payload,
- const char *name ATTRIBUTE_UNUSED,
+ const void *name ATTRIBUTE_UNUSED,
void *data)
{
virDomainSnapshotObjPtr snap = payload;
@@ -6533,7 +6533,7 @@ struct snap_reparent {
static void
qemuDomainSnapshotReparentChildren(void *payload,
- const char *name ATTRIBUTE_UNUSED,
+ const void *name ATTRIBUTE_UNUSED,
void *data)
{
virDomainSnapshotObjPtr snap = payload;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9c5ea63..e418c37 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -949,7 +949,7 @@ qemuProcessFindCharDevicePTYs(virDomainObjPtr vm,
return 0;
}
-static void qemuProcessFreePtyPath(void *payload, const char *name ATTRIBUTE_UNUSED)
+static void qemuProcessFreePtyPath(void *payload, const void *name ATTRIBUTE_UNUSED)
{
VIR_FREE(payload);
}
@@ -1783,7 +1783,7 @@ struct qemuProcessReconnectData {
* and re-reserve the security labels in use
*/
static void
-qemuProcessReconnect(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
+qemuProcessReconnect(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr obj = payload;
struct qemuProcessReconnectData *data = opaque;
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 2af8002..7cacadb 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -149,7 +149,7 @@ struct umlAutostartData {
};
static void
-umlAutostartDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
+umlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr vm = payload;
const struct umlAutostartData *data = opaque;
@@ -508,7 +508,7 @@ umlActive(void) {
}
static void
-umlShutdownOneVM(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
+umlShutdownOneVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
{
virDomainObjPtr dom = payload;
struct uml_driver *driver = opaque;
diff --git a/src/util/hash.c b/src/util/hash.c
index d7950b9..aa658d4 100644
--- a/src/util/hash.c
+++ b/src/util/hash.c
@@ -43,7 +43,7 @@ typedef struct _virHashEntry virHashEntry;
typedef virHashEntry *virHashEntryPtr;
struct _virHashEntry {
struct _virHashEntry *next;
- char *name;
+ void *name;
void *payload;
int valid;
};
@@ -56,25 +56,48 @@ struct _virHashTable {
int size;
int nbElems;
virHashDeallocator f;
+ virHashCode code;
+ virHashEqual equal;
+ virHashCopy copy;
+ virHashRelease release;
};
-/*
- * virHashComputeKey:
- * Calculate the hash key
- */
-static unsigned long
-virHashComputeKey(virHashTablePtr table, const char *name)
+static unsigned long virHashStrCode(const void *name)
{
+ const char *str = name;
unsigned long value = 0L;
char ch;
- if (name != NULL) {
- value += 30 * (*name);
- while ((ch = *name++) != 0) {
+ if (str != NULL) {
+ value += 30 * (*str);
+ while ((ch = *str++) != 0) {
value =
value ^ ((value << 5) + (value >> 3) + (unsigned long) ch);
}
}
+ return value;
+}
+
+static bool virHashStrEqual(const void *namea, const void *nameb)
+{
+ return strcmp(namea, nameb) == 0 ? true : false;
+}
+
+static void *virHashStrCopy(const void *name)
+{
+ return strdup(name);
+}
+
+static void virHashStrRelease(void *name)
+{
+ VIR_FREE(name);
+}
+
+
+static unsigned long
+virHashComputeKey(virHashTablePtr table, const void *name)
+{
+ unsigned long value = table->code(name);
return (value % table->size);
}
@@ -87,8 +110,9 @@ virHashComputeKey(virHashTablePtr table, const char *name)
*
* Returns the newly created object, or NULL if an error occured.
*/
-virHashTablePtr
-virHashCreate(int size, virHashDeallocator deallocator)
+virHashTablePtr virHashCreateFull(int size, virHashDeallocator deallocator,
+ virHashCode code, virHashEqual equal,
+ virHashCopy copy, virHashRelease release)
{
virHashTablePtr table = NULL;
@@ -103,6 +127,10 @@ virHashCreate(int size, virHashDeallocator deallocator)
table->size = size;
table->nbElems = 0;
table->f = deallocator;
+ table->code = code;
+ table->equal = equal;
+ table->copy = copy;
+ table->release = release;
if (VIR_ALLOC_N(table->table, size) < 0) {
virReportOOMError();
VIR_FREE(table);
@@ -112,6 +140,17 @@ virHashCreate(int size, virHashDeallocator deallocator)
return table;
}
+virHashTablePtr
+virHashCreate(int size, virHashDeallocator deallocator)
+{
+ return virHashCreateFull(size,
+ deallocator,
+ virHashStrCode,
+ virHashStrEqual,
+ virHashStrCopy,
+ virHashStrRelease);
+}
+
/**
* virHashGrow:
* @table: the hash table
@@ -232,7 +271,8 @@ virHashFree(virHashTablePtr table)
next = iter->next;
if ((table->f != NULL) && (iter->payload != NULL))
table->f(iter->payload, iter->name);
- VIR_FREE(iter->name);
+ if (table->release)
+ table->release(iter->name);
iter->payload = NULL;
if (!inside_table)
VIR_FREE(iter);
@@ -247,7 +287,7 @@ virHashFree(virHashTablePtr table)
}
static int
-virHashAddOrUpdateEntry(virHashTablePtr table, const char *name,
+virHashAddOrUpdateEntry(virHashTablePtr table, const void *name,
void *userdata, virHashDeallocator f,
bool is_update)
{
@@ -270,13 +310,13 @@ virHashAddOrUpdateEntry(virHashTablePtr table, const char *name,
} else {
for (insert = &(table->table[key]); insert->next != NULL;
insert = insert->next) {
- if (STREQ(insert->name, name)) {
+ if (table->equal(insert->name, name)) {
found = true;
break;
}
len++;
}
- if (STREQ(insert->name, name))
+ if (table->equal(insert->name, name))
found = true;
}
@@ -300,7 +340,7 @@ virHashAddOrUpdateEntry(virHashTablePtr table, const char *name,
}
}
- new_name = strdup(name);
+ new_name = table->copy(name);
if (new_name == NULL) {
virReportOOMError();
if (insert != NULL)
@@ -335,7 +375,7 @@ virHashAddOrUpdateEntry(virHashTablePtr table, const char *name,
* Returns 0 the addition succeeded and -1 in case of error.
*/
int
-virHashAddEntry(virHashTablePtr table, const char *name, void *userdata)
+virHashAddEntry(virHashTablePtr table, const void *name, void *userdata)
{
return virHashAddOrUpdateEntry(table, name, userdata, NULL, false);
}
@@ -354,7 +394,7 @@ virHashAddEntry(virHashTablePtr table, const char *name, void *userdata)
* Returns 0 the addition succeeded and -1 in case of error.
*/
int
-virHashUpdateEntry(virHashTablePtr table, const char *name,
+virHashUpdateEntry(virHashTablePtr table, const void *name,
void *userdata, virHashDeallocator f)
{
return virHashAddOrUpdateEntry(table, name, userdata, f, true);
@@ -370,7 +410,7 @@ virHashUpdateEntry(virHashTablePtr table, const char *name,
* Returns the a pointer to the userdata
*/
void *
-virHashLookup(virHashTablePtr table, const char *name)
+virHashLookup(virHashTablePtr table, const void *name)
{
unsigned long key;
virHashEntryPtr entry;
@@ -383,7 +423,7 @@ virHashLookup(virHashTablePtr table, const char *name)
if (table->table[key].valid == 0)
return (NULL);
for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
- if (STREQ(entry->name, name))
+ if (table->equal(entry->name, name))
return (entry->payload);
}
return (NULL);
@@ -419,7 +459,7 @@ virHashSize(virHashTablePtr table)
* Returns 0 if the removal succeeded and -1 in case of error or not found.
*/
int
-virHashRemoveEntry(virHashTablePtr table, const char *name,
+virHashRemoveEntry(virHashTablePtr table, const void *name,
virHashDeallocator f)
{
unsigned long key;
@@ -435,11 +475,12 @@ virHashRemoveEntry(virHashTablePtr table, const char *name,
} else {
for (entry = &(table->table[key]); entry != NULL;
entry = entry->next) {
- if (STREQ(entry->name, name)) {
+ if (table->equal(entry->name, name)) {
if ((f != NULL) && (entry->payload != NULL))
f(entry->payload, entry->name);
entry->payload = NULL;
- VIR_FREE(entry->name);
+ if (table->release)
+ table->release(entry->name);
if (prev) {
prev->next = entry->next;
VIR_FREE(entry);
@@ -523,7 +564,8 @@ int virHashRemoveSet(virHashTablePtr table, virHashSearcher iter, virHashDealloc
if (iter(entry->payload, entry->name, data)) {
count++;
f(entry->payload, entry->name);
- VIR_FREE(entry->name);
+ if (table->release)
+ table->release(entry->name);
table->nbElems--;
if (prev) {
prev->next = entry->next;
diff --git a/src/util/hash.h b/src/util/hash.h
index cf08e1a..6316fd9 100644
--- a/src/util/hash.h
+++ b/src/util/hash.h
@@ -29,7 +29,7 @@ typedef virHashTable *virHashTablePtr;
*
* Callback to free data from a hash.
*/
-typedef void (*virHashDeallocator) (void *payload, const char *name);
+typedef void (*virHashDeallocator) (void *payload, const void *name);
/**
* virHashIterator:
* @payload: the data in the hash
@@ -38,7 +38,7 @@ typedef void (*virHashDeallocator) (void *payload, const char *name);
*
* Callback to process a hash entry during iteration
*/
-typedef void (*virHashIterator) (void *payload, const char *name, void *data);
+typedef void (*virHashIterator) (void *payload, const void *name, void *data);
/**
* virHashSearcher
* @payload: the data in the hash
@@ -49,13 +49,23 @@ typedef void (*virHashIterator) (void *payload, const char *name, void *data);
* Returns 1 if the hash entry is desired, 0 to move
* to next entry
*/
-typedef int (*virHashSearcher) (const void *payload, const char *name,
+typedef int (*virHashSearcher) (const void *payload, const void *name,
const void *data);
+typedef unsigned long (*virHashCode)(const void *name);
+typedef bool (*virHashEqual)(const void *namea, const void *nameb);
+typedef void *(*virHashCopy)(const void *name);
+typedef void (*virHashRelease)(void *name);
+
/*
* Constructor and destructor.
*/
virHashTablePtr virHashCreate(int size, virHashDeallocator f);
+virHashTablePtr virHashCreateFull(int size, virHashDeallocator f,
+ virHashCode code,
+ virHashEqual equal,
+ virHashCopy copy,
+ virHashRelease release);
void virHashFree(virHashTablePtr table);
int virHashSize(virHashTablePtr table);
@@ -63,21 +73,21 @@ int virHashSize(virHashTablePtr table);
* Add a new entry to the hash table.
*/
int virHashAddEntry(virHashTablePtr table,
- const char *name, void *userdata);
+ const void *name, void *userdata);
int virHashUpdateEntry(virHashTablePtr table,
- const char *name,
+ const void *name,
void *userdata, virHashDeallocator f);
/*
* Remove an entry from the hash table.
*/
int virHashRemoveEntry(virHashTablePtr table,
- const char *name, virHashDeallocator f);
+ const void *name, virHashDeallocator f);
/*
* Retrieve the userdata.
*/
-void *virHashLookup(virHashTablePtr table, const char *name);
+void *virHashLookup(virHashTablePtr table, const void *name);
/*
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index 27cc387..fe7e533 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -139,7 +139,7 @@ static int xenInotifyActive(virConnectPtr conn)
/* Release memory associated with a cached config object */
-static void xenXMConfigFree(void *payload, const char *key ATTRIBUTE_UNUSED) {
+static void xenXMConfigFree(void *payload, const void *key ATTRIBUTE_UNUSED) {
xenXMConfCachePtr entry = (xenXMConfCachePtr)payload;
virDomainDefFree(entry->def);
VIR_FREE(entry);
@@ -151,7 +151,7 @@ struct xenXMConfigReaperData {
};
/* Remove any configs which were not refreshed recently */
-static int xenXMConfigReaper(const void *payload, const char *key ATTRIBUTE_UNUSED, const void *data) {
+static int xenXMConfigReaper(const void *payload, const void *key ATTRIBUTE_UNUSED, const void *data) {
const struct xenXMConfigReaperData *args = data;
xenXMConfCachePtr entry = (xenXMConfCachePtr)payload;
@@ -938,7 +938,7 @@ cleanup:
/*
* Hash table iterator to search for a domain based on UUID
*/
-static int xenXMDomainSearchForUUID(const void *payload, const char *name ATTRIBUTE_UNUSED, const void *data) {
+static int xenXMDomainSearchForUUID(const void *payload, const void *name ATTRIBUTE_UNUSED, const void *data) {
const unsigned char *wantuuid = (const unsigned char *)data;
const xenXMConfCachePtr entry = (const xenXMConfCachePtr)payload;
@@ -1235,7 +1235,7 @@ struct xenXMListIteratorContext {
char ** names;
};
-static void xenXMListIterator(void *payload ATTRIBUTE_UNUSED, const char *name, void *data) {
+static void xenXMListIterator(void *payload ATTRIBUTE_UNUSED, const void *name, void *data) {
struct xenXMListIteratorContext *ctx = data;
virDomainPtr dom = NULL;
--
1.7.4
13 years, 8 months
[libvirt] [PATCH] Allow 32-on-64 execution for LXC guests
by Daniel P. Berrange
Using the 'personality(2)' system call, we can make a container
on an x86_64 host appear to be i686. Likewise for most other
Linux 64bit arches.
* src/lxc/lxc_conf.c: Fill in 32bit capabilities for x86_64 hosts
* src/lxc/lxc_container.h, src/lxc/lxc_container.c: Add API to
check if an arch has a 32bit alternative
* src/lxc/lxc_controller.c: Set the process personality when
starting guest
---
src/lxc/lxc_conf.c | 25 ++++++++++++++++++++++++-
src/lxc/lxc_container.c | 21 +++++++++++++++++++++
src/lxc/lxc_container.h | 2 ++
src/lxc/lxc_controller.c | 26 ++++++++++++++++++++++++--
4 files changed, 71 insertions(+), 3 deletions(-)
diff --git a/src/lxc/lxc_conf.c b/src/lxc/lxc_conf.c
index 59d1161..226a57e 100644
--- a/src/lxc/lxc_conf.c
+++ b/src/lxc/lxc_conf.c
@@ -36,6 +36,7 @@
#include "logging.h"
#include "uuid.h"
#include "configmake.h"
+#include "lxc_container.h"
#define VIR_FROM_THIS VIR_FROM_LXC
@@ -45,6 +46,7 @@ virCapsPtr lxcCapsInit(void)
struct utsname utsname;
virCapsPtr caps;
virCapsGuestPtr guest;
+ const char *altArch;
uname(&utsname);
@@ -73,7 +75,7 @@ virCapsPtr lxcCapsInit(void)
if ((guest = virCapabilitiesAddGuest(caps,
"exe",
utsname.machine,
- sizeof(int) == 4 ? 32 : 8,
+ sizeof(void*) == 4 ? 32 : 64,
LIBEXECDIR "/libvirt_lxc",
NULL,
0,
@@ -88,6 +90,27 @@ virCapsPtr lxcCapsInit(void)
NULL) == NULL)
goto error;
+ /* On 64-bit hosts, we can use personality() to request a 32bit process */
+ if ((altArch = lxcContainerGetAlt32bitArch(utsname.machine)) != NULL) {
+ if ((guest = virCapabilitiesAddGuest(caps,
+ "exe",
+ altArch,
+ 32,
+ LIBEXECDIR "/libvirt_lxc",
+ NULL,
+ 0,
+ NULL)) == NULL)
+ goto error;
+
+ if (virCapabilitiesAddGuestDomain(guest,
+ "lxc",
+ NULL,
+ NULL,
+ 0,
+ NULL) == NULL)
+ goto error;
+ }
+
/* LXC Requires an emulator in the XML */
virCapabilitiesSetEmulatorRequired(caps);
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 269dc97..9830b71 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -837,6 +837,27 @@ static int userns_supported(void)
#endif
}
+const char *lxcContainerGetAlt32bitArch(const char *arch)
+{
+ /* Any Linux 64bit arch which has a 32bit
+ * personality available should be listed here */
+ if (STREQ(arch, "x86_64"))
+ return "i686";
+ if (STREQ(arch, "s390x"))
+ return "s390";
+ if (STREQ(arch, "ppc64"))
+ return "ppc";
+ if (STREQ(arch, "parisc64"))
+ return "parisc";
+ if (STREQ(arch, "sparc64"))
+ return "sparc";
+ if (STREQ(arch, "mips64"))
+ return "mips";
+
+ return NULL;
+}
+
+
/**
* lxcContainerStart:
* @def: pointer to virtual machine structure
diff --git a/src/lxc/lxc_container.h b/src/lxc/lxc_container.h
index 75c8836..5e08d45 100644
--- a/src/lxc/lxc_container.h
+++ b/src/lxc/lxc_container.h
@@ -55,4 +55,6 @@ int lxcContainerStart(virDomainDefPtr def,
int lxcContainerAvailable(int features);
+const char *lxcContainerGetAlt32bitArch(const char *arch);
+
#endif /* LXC_CONTAINER_H */
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 28cbe57..61e21c3 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2010 Red Hat, Inc.
- * Copyright IBM Corp. 2008
+ * Copyright (C) 2010 Red Hat, Inc. Copyright IBM Corp. 2008
*
* lxc_controller.c: linux container process controller
*
@@ -29,6 +28,8 @@
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
+#include <sys/utsname.h>
+#include <sys/personality.h>
#include <unistd.h>
#include <paths.h>
#include <errno.h>
@@ -565,6 +566,25 @@ static int lxcControllerCleanupInterfaces(unsigned int nveths,
return 0;
}
+static int lxcSetPersonality(virDomainDefPtr def)
+{
+ struct utsname utsname;
+ const char *altArch;
+
+ uname(&utsname);
+
+ altArch = lxcContainerGetAlt32bitArch(utsname.machine);
+ if (altArch &&
+ STREQ(def->os.arch, altArch)) {
+ if (personality(PER_LINUX32) < 0) {
+ virReportSystemError(errno, _("Unable to request personality for %s on %s"),
+ altArch, utsname.machine);
+ return -1;
+ }
+ }
+ return 0;
+}
+
#ifndef MS_REC
# define MS_REC 16384
#endif
@@ -684,6 +704,8 @@ lxcControllerRun(virDomainDefPtr def,
}
}
+ if (lxcSetPersonality(def) < 0)
+ goto cleanup;
if ((container = lxcContainerStart(def,
nveths,
--
1.7.4
13 years, 8 months
[libvirt] [PATCH] Put <stdbool.h> into internal.h so it is available everywhere
by Daniel P. Berrange
Remove the <stdbool.h> header from all source files / headers
and just put it into internal.h
* src/internal.h: Add <stdbool.h>
---
daemon/dispatch.c | 1 -
src/conf/capabilities.h | 2 --
src/conf/nwfilter_conf.h | 1 -
src/conf/storage_encryption_conf.h | 1 -
src/driver.h | 1 -
src/esx/esx_util.h | 2 --
src/fdstream.h | 1 -
src/internal.h | 1 +
src/lxc/lxc_driver.c | 1 -
src/lxc/veth.c | 1 -
src/nodeinfo.c | 1 -
src/opennebula/one_driver.c | 1 -
src/qemu/qemu_conf.h | 1 -
src/qemu/qemu_driver.c | 1 -
src/qemu/qemu_hotplug.h | 2 --
src/secret/secret_driver.c | 1 -
src/security/security_apparmor.c | 1 -
src/security/virt-aa-helper.c | 1 -
src/storage/storage_backend.h | 1 -
src/storage/storage_backend_fs.c | 1 -
src/util/bitmap.h | 1 -
src/util/cgroup.c | 1 -
src/util/command.c | 1 -
src/util/files.h | 1 -
src/util/hash.c | 1 -
src/util/network.h | 1 -
src/util/storage_file.h | 1 -
src/util/threadpool.c | 2 --
src/util/threads.h | 2 --
src/util/util.h | 1 -
src/util/virtaudit.h | 1 -
src/vbox/vbox_XPCOMCGlue.c | 1 -
src/vbox/vbox_tmpl.c | 1 -
src/vmx/vmx.h | 2 --
src/xen/xend_internal.c | 1 -
src/xen/xend_internal.h | 1 -
tests/nwfilterxml2xmltest.c | 1 -
tests/qemuargv2xmltest.c | 1 -
tests/qemuxml2argvtest.c | 1 -
tools/console.c | 1 -
40 files changed, 1 insertions(+), 45 deletions(-)
diff --git a/daemon/dispatch.c b/daemon/dispatch.c
index 3397a00..dc3b48a 100644
--- a/daemon/dispatch.c
+++ b/daemon/dispatch.c
@@ -26,7 +26,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
-#include <stdbool.h>
#include "dispatch.h"
#include "remote.h"
diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
index 759265d..96bf0a2 100644
--- a/src/conf/capabilities.h
+++ b/src/conf/capabilities.h
@@ -24,8 +24,6 @@
#ifndef __VIR_CAPABILITIES_H
# define __VIR_CAPABILITIES_H
-# include <stdbool.h>
-
# include "internal.h"
# include "util.h"
# include "buf.h"
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index 5db4658..40da8c3 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -28,7 +28,6 @@
# include <stdint.h>
# include <stddef.h>
-# include <stdbool.h>
# include "internal.h"
diff --git a/src/conf/storage_encryption_conf.h b/src/conf/storage_encryption_conf.h
index c722cc6..fa5f3cb 100644
--- a/src/conf/storage_encryption_conf.h
+++ b/src/conf/storage_encryption_conf.h
@@ -27,7 +27,6 @@
# include "buf.h"
# include "util.h"
-# include <stdbool.h>
# include <libxml/tree.h>
enum virStorageEncryptionSecretType {
diff --git a/src/driver.h b/src/driver.h
index 7451004..c65a4b9 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -7,7 +7,6 @@
# define __VIR_DRIVER_H__
# include "config.h"
-# include <stdbool.h>
# include <libxml/uri.h>
diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h
index 4cbf9b7..d00e28a 100644
--- a/src/esx/esx_util.h
+++ b/src/esx/esx_util.h
@@ -1,4 +1,3 @@
-
/*
* esx_util.h: utility functions for the VMware ESX driver
*
@@ -23,7 +22,6 @@
#ifndef __ESX_UTIL_H__
# define __ESX_UTIL_H__
-# include <stdbool.h>
# include <libxml/uri.h>
# include "internal.h"
diff --git a/src/fdstream.h b/src/fdstream.h
index f8d22d5..53cbaa7 100644
--- a/src/fdstream.h
+++ b/src/fdstream.h
@@ -24,7 +24,6 @@
# define __VIR_FDSTREAM_H_
# include "internal.h"
-# include <stdbool.h>
int virFDStreamOpen(virStreamPtr st,
int fd);
diff --git a/src/internal.h b/src/internal.h
index e263684..be97801 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -8,6 +8,7 @@
# include <errno.h>
# include <limits.h>
# include <verify.h>
+# include <stdbool.h>
# if STATIC_ANALYSIS
# undef NDEBUG /* Don't let a prior NDEBUG definition cause trouble. */
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index a17b0b6..70e74d5 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -27,7 +27,6 @@
#include <fcntl.h>
#include <sched.h>
#include <sys/utsname.h>
-#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/src/lxc/veth.c b/src/lxc/veth.c
index 78e011e..65ff5d8 100644
--- a/src/lxc/veth.c
+++ b/src/lxc/veth.c
@@ -13,7 +13,6 @@
#include <config.h>
#include <string.h>
-#include <stdbool.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index f4ea36e..5d40aca 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -23,7 +23,6 @@
#include <config.h>
-#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
diff --git a/src/opennebula/one_driver.c b/src/opennebula/one_driver.c
index 75d7b9a..a0654e2 100644
--- a/src/opennebula/one_driver.c
+++ b/src/opennebula/one_driver.c
@@ -25,7 +25,6 @@
#include <fcntl.h>
#include <sched.h>
#include <sys/utsname.h>
-#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index af1be2e..7c6fde7 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -25,7 +25,6 @@
# define __QEMUD_CONF_H
# include <config.h>
-# include <stdbool.h>
# include "ebtables.h"
# include "internal.h"
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8b15a3e..0baff56 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -29,7 +29,6 @@
#include <dirent.h>
#include <limits.h>
#include <string.h>
-#include <stdbool.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index 217785d..1c96444 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -24,8 +24,6 @@
#ifndef __QEMU_HOTPLUG_H__
# define __QEMU_HOTPLUG_H__
-# include <stdbool.h>
-
# include "qemu_conf.h"
# include "domain_conf.h"
diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
index c5a876b..5ca5006 100644
--- a/src/secret/secret_driver.c
+++ b/src/secret/secret_driver.c
@@ -24,7 +24,6 @@
#include <dirent.h>
#include <fcntl.h>
-#include <stdbool.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 7dc01ac..deb4181 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -23,7 +23,6 @@
#include <errno.h>
#include <unistd.h>
#include <wait.h>
-#include <stdbool.h>
#include "internal.h"
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index b91cf98..77df514 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -24,7 +24,6 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <getopt.h>
-#include <stdbool.h>
#include <sys/utsname.h>
#include <locale.h>
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
index 6f395c7..65cbd7e 100644
--- a/src/storage/storage_backend.h
+++ b/src/storage/storage_backend.h
@@ -25,7 +25,6 @@
# define __VIR_STORAGE_BACKEND_H__
# include <stdint.h>
-# include <stdbool.h>
# include "internal.h"
# include "storage_conf.h"
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index ff39d48..c33fb05 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -26,7 +26,6 @@
#include <sys/statvfs.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <stdbool.h>
#include <stdio.h>
#include <dirent.h>
#include <errno.h>
diff --git a/src/util/bitmap.h b/src/util/bitmap.h
index 08515d1..0541112 100644
--- a/src/util/bitmap.h
+++ b/src/util/bitmap.h
@@ -25,7 +25,6 @@
# include "internal.h"
-# include <stdbool.h>
# include <sys/types.h>
diff --git a/src/util/cgroup.c b/src/util/cgroup.c
index b71eef9..a1299aa 100644
--- a/src/util/cgroup.c
+++ b/src/util/cgroup.c
@@ -20,7 +20,6 @@
#include <string.h>
#include <errno.h>
#include <stdlib.h>
-#include <stdbool.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <libgen.h>
diff --git a/src/util/command.c b/src/util/command.c
index 0d5cb79..ff2bd46 100644
--- a/src/util/command.c
+++ b/src/util/command.c
@@ -23,7 +23,6 @@
#include <poll.h>
#include <stdarg.h>
-#include <stdbool.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/wait.h>
diff --git a/src/util/files.h b/src/util/files.h
index 744ba93..5137fb3 100644
--- a/src/util/files.h
+++ b/src/util/files.h
@@ -26,7 +26,6 @@
#ifndef __VIR_FILES_H_
# define __VIR_FILES_H_
-# include <stdbool.h>
# include <stdio.h>
# include "internal.h"
diff --git a/src/util/hash.c b/src/util/hash.c
index d7950b9..3ab73dd 100644
--- a/src/util/hash.c
+++ b/src/util/hash.c
@@ -22,7 +22,6 @@
#include <config.h>
#include <string.h>
-#include <stdbool.h>
#include <stdlib.h>
#include "virterror_internal.h"
diff --git a/src/util/network.h b/src/util/network.h
index 0b43bf6..ed0b78c 100644
--- a/src/util/network.h
+++ b/src/util/network.h
@@ -19,7 +19,6 @@
# include <sys/un.h>
# endif
# include <netdb.h>
-# include <stdbool.h>
# include <netinet/in.h>
typedef struct {
diff --git a/src/util/storage_file.h b/src/util/storage_file.h
index 04c1bb2..f1bdd02 100644
--- a/src/util/storage_file.h
+++ b/src/util/storage_file.h
@@ -25,7 +25,6 @@
# define __VIR_STORAGE_FILE_H__
# include "util.h"
-# include <stdbool.h>
enum virStorageFileFormat {
VIR_STORAGE_FILE_AUTO_SAFE = -2,
diff --git a/src/util/threadpool.c b/src/util/threadpool.c
index 1213862..8217591 100644
--- a/src/util/threadpool.c
+++ b/src/util/threadpool.c
@@ -25,8 +25,6 @@
#include <config.h>
-#include <stdbool.h>
-
#include "threadpool.h"
#include "memory.h"
#include "threads.h"
diff --git a/src/util/threads.h b/src/util/threads.h
index 35e319e..c129301 100644
--- a/src/util/threads.h
+++ b/src/util/threads.h
@@ -22,8 +22,6 @@
#ifndef __THREADS_H_
# define __THREADS_H_
-# include <stdbool.h>
-
# include "internal.h"
typedef struct virMutex virMutex;
diff --git a/src/util/util.h b/src/util/util.h
index c822174..5f6473c 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -31,7 +31,6 @@
# include <sys/select.h>
# include <sys/types.h>
# include <stdarg.h>
-# include <stdbool.h>
# ifndef MIN
# define MIN(a, b) ((a) < (b) ? (a) : (b))
diff --git a/src/util/virtaudit.h b/src/util/virtaudit.h
index 6c4deeb..a558a17 100644
--- a/src/util/virtaudit.h
+++ b/src/util/virtaudit.h
@@ -24,7 +24,6 @@
# define __LIBVIRT_AUDIT_H__
# include "internal.h"
-# include <stdbool.h>
enum virAuditRecordType {
VIR_AUDIT_RECORD_MACHINE_CONTROL,
diff --git a/src/vbox/vbox_XPCOMCGlue.c b/src/vbox/vbox_XPCOMCGlue.c
index fbe210c..0caeef9 100644
--- a/src/vbox/vbox_XPCOMCGlue.c
+++ b/src/vbox/vbox_XPCOMCGlue.c
@@ -34,7 +34,6 @@
#include <stdlib.h>
#include <dlfcn.h>
-#include <stdbool.h>
#include "vbox_XPCOMCGlue.h"
#include "internal.h"
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 1c4e46f..8848cc0 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -35,7 +35,6 @@
#include <config.h>
#include <sys/utsname.h>
-#include <stdbool.h>
#include <unistd.h>
#include "internal.h"
diff --git a/src/vmx/vmx.h b/src/vmx/vmx.h
index c317108..4d54660 100644
--- a/src/vmx/vmx.h
+++ b/src/vmx/vmx.h
@@ -23,8 +23,6 @@
#ifndef __VIR_VMX_H__
# define __VIR_VMX_H__
-# include <stdbool.h>
-
# include "internal.h"
# include "conf.h"
# include "domain_conf.h"
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index e811b86..bfaed65 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -21,7 +21,6 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
-#include <stdbool.h>
#include <math.h>
#include <stdarg.h>
#include <netinet/in.h>
diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h
index c90c572..805cf91 100644
--- a/src/xen/xend_internal.h
+++ b/src/xen/xend_internal.h
@@ -18,7 +18,6 @@
# include <sys/types.h>
# include <stdint.h>
-# include <stdbool.h>
# include <libxml/uri.h>
# include "internal.h"
diff --git a/tests/nwfilterxml2xmltest.c b/tests/nwfilterxml2xmltest.c
index 9cad913..575177a 100644
--- a/tests/nwfilterxml2xmltest.c
+++ b/tests/nwfilterxml2xmltest.c
@@ -4,7 +4,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#include <stdbool.h>
#include <sys/types.h>
#include <fcntl.h>
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
index 7499ba0..cfcd824 100644
--- a/tests/qemuargv2xmltest.c
+++ b/tests/qemuargv2xmltest.c
@@ -4,7 +4,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#include <stdbool.h>
#include <sys/types.h>
#include <fcntl.h>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 4817d51..a026473 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -4,7 +4,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#include <stdbool.h>
#include <sys/types.h>
#include <fcntl.h>
diff --git a/tools/console.c b/tools/console.c
index e126320..224cf03 100644
--- a/tools/console.c
+++ b/tools/console.c
@@ -34,7 +34,6 @@
# include <errno.h>
# include <unistd.h>
# include <signal.h>
-# include <stdbool.h>
# include "internal.h"
# include "console.h"
--
1.7.4
13 years, 8 months
[libvirt] [PATCH] virsh: Make <mac> required when device-detaching interface
by Michal Privoznik
Problem is, if user does not specify mac address in input XML,
we generate a random one, which is why device-detach fails giving
a confusing error message. Therefore <mac> needs to be required.
---
tools/virsh.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 2837e0f..dfb48d2 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -8580,9 +8580,12 @@ cmdDetachDevice(vshControl *ctl, const vshCmd *cmd)
virDomainPtr dom;
char *from;
char *buffer;
- int ret = TRUE;
+ int ret = FALSE;
int found;
unsigned int flags;
+ xmlDocPtr xml = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ int mac_cnt;
if (!vshConnectionUsability(ctl, ctl->conn))
return FALSE;
@@ -8592,14 +8595,41 @@ cmdDetachDevice(vshControl *ctl, const vshCmd *cmd)
from = vshCommandOptString(cmd, "file", &found);
if (!found) {
- virDomainFree(dom);
- return FALSE;
+ goto cleanup;
}
if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) {
virshReportError(ctl);
- virDomainFree(dom);
- return FALSE;
+ goto cleanup;
+ }
+
+ xml = xmlReadDoc((const xmlChar *) buffer, "interface.xml", NULL,
+ XML_PARSE_NOENT | XML_PARSE_NONET |
+ XML_PARSE_NOWARNING);
+
+ if (!xml) {
+ vshError(ctl, "%s", _("input XML is not valid"));
+ goto cleanup;
+ }
+
+ ctxt = xmlXPathNewContext(xml);
+ mac_cnt = virXPathNodeSet("/interface/mac", ctxt, NULL);
+
+ switch(mac_cnt) {
+ case 1:
+ break;
+
+ case 0:
+ case -1:
+ vshError(ctl, "%s", _("You must specify mac address in xml file"));
+ goto cleanup;
+ break;
+
+ default:
+ vshError(ctl, "%s", _("You must specify exactly one mac address in"
+ " xml file"));
+ goto cleanup;
+ break;
}
if (vshCommandOptBool(cmd, "persistent")) {
@@ -8610,18 +8640,23 @@ cmdDetachDevice(vshControl *ctl, const vshCmd *cmd)
} else {
ret = virDomainDetachDevice(dom, buffer);
}
- VIR_FREE(buffer);
if (ret < 0) {
+ ret = FALSE;
vshError(ctl, _("Failed to detach device from %s"), from);
- virDomainFree(dom);
- return FALSE;
- } else {
- vshPrint(ctl, "%s", _("Device detached successfully\n"));
+ goto cleanup;
}
+ vshPrint(ctl, "%s", _("Device detached successfully\n"));
+ ret = TRUE;
+
+cleanup:
+ xmlXPathFreeContext(ctxt);
+ if (xml)
+ xmlFreeDoc(xml);
+ VIR_FREE(buffer);
virDomainFree(dom);
- return TRUE;
+ return ret;
}
--
1.7.4
13 years, 8 months