[libvirt] [PATCH 00/13] Network disk improvements (NBD & libiscsi)
by Paolo Bonzini
This series improves support for NBD disks (patches 1-6), and adds
support for the libiscsi userspace initiator (patches 7-13).
Please review!
Paolo
Paolo Bonzini (13):
qemu: fix use-after-free when parsing NBD disk
qemu: do not support non-network disks without -drive
qemu: rewrite NBD command-line builder and parser
qemu: support named nbd exports
qemu: support NBD with Unix sockets
qemu: support URI syntax for NBD
domain: add support for iscsi network disks
qemu: add support for libiscsi
qemu: support LUN numbers for iSCSI disks
domain: make port optional for network disks
secret: add iscsi to possible usage types
domain: parse XML for iscsi authorization credentials
qemu: pass iscsi authorization credentials
docs/formatdomain.html.in | 42 +-
docs/formatsecret.html.in | 12 +
docs/schemas/domaincommon.rng | 37 +-
docs/schemas/secret.rng | 10 +
include/libvirt/libvirt.h.in | 1 +
src/conf/domain_conf.c | 51 ++-
src/conf/domain_conf.h | 3 +
src/conf/secret_conf.c | 22 +-
src/conf/secret_conf.h | 1 +
src/qemu/qemu_command.c | 432 ++++++++++++++-------
src/secret/secret_driver.c | 8 +
tests/qemuargv2xmltest.c | 5 +
.../qemuxml2argv-disk-drive-network-gluster.args | 2 +-
...qemuxml2argv-disk-drive-network-iscsi-auth.args | 1 +
.../qemuxml2argv-disk-drive-network-iscsi-auth.xml | 31 ++
.../qemuxml2argv-disk-drive-network-iscsi.args | 1 +
.../qemuxml2argv-disk-drive-network-iscsi.xml | 34 ++
...qemuxml2argv-disk-drive-network-nbd-export.args | 5 +
.../qemuxml2argv-disk-drive-network-nbd-export.xml | 33 ++
...ml2argv-disk-drive-network-nbd-ipv6-export.args | 5 +
...xml2argv-disk-drive-network-nbd-ipv6-export.xml | 33 ++
.../qemuxml2argv-disk-drive-network-nbd-ipv6.args | 5 +
.../qemuxml2argv-disk-drive-network-nbd-ipv6.xml | 33 ++
.../qemuxml2argv-disk-drive-network-nbd-unix.args | 5 +
.../qemuxml2argv-disk-drive-network-nbd-unix.xml | 33 ++
tests/qemuxml2argvtest.c | 12 +
tests/qemuxml2xmltest.c | 7 +
27 files changed, 687 insertions(+), 177 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-export.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-export.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6-export.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6-export.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-unix.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-unix.xml
--
1.8.1.2
11 years, 7 months
[libvirt] [PATCH RESEND 1/2] NUMA: cleanup for numa related codes
by Gao feng
Intend to reduce the redundant code,use virNumaSetupMemoryPolicy
to replace virLXCControllerSetupNUMAPolicy and
qemuProcessInitNumaMemoryPolicy.
This patch also moves the numa related codes to the
file virnuma.c and virnuma.h
Signed-off-by: Gao feng <gaofeng(a)cn.fujitsu.com>
---
src/conf/domain_conf.c | 31 ++++--------
src/conf/domain_conf.h | 25 +---------
src/libvirt_private.syms | 9 ++--
src/lxc/lxc_controller.c | 116 +------------------------------------------
src/qemu/qemu_cgroup.c | 4 +-
src/qemu/qemu_driver.c | 6 +--
src/qemu/qemu_process.c | 123 +--------------------------------------------
src/util/virnuma.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++
src/util/virnuma.h | 30 +++++++++++
9 files changed, 182 insertions(+), 288 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a1cfc76..fa70329 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -690,11 +690,6 @@ VIR_ENUM_IMPL(virDomainTimerMode, VIR_DOMAIN_TIMER_MODE_LAST,
"paravirt",
"smpsafe");
-VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST,
- "strict",
- "preferred",
- "interleave");
-
VIR_ENUM_IMPL(virDomainStartupPolicy, VIR_DOMAIN_STARTUP_POLICY_LAST,
"default",
"mandatory",
@@ -709,12 +704,6 @@ VIR_ENUM_IMPL(virDomainDiskTray, VIR_DOMAIN_DISK_TRAY_LAST,
"closed",
"open");
-VIR_ENUM_IMPL(virDomainNumatuneMemPlacementMode,
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST,
- "default",
- "static",
- "auto");
-
VIR_ENUM_IMPL(virDomainRNGModel,
VIR_DOMAIN_RNG_MODEL_LAST,
"virtio");
@@ -9852,7 +9841,7 @@ virDomainDefParseXML(virCapsPtr caps,
int placement_mode = 0;
if (placement) {
if ((placement_mode =
- virDomainNumatuneMemPlacementModeTypeFromString(placement)) < 0) {
+ virNumaTuneMemPlacementModeTypeFromString(placement)) < 0) {
virReportError(VIR_ERR_XML_ERROR,
_("Unsupported memory placement "
"mode '%s'"), placement);
@@ -9862,18 +9851,18 @@ virDomainDefParseXML(virCapsPtr caps,
VIR_FREE(placement);
} else if (def->numatune.memory.nodemask) {
/* Defaults to "static" if nodeset is specified. */
- placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
+ placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC;
} else {
/* Defaults to "placement" of <vcpu> if nodeset is
* not specified.
*/
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC)
- placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
+ placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC;
else
- placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
+ placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO;
}
- if (placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC &&
+ if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC &&
!def->numatune.memory.nodemask) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("nodeset for NUMA memory tuning must be set "
@@ -9882,13 +9871,13 @@ virDomainDefParseXML(virCapsPtr caps,
}
/* Ignore 'nodeset' if 'placement' is 'auto' finally */
- if (placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
+ if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)
virBitmapFree(def->numatune.memory.nodemask);
/* Copy 'placement' of <numatune> to <vcpu> if its 'placement'
* is not specified and 'placement' of <numatune> is specified.
*/
- if (placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO &&
+ if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO &&
!def->cpumask)
def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO;
@@ -9907,7 +9896,7 @@ virDomainDefParseXML(virCapsPtr caps,
* and 'placement' of <vcpu> is 'auto'.
*/
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
- def->numatune.memory.placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
+ def->numatune.memory.placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO;
def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
}
}
@@ -14818,7 +14807,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAsprintf(buf, " <memory mode='%s' ", mode);
if (def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC) {
nodemask = virBitmapFormat(def->numatune.memory.nodemask);
if (nodemask == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -14829,7 +14818,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAsprintf(buf, "nodeset='%s'/>\n", nodemask);
VIR_FREE(nodemask);
} else if (def->numatune.memory.placement_mode) {
- placement = virDomainNumatuneMemPlacementModeTypeToString(def->numatune.memory.placement_mode);
+ placement = virNumaTuneMemPlacementModeTypeToString(def->numatune.memory.placement_mode);
virBufferAsprintf(buf, "placement='%s'/>\n", placement);
}
virBufferAddLit(buf, " </numatune>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index bfc37a0..6d856a3 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -47,6 +47,7 @@
# include "device_conf.h"
# include "virbitmap.h"
# include "virstoragefile.h"
+# include "virnuma.h"
/* forward declarations of all device types, required by
* virDomainDeviceDef
@@ -1605,14 +1606,6 @@ enum virDomainCpuPlacementMode {
VIR_DOMAIN_CPU_PLACEMENT_MODE_LAST
};
-enum virDomainNumatuneMemPlacementMode {
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_DEFAULT = 0,
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC,
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO,
-
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST
-};
-
typedef struct _virDomainTimerCatchupDef virDomainTimerCatchupDef;
typedef virDomainTimerCatchupDef *virDomainTimerCatchupDefPtr;
struct _virDomainTimerCatchupDef {
@@ -1701,18 +1694,6 @@ virDomainVcpuPinDefPtr virDomainVcpuPinFindByVcpu(virDomainVcpuPinDefPtr *def,
int nvcpupin,
int vcpu);
-typedef struct _virDomainNumatuneDef virDomainNumatuneDef;
-typedef virDomainNumatuneDef *virDomainNumatuneDefPtr;
-struct _virDomainNumatuneDef {
- struct {
- virBitmapPtr nodemask;
- int mode;
- int placement_mode; /* enum virDomainNumatuneMemPlacementMode */
- } memory;
-
- /* Future NUMA tuning related stuff should go here. */
-};
-
typedef struct _virBlkioDeviceWeight virBlkioDeviceWeight;
typedef virBlkioDeviceWeight *virBlkioDeviceWeightPtr;
struct _virBlkioDeviceWeight {
@@ -1802,7 +1783,7 @@ struct _virDomainDef {
virDomainVcpuPinDefPtr emulatorpin;
} cputune;
- virDomainNumatuneDef numatune;
+ virNumaTuneDef numatune;
/* These 3 are based on virDomainLifeCycleAction enum flags */
int onReboot;
@@ -2397,8 +2378,6 @@ VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression)
VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode)
VIR_ENUM_DECL(virDomainGraphicsSpiceClipboardCopypaste)
VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode)
-VIR_ENUM_DECL(virDomainNumatuneMemMode)
-VIR_ENUM_DECL(virDomainNumatuneMemPlacementMode)
VIR_ENUM_DECL(virDomainHyperv)
VIR_ENUM_DECL(virDomainRNGModel)
VIR_ENUM_DECL(virDomainRNGBackend)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index dc01bfa..8890859 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -252,10 +252,6 @@ virDomainNetRemove;
virDomainNetTypeToString;
virDomainNostateReasonTypeFromString;
virDomainNostateReasonTypeToString;
-virDomainNumatuneMemModeTypeFromString;
-virDomainNumatuneMemModeTypeToString;
-virDomainNumatuneMemPlacementModeTypeFromString;
-virDomainNumatuneMemPlacementModeTypeToString;
virDomainObjAssignDef;
virDomainObjCopyPersistentDef;
virDomainObjGetPersistentDef;
@@ -1557,7 +1553,12 @@ virNodeSuspendGetTargetMask;
# util/virnuma.h
+virDomainNumatuneMemModeTypeFromString;
+virDomainNumatuneMemModeTypeToString;
+virNumaTuneMemPlacementModeTypeFromString;
+virNumaTuneMemPlacementModeTypeToString;
virNumaGetAutoPlacementAdvice;
+virNumaSetupMemoryPolicy;
# util/virobject.h
virClassForObject;
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 405205c..f19f8c1 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -46,11 +46,6 @@
# include <cap-ng.h>
#endif
-#if WITH_NUMACTL
-# define NUMA_VERSION1_COMPATIBILITY 1
-# include <numa.h>
-#endif
-
#include "virerror.h"
#include "virlog.h"
#include "virutil.h"
@@ -469,113 +464,6 @@ cleanup:
return ret;
}
-#if WITH_NUMACTL
-static int virLXCControllerSetupNUMAPolicy(virLXCControllerPtr ctrl,
- virBitmapPtr nodemask)
-{
- nodemask_t mask;
- int mode = -1;
- int node = -1;
- int ret = -1;
- int i = 0;
- int maxnode = 0;
- bool warned = false;
- virDomainNumatuneDef numatune = ctrl->def->numatune;
- virBitmapPtr tmp_nodemask = NULL;
-
- if (numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
- if (!numatune.memory.nodemask)
- return 0;
- VIR_DEBUG("Set NUMA memory policy with specified nodeset");
- tmp_nodemask = numatune.memory.nodemask;
- } else if (numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO) {
- VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
- tmp_nodemask = nodemask;
- } else {
- return 0;
- }
-
- VIR_DEBUG("Setting NUMA memory policy");
-
- if (numa_available() < 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("Host kernel is not aware of NUMA."));
- return -1;
- }
-
- maxnode = numa_max_node() + 1;
-
- /* Convert nodemask to NUMA bitmask. */
- nodemask_zero(&mask);
- i = -1;
- while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
- if (i > NUMA_NUM_NODES) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Host cannot support NUMA node %d"), i);
- return -1;
- }
- if (i > maxnode && !warned) {
- VIR_WARN("nodeset is out of range, there is only %d NUMA "
- "nodes on host", maxnode);
- warned = true;
- }
- nodemask_set(&mask, i);
- }
-
- mode = ctrl->def->numatune.memory.mode;
-
- if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
- numa_set_bind_policy(1);
- numa_set_membind(&mask);
- numa_set_bind_policy(0);
- } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
- int nnodes = 0;
- for (i = 0; i < NUMA_NUM_NODES; i++) {
- if (nodemask_isset(&mask, i)) {
- node = i;
- nnodes++;
- }
- }
-
- if (nnodes != 1) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("NUMA memory tuning in 'preferred' mode "
- "only supports single node"));
- goto cleanup;
- }
-
- numa_set_bind_policy(0);
- numa_set_preferred(node);
- } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
- numa_set_interleave_mask(&mask);
- } else {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Unable to set NUMA policy %s"),
- virDomainNumatuneMemModeTypeToString(mode));
- goto cleanup;
- }
-
- ret = 0;
-
-cleanup:
- return ret;
-}
-#else
-static int virLXCControllerSetupNUMAPolicy(virLXCControllerPtr ctrl,
- virBitmapPtr nodemask ATTRIBUTE_UNUSED)
-{
- if (ctrl->def->numatune.memory.nodemask) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("NUMA policy is not available on this platform"));
- return -1;
- }
-
- return 0;
-}
-#endif
-
/*
* To be run while still single threaded
@@ -638,7 +526,7 @@ static int virLXCControllerGetNumadAdvice(virLXCControllerPtr ctrl,
if ((ctrl->def->placement_mode ==
VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
(ctrl->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) {
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)) {
nodeset = virNumaGetAutoPlacementAdvice(ctrl->def->vcpus,
ctrl->def->mem.cur_balloon);
if (!nodeset)
@@ -675,7 +563,7 @@ static int virLXCControllerSetupResourceLimits(virLXCControllerPtr ctrl,
int ret = -1;
if (virLXCControllerGetNumadAdvice(ctrl, &nodemask) < 0 ||
- virLXCControllerSetupNUMAPolicy(ctrl, nodemask) < 0)
+ virNumaSetupMemoryPolicy(ctrl->def->numatune, nodemask) < 0)
goto cleanup;
if (virLXCControllerSetupCpuAffinity(ctrl) < 0)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 9d6e88b..c9b4ca2 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -423,12 +423,12 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
if ((vm->def->numatune.memory.nodemask ||
(vm->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) &&
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)) &&
vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
char *mask = NULL;
if (vm->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)
mask = virBitmapFormat(nodemask);
else
mask = virBitmapFormat(vm->def->numatune.memory.nodemask);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9cd9e44..f057d38 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7648,7 +7648,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
virBitmapFree(vm->def->numatune.memory.nodemask);
vm->def->numatune.memory.placement_mode =
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC;
vm->def->numatune.memory.nodemask = virBitmapNewCopy(nodeset);
}
@@ -7657,7 +7657,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
persistentDef->numatune.memory.nodemask = nodeset;
persistentDef->numatune.memory.placement_mode =
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC;
nodeset = NULL;
}
virBitmapFree(nodeset);
@@ -7667,7 +7667,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
if (!persistentDef->numatune.memory.placement_mode)
persistentDef->numatune.memory.placement_mode =
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO;
if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
ret = -1;
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2465938..fcb3c50 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -45,11 +45,6 @@
#include "qemu_bridge_filter.h"
#include "qemu_migration.h"
-#if WITH_NUMACTL
-# define NUMA_VERSION1_COMPATIBILITY 1
-# include <numa.h>
-#endif
-
#include "datatypes.h"
#include "virlog.h"
#include "virerror.h"
@@ -1791,120 +1786,6 @@ qemuProcessDetectVcpuPIDs(virQEMUDriverPtr driver,
}
-/*
- * Set NUMA memory policy for qemu process, to be run between
- * fork/exec of QEMU only.
- */
-#if WITH_NUMACTL
-static int
-qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
- virBitmapPtr nodemask)
-{
- nodemask_t mask;
- int mode = -1;
- int node = -1;
- int ret = -1;
- int i = 0;
- int maxnode = 0;
- bool warned = false;
- virDomainNumatuneDef numatune = vm->def->numatune;
- virBitmapPtr tmp_nodemask = NULL;
-
- if (numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
- if (!numatune.memory.nodemask)
- return 0;
- VIR_DEBUG("Set NUMA memory policy with specified nodeset");
- tmp_nodemask = numatune.memory.nodemask;
- } else if (numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO) {
- VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
- tmp_nodemask = nodemask;
- } else {
- return 0;
- }
-
- if (numa_available() < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Host kernel is not aware of NUMA."));
- return -1;
- }
-
- maxnode = numa_max_node() + 1;
- /* Convert nodemask to NUMA bitmask. */
- nodemask_zero(&mask);
- i = -1;
- while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
- if (i > NUMA_NUM_NODES) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Host cannot support NUMA node %d"), i);
- return -1;
- }
- if (i > maxnode && !warned) {
- VIR_WARN("nodeset is out of range, there is only %d NUMA "
- "nodes on host", maxnode);
- warned = true;
- }
- nodemask_set(&mask, i);
- }
-
- mode = numatune.memory.mode;
-
- if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
- numa_set_bind_policy(1);
- numa_set_membind(&mask);
- numa_set_bind_policy(0);
- } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
- int nnodes = 0;
- for (i = 0; i < NUMA_NUM_NODES; i++) {
- if (nodemask_isset(&mask, i)) {
- node = i;
- nnodes++;
- }
- }
-
- if (nnodes != 1) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("NUMA memory tuning in 'preferred' mode "
- "only supports single node"));
- goto cleanup;
- }
-
- numa_set_bind_policy(0);
- numa_set_preferred(node);
- } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
- numa_set_interleave_mask(&mask);
- } else {
- /* XXX: Shouldn't go here, as we already do checking when
- * parsing domain XML.
- */
- virReportError(VIR_ERR_XML_ERROR,
- "%s", _("Invalid mode for memory NUMA tuning."));
- goto cleanup;
- }
-
- ret = 0;
-
-cleanup:
- return ret;
-}
-#else
-static int
-qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
- virBitmapPtr nodemask ATTRIBUTE_UNUSED)
-{
- if (vm->def->numatune.memory.nodemask) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("libvirt is compiled without NUMA tuning support"));
-
- return -1;
- }
-
- return 0;
-}
-#endif
-
-
/* Helper to prepare cpumap for affinity setting, convert
* NUMA nodeset into cpuset if @nodemask is not NULL, otherwise
* just return a new allocated bitmap.
@@ -2654,7 +2535,7 @@ static int qemuProcessHook(void *data)
qemuProcessInitCpuAffinity(h->driver, h->vm, h->nodemask) < 0)
goto cleanup;
- if (qemuProcessInitNumaMemoryPolicy(h->vm, h->nodemask) < 0)
+ if (virNumaSetupMemoryPolicy(h->vm->def->numatune, h->nodemask) < 0)
goto cleanup;
ret = 0;
@@ -3608,7 +3489,7 @@ int qemuProcessStart(virConnectPtr conn,
if ((vm->def->placement_mode ==
VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
(vm->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) {
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)) {
nodeset = virNumaGetAutoPlacementAdvice(vm->def->vcpus,
vm->def->mem.cur_balloon);
if (!nodeset)
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index f6a6eb2..bace06f 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -21,12 +21,30 @@
#include <config.h>
+#if WITH_NUMACTL
+# define NUMA_VERSION1_COMPATIBILITY 1
+# include <numa.h>
+#endif
+
#include "virnuma.h"
#include "vircommand.h"
#include "virerror.h"
+#include "virlog.h"
#define VIR_FROM_THIS VIR_FROM_NONE
+VIR_ENUM_IMPL(virDomainNumatuneMemMode,
+ VIR_DOMAIN_NUMATUNE_MEM_LAST,
+ "strict",
+ "preferred",
+ "interleave");
+
+VIR_ENUM_IMPL(virNumaTuneMemPlacementMode,
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_LAST,
+ "default",
+ "static",
+ "auto");
+
#if HAVE_NUMAD
char *
virNumaGetAutoPlacementAdvice(unsigned short vcpus,
@@ -59,3 +77,111 @@ virNumaGetAutoPlacementAdvice(unsigned short vcpus ATTRIBUTE_UNUSED,
return NULL;
}
#endif
+
+#if WITH_NUMACTL
+int
+virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
+ virBitmapPtr nodemask)
+{
+ nodemask_t mask;
+ int mode = -1;
+ int node = -1;
+ int ret = -1;
+ int i = 0;
+ int maxnode = 0;
+ bool warned = false;
+ virBitmapPtr tmp_nodemask = NULL;
+
+ if (numatune.memory.placement_mode ==
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC) {
+ if (!numatune.memory.nodemask)
+ return 0;
+ VIR_DEBUG("Set NUMA memory policy with specified nodeset");
+ tmp_nodemask = numatune.memory.nodemask;
+ } else if (numatune.memory.placement_mode ==
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO) {
+ VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
+ tmp_nodemask = nodemask;
+ } else {
+ return 0;
+ }
+
+ if (numa_available() < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Host kernel is not aware of NUMA."));
+ return -1;
+ }
+
+ maxnode = numa_max_node() + 1;
+ /* Convert nodemask to NUMA bitmask. */
+ nodemask_zero(&mask);
+ i = -1;
+ while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
+ if (i > NUMA_NUM_NODES) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Host cannot support NUMA node %d"), i);
+ return -1;
+ }
+ if (i > maxnode && !warned) {
+ VIR_WARN("nodeset is out of range, there is only %d NUMA "
+ "nodes on host", maxnode);
+ warned = true;
+ }
+ nodemask_set(&mask, i);
+ }
+
+ mode = numatune.memory.mode;
+
+ if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
+ numa_set_bind_policy(1);
+ numa_set_membind(&mask);
+ numa_set_bind_policy(0);
+ } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
+ int nnodes = 0;
+ for (i = 0; i < NUMA_NUM_NODES; i++) {
+ if (nodemask_isset(&mask, i)) {
+ node = i;
+ nnodes++;
+ }
+ }
+
+ if (nnodes != 1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("NUMA memory tuning in 'preferred' mode "
+ "only supports single node"));
+ goto cleanup;
+ }
+
+ numa_set_bind_policy(0);
+ numa_set_preferred(node);
+ } else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
+ numa_set_interleave_mask(&mask);
+ } else {
+ /* XXX: Shouldn't go here, as we already do checking when
+ * parsing domain XML.
+ */
+ virReportError(VIR_ERR_XML_ERROR,
+ "%s", _("Invalid mode for memory NUMA tuning."));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ return ret;
+}
+#else
+int
+virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
+ virBitmapPtr nodemask ATTRIBUTE_UNUSED)
+{
+ if (numatune.memory.nodemask) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("libvirt is compiled without NUMA tuning support"));
+
+ return -1;
+ }
+
+ return 0;
+}
+#endif
diff --git a/src/util/virnuma.h b/src/util/virnuma.h
index d3d7d3e..9ff8e69 100644
--- a/src/util/virnuma.h
+++ b/src/util/virnuma.h
@@ -22,7 +22,37 @@
#ifndef __VIR_NUMA_H__
# define __VIR_NUMA_H__
+# include "internal.h"
+# include "virbitmap.h"
+# include "virutil.h"
+
+enum virNumaTuneMemPlacementMode {
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_DEFAULT = 0,
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC,
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO,
+
+ VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_LAST
+};
+
+VIR_ENUM_DECL(virNumaTuneMemPlacementMode)
+
+VIR_ENUM_DECL(virDomainNumatuneMemMode)
+
+typedef struct _virNumaTuneDef virNumaTuneDef;
+typedef virNumaTuneDef *virNumaTuneDefPtr;
+struct _virNumaTuneDef {
+ struct {
+ virBitmapPtr nodemask;
+ int mode;
+ int placement_mode; /* enum virNumaTuneMemPlacementMode */
+ } memory;
+
+ /* Future NUMA tuning related stuff should go here. */
+};
+
char *virNumaGetAutoPlacementAdvice(unsigned short vcups,
unsigned long long balloon);
+int virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
+ virBitmapPtr nodemask);
#endif /* __VIR_NUMA_H__ */
--
1.7.11.7
11 years, 7 months
Re: [libvirt] Consultation of the patch "util: Prepare helpers for unpriv_sgio setting"
by yuxh
On 03/13/2013 11:33 AM, Osier Yang wrote:
> On 2013年03月13日 11:04, yuxh wrote:
>> To Osier Yang
>>
>> Sorry for disturbing you on the working time, but I really need your
>> help.
>> I met a problem when I do the virtualization test on the environment of
>> (Host: RHEL6.4GA. Guest: RHEL6.4GA) and it seems to have relationship
>> with your patch of "util: Prepare helpers for unpriv_sgio setting".
>
> Never mind, it's the bug I produced. :(
>
>>
>> I added a disk to virtio-scsi bus through the VM's XML file like this:
>> <disk type='block' device='disk'>
>> <driver name='qemu' type='raw' io='threads'/>
>> <source dev='/mnt/test.raw'/>
>> <target dev='sdb' bus='scsi'/>
>> <shareable/>
>> </disk>
>>
>> Then when I started the VM, I met the error.
>> [root@build SOURCES]# virsh start pan64ga
>> error: Failed to start domain pan64ga
>> error: Unable to get minor number of device '/mnt/test.raw': Invalid
>> argument
>>
>> [root@build SOURCES]#
>>
>> I tried other source files and other way of using if and I found:
>> 1). If we use the files which format is raw, qed and qcow2 as the disk
>> this error occur again.
>> 2). If we use partition(such as /dev/sdb1) or whole disk(such as
>> /dev/sdb) this error doesn't occur.
>> 3). If we delete the "<shareable/>" then files, partition and disk all
>> can be used correctly.
>>
>> And I investigate the error msg. it is returned by qemuGetSharedDiskKey
>> fuction.
>> char *
>> qemuGetSharedDiskKey(const char *disk_path)
>> {
>> ...
>> // error occur here. return value is -22
>> if ((rc = virGetDeviceID(disk_path, &maj, &min)) < 0) {
>> virReportSystemError(-rc,
>> _("Unable to get minor number of device '%s'"),
>> disk_path);
>> return NULL;
>> }
>> ...
>> }
>>
>> Go on the virGetDeviceID fuction:
>> int
>> virGetDeviceID(const char *path, int *maj, int *min)
>> {
>> ...
>>
>> if (!S_ISBLK(sb.st_mode)) {
>> VIR_FREE(canonical_path);
>> return -EINVAL; // error occur here and it return -22
>> }
>> ...
>> }
>>
>> So the error occur place is "S_ISBLK(sb.st_mode)" and I tried compiled
>> the libvirt with these lines deleted and the error didn't happen again.
>> Also I checked the disk if VM and it worked well.
>> I found this fuction virGetDeviceID is come from your patch of "util:
>> Prepare helpers for unpriv_sgio setting". But I am not familiar with
>> libvirt.
>> So I have to consult with you about whether this "S_ISBLK" check is
>> vital and If we can delete it or
>> find out some method to avoid this error so we can use the file as
>> shared disk in VM.
>
> It's fixd by
> https://www.redhat.com/archives/libvir-list/2013-February/msg01024.html,
> which is already committed to upstream, and backported
> to 6.4.z. You will see the fix in the new build, which will come soon.
>
> Regards,
> Osier
Sorry, I have tried the the libvirt's upstream code and it still have
this error.
According to the code, if we use "<disk type='block' device='disk'> "
and "<shareable/> " to set the disk's configuration in VM's XML file, it
will go through like below:
int
qemuAddSharedDisk(virQEMUDriverPtr driver,
virDomainDiskDefPtr disk,
const char *name)
{ ...
if (!(key = qemuGetSharedDiskKey(disk->src)))
goto cleanup;
...
}
char *
qemuGetSharedDiskKey(const char *disk_path)
{
...
if ((rc = virGetDeviceID(disk_path, &maj, &min)) < 0) {
virReportSystemError(-rc,
_("Unable to get minor number of device
'%s'"),
disk_path);
return NULL;
}
...
}
int
virGetDeviceID(const char *path, int *maj, int *min)
{
struct stat sb;
if (stat(path, &sb) < 0)
return -errno;
if (!S_ISBLK(sb.st_mode))
return -EINVAL;
if (maj)
*maj = major(sb.st_rdev);
if (min)
*min = minor(sb.st_rdev);
return 0;
}
To make a long story short, the virGetDeviceID fuction want to get the
maj and min number of the source file which we provided as the VM's
disk. But the file such as /mnt/test.raw doesn't have the maj and min
number.
So virGetDeviceID return " -EINVAL" and qemuGetSharedDiskKey print the
error message of "Unable to get minor number of device /mnt/test.raw".
That's the reason the VM can't be started.
So I just want to know now, if the way I used a file to act as VM's disk
and set "<disk type='block' device='disk'>" , "<shareable/> " at the
same time is reasonable.
Thanks
yuxh
>
>
--
以上
第一软件事业部 第一开发部 driver组 于星海
Best Regards
--------------------------------------------------
Yu Xinghai
Development Dept.I
Nanjing Fujitsu Nanda Software Tech. Co., Ltd.(FNST)
No.6 Wenzhu Road, Nanjing, 210012, China
TEL: +86+25-86630566-8533
FUJITSU INTERNAL: 7998-8533
FAX: +86+25-83317685
MAIL: yuxinghai(a)cn.fujitsu.com
--------------------------------------------------
11 years, 7 months
[libvirt] [PATCH 1/1] Clean redundant code about VCPU string checking
by Li Zhang
From: Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
Now that VCPU number are removed from qemu_monitor_text.c.
VCPU string checking also should be removed.
Report-by: John Ferlan <jferlan(a)redhat.com>
Signed-off-by: Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
---
src/qemu/qemu_monitor_text.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 1b6efba..3a0c55f 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -527,17 +527,10 @@ int qemuMonitorTextGetCPUInfo(qemuMonitorPtr mon,
*/
line = qemucpus;
do {
- char *offset = strchr(line, '#');
+ char *offset = NULL;
char *end = NULL;
int tid = 0;
- /* See if we're all done */
- if (offset == NULL)
- break;
-
- if (end == NULL || *end != ':')
- goto error;
-
/* Extract host Thread ID */
if ((offset = strstr(line, "thread_id=")) == NULL)
goto error;
--
1.7.10.1
11 years, 7 months
[libvirt] [PATCH] Don't fail if SELinux is diabled
by Guido Günther
but libvirt is built with --with-selinux. In this case getpeercon
returns ENOPROTOOPT so dont' return an error in that case but simply
don't set seccon.
---
src/rpc/virnetsocket.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index 39504ac..c4fd9ee 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -1171,7 +1171,7 @@ int virNetSocketGetSecurityContext(virNetSocketPtr sock,
virObjectLock(sock);
if (getpeercon(sock->fd, &seccon) < 0) {
- if (errno == ENOSYS) {
+ if (errno == ENOSYS || errno == ENOPROTOOPT) {
ret = 0;
goto cleanup;
}
--
1.7.10.4
11 years, 7 months
[libvirt] [PATCH] clarify vmrsh net commands
by Gene Czarcinski
Clarify that net-create deals with a transient virtual
network whereas net-define defines a persistent virtual
network definition and will create the network (xml)
definition file.
Clarify that net-destroy works with both transient and
persistent virtual networks.
Change the comment about error checking with respect to
net-edit and net-define: same error checking and
diagnostics.
Signed-off-by: Gene Czarcinski <gene(a)czarc.net>
---
tools/virsh.pod | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod
index a5d8fe6..1fe08f4 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -2034,19 +2034,20 @@ The I<--disable> option disable autostarting.
=item B<net-create> I<file>
-Create a virtual network from an XML I<file>, see the documentation at
-L<http://libvirt.org/formatnetwork.html> to get a description of the
-XML network format used by libvirt.
+Create a transient (temporary) virtual network from an
+XML I<file> and instantiate (start) the network.
+See the documentation at L<http://libvirt.org/formatnetwork.html>
+to get a description of the XML network format used by libvirt.
=item B<net-define> I<file>
-Define a virtual network from an XML I<file>, the network is just defined but
-not instantiated.
+Define a persistent virtual network from an XML I<file>, the network is just defined but
+not instantiated (started).
=item B<net-destroy> I<network>
-Destroy (stop) a given virtual network specified by its name or UUID. This
-takes effect immediately.
+Destroy (stop) a given transient or persistent virtual network
+specified by its name or UUID. This takes effect immediately.
=item B<net-dumpxml> I<network> [I<--inactive>]
@@ -2064,7 +2065,8 @@ This is equivalent to:
vi network.xml (or make changes with your other text editor)
virsh net-define network.xml
-except that it does some error checking.
+The same error checking is performed by net-edit and net-define and
+the same diagnostic error messages will be issued.
The editor used can be supplied by the C<$VISUAL> or C<$EDITOR> environment
variables, and defaults to C<vi>.
--
1.8.1.4
11 years, 7 months
[libvirt] about Application_Development_Guide.pdf
by huyp1024
HI,buddy. I'm sheldon.
I'm trying to develop virtual machine lifecycle management software using libvirt.
I found the development guide is very useful,it helps a lot.
But this book I download from offical website is a draft,there are a lot of funcitons which are not claimed.
I appreciate very much that you give me some document that developers are being in reference to .
Best wishes! keep in touch.
Yours sincely!
.
11 years, 7 months
[libvirt] [PATCH 1/4] doc/schema: add ocfs2 to storage pool
by Philipp Hahn
Add ocfs2 for disk pool.
Signed-off-by: Philipp Hahn <hahn(a)univention.de>
---
docs/schemas/storagevol.rng | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng
index ba95c55..765c5a5 100644
--- a/docs/schemas/storagevol.rng
+++ b/docs/schemas/storagevol.rng
@@ -179,11 +179,10 @@
<value>vfat</value>
<value>hfs+</value>
<value>xfs</value>
+ <value>ocfs2</value>
</choice>
-
</define>
-
<define name='formatfile'>
<choice>
<value>unknown</value>
--
1.7.10.4
11 years, 7 months
[libvirt] [PATCH] Fix typos s/HAVE_SELINUX/WITH_SELINUX/
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
The virNetSocket & virIdentity classes accidentally got some
conditionals using HAVE_SELINUX instead of WITH_SELINUX.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
Pushed under trivial rule
---
src/rpc/virnetsocket.c | 4 ++--
src/util/viridentity.c | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index 68aca1b..c86a47a 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -40,7 +40,7 @@
#endif
#include "c-ctype.h"
-#ifdef HAVE_SELINUX
+#ifdef WITH_SELINUX
# include <selinux/selinux.h>
#endif
@@ -1160,7 +1160,7 @@ int virNetSocketGetUNIXIdentity(virNetSocketPtr sock ATTRIBUTE_UNUSED,
}
#endif
-#ifdef HAVE_SELINUX
+#ifdef WITH_SELINUX
int virNetSocketGetSecurityContext(virNetSocketPtr sock,
char **context)
{
diff --git a/src/util/viridentity.c b/src/util/viridentity.c
index 2092137..1d40972 100644
--- a/src/util/viridentity.c
+++ b/src/util/viridentity.c
@@ -22,7 +22,7 @@
#include <config.h>
#include <unistd.h>
-#if HAVE_SELINUX
+#if WITH_SELINUX
# include <selinux/selinux.h>
#endif
@@ -135,7 +135,7 @@ virIdentityPtr virIdentityGetSystem(void)
char *groupname = NULL;
char *seccontext = NULL;
virIdentityPtr ret = NULL;
-#if HAVE_SELINUX
+#if WITH_SELINUX
security_context_t con;
#endif
@@ -144,7 +144,7 @@ virIdentityPtr virIdentityGetSystem(void)
if (!(groupname = virGetGroupName(getgid())))
goto cleanup;
-#if HAVE_SELINUX
+#if WITH_SELINUX
if (getcon(&con) < 0) {
virReportSystemError(errno, "%s",
_("Unable to lookup SELinux process context"));
--
1.8.1.4
11 years, 7 months