[libvirt] [PATCH] interface: Check for interface (in-)activity on some operations
by Michal Privoznik
Right now it is possible to undefine an active interface, or
destroy inactive. This patch add some checking to these operations
to prevent this. Also fix test driver.
---
src/interface/netcf_driver.c | 83 ++++++++++++++++++++++++++++++++++++------
src/test/test_driver.c | 5 +++
2 files changed, 76 insertions(+), 12 deletions(-)
diff --git a/src/interface/netcf_driver.c b/src/interface/netcf_driver.c
index 855b5a3..bf590f3 100644
--- a/src/interface/netcf_driver.c
+++ b/src/interface/netcf_driver.c
@@ -119,6 +119,40 @@ static struct netcf_if *interfaceDriverGetNetcfIF(struct netcf *ncf, virInterfac
return iface;
}
+/*
+ * interfaceObjIsActive:
+ * @iface - interface
+ *
+ * Caller MUST have driver locked to prevent race condition.
+ * Returns:
+ * -1 on error
+ * 0 on inactive interface
+ * 1 on active interface
+ */
+static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+interfaceObjIsActive(struct interface_driver *driver,
+ struct netcf_if *iface,
+ virInterfacePtr ifinfo)
+{
+ int ret = -1;
+ unsigned int flags = 0;
+
+ if (ncf_if_status(iface, &flags) < 0) {
+ const char *errmsg, *details;
+ int errcode = ncf_error(driver->netcf, &errmsg, &details);
+ interfaceReportError(netcf_to_vir_err(errcode),
+ _("failed to get status of interface %s: %s%s%s"),
+ ifinfo->name, errmsg, details ? " - " : "",
+ details ? details : "");
+ goto cleanup;
+ }
+
+ ret = flags & NETCF_IFACE_ACTIVE ? 1 : 0;
+
+cleanup:
+ return ret;
+}
+
static virDrvOpenStatus interfaceOpenInterface(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
unsigned int flags)
@@ -438,6 +472,7 @@ static int interfaceUndefine(virInterfacePtr ifinfo) {
struct interface_driver *driver = ifinfo->conn->interfacePrivateData;
struct netcf_if *iface = NULL;
int ret = -1;
+ int active;
interfaceDriverLock(driver);
@@ -447,6 +482,17 @@ static int interfaceUndefine(virInterfacePtr ifinfo) {
goto cleanup;
}
+ active = interfaceObjIsActive(driver, iface, ifinfo);
+ if (active < 0) {
+ /* helper already reported error */
+ goto cleanup;
+ } else if (active) {
+ interfaceReportError(VIR_ERR_OPERATION_INVALID,
+ _("interface %s is active"),
+ ifinfo->name);
+ goto cleanup;
+ }
+
ret = ncf_if_undefine(iface);
if (ret < 0) {
const char *errmsg, *details;
@@ -470,6 +516,7 @@ static int interfaceCreate(virInterfacePtr ifinfo,
struct interface_driver *driver = ifinfo->conn->interfacePrivateData;
struct netcf_if *iface = NULL;
int ret = -1;
+ int active;
virCheckFlags(0, -1);
@@ -481,6 +528,17 @@ static int interfaceCreate(virInterfacePtr ifinfo,
goto cleanup;
}
+ active = interfaceObjIsActive(driver, iface, ifinfo);
+ if (active < 0) {
+ /* helper already reported error */
+ goto cleanup;
+ } else if (active) {
+ interfaceReportError(VIR_ERR_OPERATION_INVALID,
+ _("interface %s is already active"),
+ ifinfo->name);
+ goto cleanup;
+ }
+
ret = ncf_if_up(iface);
if (ret < 0) {
const char *errmsg, *details;
@@ -504,6 +562,7 @@ static int interfaceDestroy(virInterfacePtr ifinfo,
struct interface_driver *driver = ifinfo->conn->interfacePrivateData;
struct netcf_if *iface = NULL;
int ret = -1;
+ int active;
virCheckFlags(0, -1);
@@ -515,6 +574,17 @@ static int interfaceDestroy(virInterfacePtr ifinfo,
goto cleanup;
}
+ active = interfaceObjIsActive(driver, iface, ifinfo);
+ if (active < 0) {
+ /* helper already reported error */
+ goto cleanup;
+ } else if (!active) {
+ interfaceReportError(VIR_ERR_OPERATION_INVALID,
+ _("interface %s is not active"),
+ ifinfo->name);
+ goto cleanup;
+ }
+
ret = ncf_if_down(iface);
if (ret < 0) {
const char *errmsg, *details;
@@ -536,7 +606,6 @@ static int interfaceIsActive(virInterfacePtr ifinfo)
{
struct interface_driver *driver = ifinfo->conn->interfacePrivateData;
struct netcf_if *iface = NULL;
- unsigned int flags = 0;
int ret = -1;
interfaceDriverLock(driver);
@@ -547,17 +616,7 @@ static int interfaceIsActive(virInterfacePtr ifinfo)
goto cleanup;
}
- if (ncf_if_status(iface, &flags) < 0) {
- const char *errmsg, *details;
- int errcode = ncf_error(driver->netcf, &errmsg, &details);
- interfaceReportError(netcf_to_vir_err(errcode),
- _("failed to get status of interface %s: %s%s%s"),
- ifinfo->name, errmsg, details ? " - " : "",
- details ? details : "");
- goto cleanup;
- }
-
- ret = flags & NETCF_IFACE_ACTIVE ? 1 : 0;
+ ret = interfaceObjIsActive(driver, iface, ifinfo);
cleanup:
ncf_if_free(iface);
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index f3fb320..d165586 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -3648,6 +3648,11 @@ static int testInterfaceUndefine(virInterfacePtr iface)
goto cleanup;
}
+ if (privinterface->active != 0) {
+ testError(VIR_ERR_OPERATION_INVALID, NULL);
+ goto cleanup;
+ }
+
virInterfaceRemove(&privconn->ifaces,
privinterface);
ret = 0;
--
1.7.5.rc3
13 years, 9 months
[libvirt] [PATCH v2 0/8] Introduce New API virDomainUndefineFlags
by Osier Yang
Per discussion on
https://www.redhat.com/archives/libvir-list/2011-July/msg00556.html,
This patch series introduce new API virDomainUndefineFlags, which
only support flag VIR_DOMAIN_UNDEFINE_MANAGED_STATE now, might introduce
more flags in future though.
If the domain has a managed state file, then including
VIR_DOMAIN_UNDEFINE_MANAGED_STATE in @flags will also remove that file,
and omitting the flag will cause the undefine process to fail. This
also changes the behavior of virDomainUndefine, but considering undefine
a domain with managed state file left is unsafe, we need to do so.
[PATCH v2 1/8] is small fix on rpc generator scripts, not related with the
new API.
[PATCH v2 1/8] rpc: Fix typos in rpc generator scripts
[PATCH v2 2/8] undefine: Define the new API
[PATCH v2 3/8] undefine: Wire up the remote protocol
[PATCH v2 4/8] undefine: Implement internal API for qemu driver
[PATCH v2 5/8] undefine: Implement internal API for libxl driver
[PATCH v2 6/8] undefine: Implement undefineFlags in all other
[PATCH v2 7/8] undefine: Extend virsh undefine to support the new
[PATCH v2 8/8] virsh: Extend virsh dominfo to display if managed
v1 - v2:
* s/virDomainUndefineWithFlags/virDomainUndefineFlags/
* Update with other bunch of feedbacks from Eric
* Changes on virsh dominfo to display if domain managed state exists
Regards
Osier
13 years, 9 months
[libvirt] [PATCH] doc: Correct docs for iface commands
by Osier Yang
duplicate documents for "iface-name", lacks of document for
"iface-mac", inconsistent option names with virsh help strings.
---
tools/virsh.pod | 16 ++++++++++------
1 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 377fac0..4f218d3 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1081,20 +1081,24 @@ Returns the list of active host interfaces. If I<--all> is specified
this will also include defined but inactive interfaces. If
I<--inactive> is specified only the inactive ones will be listed.
-=item B<iface-name> I<iface-MAC>
+=item B<iface-name> I<interface>
-Convert a host interface MAC to interface name, if the I<iface-MAC> is
-unique among the host's interfaces.
+Convert a host interface MAC to interface name, if the MAC address is unique
+among the host's interfaces.
-=item B<iface-name> I<iface-MAC>
+I<interface> specifies the interface MAC address.
+
+=item B<iface-mac> I<interface>
Convert a host interface name to MAC address.
-=item B<iface-start> I<iface>
+I<interface> specifies the interface name.
+
+=item B<iface-start> I<interface>
Start a (previously defined) host interface, such as by running "if-up".
-=item B<iface-undefine> I<iface>
+=item B<iface-undefine> I<interface>
Undefine the configuration for an inactive host interface.
--
1.7.6
13 years, 9 months
[libvirt] [PATCHv4] libvirt: do not mix internal flags into public API
by Eric Blake
There were two API in driver.c that were silently masking flags
bits prior to calling out to the drivers, and several others
that were explicitly masking flags bits. This is not
forward-compatible - if we ever have that many flags in the
future, then talking to an old server that masks out the
flags would be indistinguishable from talking to a new server
that can honor the flag. In general, libvirt.c should forward
_all_ flags on to drivers, and only the drivers should reject
unknown flags.
In the case of virDrvSecretGetValue, the solution is to separate
the internal driver callback function to have two parameters
instead of one, with only one parameter affected by the public
API. In the case of virDomainGetXMLDesc, it turns out that
no one was ever mixing VIR_DOMAIN_XML_INTERNAL_STATUS with
the dumpxml path in the first place; that internal flag was
only used in saving and restoring state files, which happened
to be in functions internal to a single file, so there is no
mixing of the internal flag with a public flags argument.
Additionally, virDomainMemoryStats passed a flags argument
over RPC, but not to the driver.
* src/driver.h (VIR_DOMAIN_XML_FLAGS_MASK)
(VIR_SECRET_GET_VALUE_FLAGS_MASK): Delete.
(virDrvSecretGetValue): Separate out internal flags.
(virDrvDomainMemoryStats): Provide missing flags argument.
* src/driver.c (verify): Drop unused check.
* src/conf/domain_conf.h (virDomainObjParseFile): Delete
declaration.
(virDomainXMLInternalFlags): Move...
* src/conf/domain_conf.c: ...here. Delete redundant include.
(virDomainObjParseFile): Make static.
* src/libvirt.c (virDomainGetXMLDesc, virSecretGetValue): Update
clients.
(virDomainMemoryPeek, virInterfaceGetXMLDesc)
(virDomainMemoryStats, virDomainBlockPeek, virNetworkGetXMLDesc)
(virStoragePoolGetXMLDesc, virStorageVolGetXMLDesc)
(virNodeNumOfDevices, virNodeListDevices, virNWFilterGetXMLDesc):
Don't mask unknown flags.
* src/interface/netcf_driver.c (interfaceGetXMLDesc): Reject
unknown flags.
* src/secret/secret_driver.c (secretGetValue): Update clients.
* src/remote/remote_driver.c (remoteSecretGetValue)
(remoteDomainMemoryStats): Likewise.
* src/qemu/qemu_process.c (qemuProcessGetVolumeQcowPassphrase):
Likewise.
* src/qemu/qemu_driver.c (qemudDomainMemoryStats): Likewise.
* daemon/remote.c (remoteDispatchDomainMemoryStats): Likewise.
---
v4: fix even more public libvirt API flag masking
v3 at https://www.redhat.com/archives/libvir-list/2011-July/msg00894.html
daemon/remote.c | 2 +-
src/conf/domain_conf.c | 16 +++++++++----
src/conf/domain_conf.h | 10 --------
src/driver.c | 4 ---
src/driver.h | 16 +++++--------
src/interface/netcf_driver.c | 2 +
src/libvirt.c | 51 +++++------------------------------------
src/qemu/qemu_driver.c | 5 +++-
src/qemu/qemu_process.c | 2 +-
src/remote/remote_driver.c | 13 ++++++++--
src/secret/secret_driver.c | 7 ++++-
11 files changed, 47 insertions(+), 81 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index e93a0dc..daad39d 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -810,7 +810,7 @@ remoteDispatchDomainMemoryStats(virNetServerPtr server ATTRIBUTE_UNUSED,
goto cleanup;
}
- nr_stats = virDomainMemoryStats(dom, stats, args->maxStats, 0);
+ nr_stats = virDomainMemoryStats(dom, stats, args->maxStats, args->flags);
if (nr_stats < 0)
goto cleanup;
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8c3e44e..3c3ab39 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -48,7 +48,6 @@
#include "storage_file.h"
#include "files.h"
#include "bitmap.h"
-#include "verify.h"
#include "count-one-bits.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN
@@ -57,6 +56,12 @@
* verify that it doesn't overflow an unsigned int when shifting */
verify(VIR_DOMAIN_VIRT_LAST <= 32);
+/* Private flag used internally by virDomainSaveStatus and
+ * virDomainObjParseFile. */
+typedef enum {
+ VIR_DOMAIN_XML_INTERNAL_STATUS = (1<<16), /* dump internal domain status information */
+} virDomainXMLInternalFlags;
+
VIR_ENUM_IMPL(virDomainTaint, VIR_DOMAIN_TAINT_LAST,
"custom-argv",
"custom-monitor",
@@ -6995,10 +7000,11 @@ cleanup:
}
-virDomainObjPtr virDomainObjParseFile(virCapsPtr caps,
- const char *filename,
- unsigned int expectedVirtTypes,
- unsigned int flags)
+static virDomainObjPtr
+virDomainObjParseFile(virCapsPtr caps,
+ const char *filename,
+ unsigned int expectedVirtTypes,
+ unsigned int flags)
{
xmlDocPtr xml;
virDomainObjPtr obj = NULL;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 172d3c2..7a3d72b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -41,11 +41,6 @@
# include "macvtap.h"
# include "sysinfo.h"
-/* Private component of virDomainXMLFlags */
-typedef enum {
- VIR_DOMAIN_XML_INTERNAL_STATUS = (1<<16), /* dump internal domain status information */
-} virDomainXMLInternalFlags;
-
/* Different types of hypervisor */
/* NB: Keep in sync with virDomainVirtTypeToString impl */
enum virDomainVirtType {
@@ -1417,11 +1412,6 @@ virDomainDefPtr virDomainDefParseNode(virCapsPtr caps,
unsigned int expectedVirtTypes,
unsigned int flags);
-virDomainObjPtr virDomainObjParseFile(virCapsPtr caps,
- const char *filename,
- unsigned int expectedVirtTypes,
- unsigned int flags);
-
bool virDomainDefCheckABIStability(virDomainDefPtr src,
virDomainDefPtr dst);
diff --git a/src/driver.c b/src/driver.c
index 579c2b3..5034277 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -32,10 +32,6 @@
#define DEFAULT_DRIVER_DIR LIBDIR "/libvirt/connection-driver"
-/* Make sure ... INTERNAL_CALL cannot be set by the caller */
-verify((VIR_SECRET_GET_VALUE_INTERNAL_CALL &
- VIR_SECRET_GET_VALUE_FLAGS_MASK) == 0);
-
#ifdef WITH_DRIVER_MODULES
/* XXX re-implment this for other OS, or use libtools helper lib ? */
diff --git a/src/driver.h b/src/driver.h
index 70ea4c2..9d0d3de 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -191,7 +191,7 @@ typedef char *
unsigned int flags);
typedef char *
(*virDrvDomainGetXMLDesc) (virDomainPtr dom,
- unsigned int flags);
+ unsigned int flags);
typedef char *
(*virDrvConnectDomainXMLFromNative) (virConnectPtr conn,
const char *nativeFormat,
@@ -331,7 +331,8 @@ typedef int
(*virDrvDomainMemoryStats)
(virDomainPtr domain,
struct _virDomainMemoryStat *stats,
- unsigned int nr_stats);
+ unsigned int nr_stats,
+ unsigned int flags);
typedef int
(*virDrvDomainBlockPeek)
@@ -1229,16 +1230,10 @@ struct _virDeviceMonitor {
virDrvNodeDeviceDestroy deviceDestroy;
};
-/* bits 16 and above of virDomainXMLFlags are for internal use */
-# define VIR_DOMAIN_XML_FLAGS_MASK 0xffff
-
-/* Bits 16 and above of virSecretGetValue flags are for internal use */
-# define VIR_SECRET_GET_VALUE_FLAGS_MASK 0xffff
-
enum {
/* This getValue call is inside libvirt, override the "private" flag.
This flag cannot be set by outside callers. */
- VIR_SECRET_GET_VALUE_INTERNAL_CALL = 1 << 16
+ VIR_SECRET_GET_VALUE_INTERNAL_CALL = 1 << 0,
};
typedef virSecretPtr
@@ -1263,7 +1258,8 @@ typedef int
typedef unsigned char *
(*virDrvSecretGetValue) (virSecretPtr secret,
size_t *value_size,
- unsigned int flags);
+ unsigned int flags,
+ unsigned int internalFlags);
typedef int
(*virDrvSecretUndefine) (virSecretPtr secret);
typedef int
diff --git a/src/interface/netcf_driver.c b/src/interface/netcf_driver.c
index 855b5a3..2f322b4 100644
--- a/src/interface/netcf_driver.c
+++ b/src/interface/netcf_driver.c
@@ -344,6 +344,8 @@ static char *interfaceGetXMLDesc(virInterfacePtr ifinfo,
virInterfaceDefPtr ifacedef = NULL;
char *ret = NULL;
+ virCheckFlags(VIR_INTERFACE_XML_INACTIVE, NULL);
+
interfaceDriverLock(driver);
iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo);
diff --git a/src/libvirt.c b/src/libvirt.c
index 7c68bd8..4de718d 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -3381,8 +3381,6 @@ virDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
goto error;
}
- flags &= VIR_DOMAIN_XML_FLAGS_MASK;
-
if (conn->driver->domainGetXMLDesc) {
char *ret;
ret = conn->driver->domainGetXMLDesc(domain, flags);
@@ -6031,11 +6029,6 @@ int virDomainMemoryStats (virDomainPtr dom, virDomainMemoryStatPtr stats,
virDispatchError(NULL);
return -1;
}
- if (flags != 0) {
- virLibDomainError(VIR_ERR_INVALID_ARG,
- _("flags must be zero"));
- goto error;
- }
if (!stats || nr_stats == 0)
return 0;
@@ -6045,7 +6038,8 @@ int virDomainMemoryStats (virDomainPtr dom, virDomainMemoryStatPtr stats,
conn = dom->conn;
if (conn->driver->domainMemoryStats) {
- nr_stats_ret = conn->driver->domainMemoryStats (dom, stats, nr_stats);
+ nr_stats_ret = conn->driver->domainMemoryStats (dom, stats, nr_stats,
+ flags);
if (nr_stats_ret == -1)
goto error;
return nr_stats_ret;
@@ -6130,12 +6124,6 @@ virDomainBlockPeek (virDomainPtr dom,
goto error;
}
- if (flags != 0) {
- virLibDomainError(VIR_ERR_INVALID_ARG,
- _("flags must be zero"));
- goto error;
- }
-
/* Allow size == 0 as an access test. */
if (size > 0 && !buffer) {
virLibDomainError(VIR_ERR_INVALID_ARG,
@@ -6239,9 +6227,10 @@ virDomainMemoryPeek (virDomainPtr dom,
* because of incompatible licensing.
*/
- if (flags != VIR_MEMORY_VIRTUAL && flags != VIR_MEMORY_PHYSICAL) {
+ /* Exactly one of these two flags must be set. */
+ if (!(flags & VIR_MEMORY_VIRTUAL) == !(flags & VIR_MEMORY_PHYSICAL)) {
virLibDomainError(VIR_ERR_INVALID_ARG,
- _("flags parameter must be VIR_MEMORY_VIRTUAL or VIR_MEMORY_PHYSICAL"));
+ _("flags parameter must include VIR_MEMORY_VIRTUAL or VIR_MEMORY_PHYSICAL"));
goto error;
}
@@ -8465,10 +8454,6 @@ virNetworkGetXMLDesc(virNetworkPtr network, unsigned int flags)
virDispatchError(NULL);
return NULL;
}
- if (flags != 0) {
- virLibNetworkError(VIR_ERR_INVALID_ARG, __FUNCTION__);
- goto error;
- }
conn = network->conn;
@@ -8978,10 +8963,6 @@ virInterfaceGetXMLDesc(virInterfacePtr iface, unsigned int flags)
virDispatchError(NULL);
return NULL;
}
- if ((flags & ~VIR_INTERFACE_XML_INACTIVE) != 0) {
- virLibInterfaceError(VIR_ERR_INVALID_ARG, __FUNCTION__);
- goto error;
- }
conn = iface->conn;
@@ -10451,10 +10432,6 @@ virStoragePoolGetXMLDesc(virStoragePoolPtr pool,
virDispatchError(NULL);
return NULL;
}
- if (flags != 0) {
- virLibStoragePoolError(VIR_ERR_INVALID_ARG, __FUNCTION__);
- goto error;
- }
conn = pool->conn;
@@ -11349,10 +11326,6 @@ virStorageVolGetXMLDesc(virStorageVolPtr vol,
virDispatchError(NULL);
return NULL;
}
- if (flags != 0) {
- virLibStorageVolError(VIR_ERR_INVALID_ARG, __FUNCTION__);
- goto error;
- }
conn = vol->conn;
@@ -11441,10 +11414,6 @@ virNodeNumOfDevices(virConnectPtr conn, const char *cap, unsigned int flags)
virDispatchError(NULL);
return -1;
}
- if (flags != 0) {
- virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__);
- goto error;
- }
if (conn->deviceMonitor && conn->deviceMonitor->numOfDevices) {
int ret;
@@ -11493,7 +11462,7 @@ virNodeListDevices(virConnectPtr conn,
virDispatchError(NULL);
return -1;
}
- if ((flags != 0) || (names == NULL) || (maxnames < 0)) {
+ if ((names == NULL) || (maxnames < 0)) {
virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
@@ -12699,12 +12668,10 @@ virSecretGetValue(virSecretPtr secret, size_t *value_size, unsigned int flags)
goto error;
}
- flags &= VIR_SECRET_GET_VALUE_FLAGS_MASK;
-
if (conn->secretDriver != NULL && conn->secretDriver->getValue != NULL) {
unsigned char *ret;
- ret = conn->secretDriver->getValue(secret, value_size, flags);
+ ret = conn->secretDriver->getValue(secret, value_size, flags, 0);
if (ret == NULL)
goto error;
return ret;
@@ -14233,10 +14200,6 @@ virNWFilterGetXMLDesc(virNWFilterPtr nwfilter, unsigned int flags)
virDispatchError(NULL);
return NULL;
}
- if (flags != 0) {
- virLibNWFilterError(VIR_ERR_INVALID_ARG, __FUNCTION__);
- goto error;
- }
conn = nwfilter->conn;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8d146aa..1a3fbfb 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6155,12 +6155,15 @@ qemudDomainInterfaceStats (virDomainPtr dom,
static int
qemudDomainMemoryStats (virDomainPtr dom,
struct _virDomainMemoryStat *stats,
- unsigned int nr_stats)
+ unsigned int nr_stats,
+ unsigned int flags)
{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
unsigned int ret = -1;
+ virCheckFlags(0, -1);
+
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
qemuDriverUnlock(driver);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d0085e0..448b06e 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -276,7 +276,7 @@ qemuProcessGetVolumeQcowPassphrase(virConnectPtr conn,
enc->secrets[0]->uuid);
if (secret == NULL)
goto cleanup;
- data = conn->secretDriver->getValue(secret, &size,
+ data = conn->secretDriver->getValue(secret, &size, 0,
VIR_SECRET_GET_VALUE_INTERNAL_CALL);
virUnrefSecret(secret);
if (data == NULL)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 2d5dc15..c2f8bbd 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -1850,7 +1850,8 @@ done:
static int
remoteDomainMemoryStats (virDomainPtr domain,
struct _virDomainMemoryStat *stats,
- unsigned int nr_stats)
+ unsigned int nr_stats,
+ unsigned int flags)
{
int rv = -1;
remote_domain_memory_stats_args args;
@@ -1868,7 +1869,7 @@ remoteDomainMemoryStats (virDomainPtr domain,
goto done;
}
args.maxStats = nr_stats;
- args.flags = 0;
+ args.flags = flags;
memset (&ret, 0, sizeof ret);
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MEMORY_STATS,
@@ -3173,7 +3174,7 @@ remoteSecretClose (virConnectPtr conn)
static unsigned char *
remoteSecretGetValue (virSecretPtr secret, size_t *value_size,
- unsigned int flags)
+ unsigned int flags, unsigned int internalFlags)
{
unsigned char *rv = NULL;
remote_secret_get_value_args args;
@@ -3182,6 +3183,12 @@ remoteSecretGetValue (virSecretPtr secret, size_t *value_size,
remoteDriverLock (priv);
+ /* internalFlags intentionally do not go over the wire */
+ if (internalFlags) {
+ remoteError(VIR_ERR_NO_SUPPORT, "%s", _("no internalFlags support"));
+ goto done;
+ }
+
make_nonnull_secret (&args.secret, secret);
args.flags = flags;
diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
index c45ba51..02cdbb9 100644
--- a/src/secret/secret_driver.c
+++ b/src/secret/secret_driver.c
@@ -873,12 +873,15 @@ cleanup:
}
static unsigned char *
-secretGetValue(virSecretPtr obj, size_t *value_size, unsigned int flags)
+secretGetValue(virSecretPtr obj, size_t *value_size, unsigned int flags,
+ unsigned int internalFlags)
{
virSecretDriverStatePtr driver = obj->conn->secretPrivateData;
unsigned char *ret = NULL;
virSecretEntryPtr secret;
+ virCheckFlags(0, NULL);
+
secretDriverLock(driver);
secret = secretFindByUUID(driver, obj->uuid);
@@ -898,7 +901,7 @@ secretGetValue(virSecretPtr obj, size_t *value_size, unsigned int flags)
goto cleanup;
}
- if ((flags & VIR_SECRET_GET_VALUE_INTERNAL_CALL) == 0 &&
+ if ((internalFlags & VIR_SECRET_GET_VALUE_INTERNAL_CALL) == 0 &&
secret->def->private) {
virSecretReportError(VIR_ERR_OPERATION_DENIED, "%s",
_("secret is private"));
--
1.7.4.4
13 years, 10 months
[libvirt] [PATCH v2 0/5] delete volumes while it is building
by Guannan Ren
This is the version 2 of patches for deleting volume while it is being built.
based on the first version: https://www.redhat.com/archives/libvir-list/2011-July/msg00535.html.
The patches is an attempt to spawn a new thread for volume building in storageVolumeCreateXML(),
then, the initial thread is waiting for the cancelling signal from storageVolumeDelete().
When it gets the signal, it uses pthread_cancel() to stop the process of volume building, then tell
storageVolumeDelete() to continue its job.
I go through the codes in other parts of libvirt briefly, such as nodedevice, network. It is rare
to spawn a new thread, so this worth a shot or probably not.
Any idea is appreciated.
13 years, 10 months
[libvirt] The future of virDomainBlockCopy API
by Jiri Denemark
Hi,
With the current changes of block copy implementation in qemu (which was
dropped in favor of using image streaming and snapshots to do the job) I think
it's best not to include virDomainBlockCopy API in libvirt (yet). This is for
several reasons:
- the ideal semantics of virDomainBlockCopy API would be a no-op in case of
failure, which can't be achieved with snapshot/image streaming combo since
the domain is switched to the new image before any copying starts instead of
when everything is finished
- since monitor/cancellation APIs are designed with future block operations in
mind, it will be easy to provide virDomainBlockCopy in the future if we feel
the need for it
- with BlockPull and Snapshot APIs in place, users/apps can do block copy by
creating a snapshot of a disk and running BlockPull on it to make the new
image independent on the original disk image
- the two phase process makes it easy to resume image streaming in case it
failed for a recoverable reason
With current (WIP) snapshot support, one would use virDomainSnapshotCreateXML
asking for a disk snapshot only (no memory) with the following XML:
<domainsnapshot>
<name>whatever</name>
<disk name='/path/to/image1' snapshot='no'/>
<disk name='/path/to/image2' snapshot='yes'>
<volsnapshot>
<name>disk snapshot name</name>
<image name='/another/path/to/image2.new'/>
</volsnapshot>
</disk>
</domainsnapshot>
This will switch the domain to /another/path/to/image2.new with
/path/to/image2 as its backing store. The new image can then be made
independent on its backing store by calling virDomainBlockPull on it.
Jirka
13 years, 10 months
Re: [libvirt] [PATCH] virsh: Expose virDomainMigrateSetMaxSpeed API to virsh
by Hui Kang
Hi,
I checked the libvirt git tree. It seems that this patch has not been applied.
I think to use virsh command line to control the migration bandwidth is useful. Thanks.
- Hui
API virDomainMigrateSetMaxSpeed was introduced since 0.9.0, but
no command in virsh yet.
---
tools/virsh.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
tools/virsh.pod | 5 +++++
2 files changed, 51 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index d98be1c..ab83ba9 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -4301,6 +4301,50 @@ done:
}
/*
+ * "migrate-setspeed" command
+ */
+static const vshCmdInfo info_migrate_setspeed[] = {
+ {"help", N_("Set the maximum migration bandwidth")},
+ {"desc", N_("Set the maximum migration bandwidth (in Mbps) for a domain "
+ "which is being migrated to another host.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_migrate_setspeed[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
+ {"bandwidth", VSH_OT_INT, VSH_OFLAG_REQ, N_("migration bandwidth limit in Mbps")},
+ {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdMigrateSetMaxSpeed(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ unsigned long bandwidth = 0;
+ bool ret = false;
+
+ if (!vshConnectionUsability(ctl, ctl->conn))
+ return false;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+ return false;
+
+ if (vshCommandOptUL(cmd, "bandwidth", &bandwidth) < 0) {
+ vshError(ctl, "%s", _("migrate: Invalid bandwidth"));
+ goto done;
+ }
+
+ if (virDomainMigrateSetMaxSpeed(dom, bandwidth, 0) < 0)
+ goto done;
+
+ ret = true;
+
+done:
+ virDomainFree(dom);
+ return ret;
+}
+
+/*
* "net-autostart" command
*/
static const vshCmdInfo info_network_autostart[] = {
@@ -11080,6 +11124,8 @@ static const vshCmdDef domManagementCmds[] = {
{"migrate", cmdMigrate, opts_migrate, info_migrate, 0},
{"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime,
opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime, 0},
+ {"migrate-setspeed", cmdMigrateSetMaxSpeed,
+ opts_migrate_setspeed, info_migrate_setspeed, 0},
{"reboot", cmdReboot, opts_reboot, info_reboot, 0},
{"restore", cmdRestore, opts_restore, info_restore, 0},
{"resume", cmdResume, opts_resume, info_resume, 0},
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 7ed3003..98adc90 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -542,6 +542,11 @@ Set maximum tolerable downtime for a domain which is being live-migrated to
another host. The I<downtime> is a number of milliseconds the guest is allowed
to be down at the end of live migration.
+=item B<migrate-setspeed> I<domain-id> I<bandwidth>
+
+Set the maximum migration bandwidth (in Mbps) for a domain which is being
+migrated to another host.
+
=item B<reboot> I<domain-id>
Reboot a domain. This acts just as if the domain had the B<reboot>
--
1.7.4
13 years, 10 months
[libvirt] [PATCH] virsh: avoid double free of domain
by ajia@redhat.com
From: Alex Jia <ajia(a)redhat.com>
* tools/virsh.c: avoid double free of domain, when weight value of blkiotune
less than 0, codes will free domain and jump to cleanup section, however,
cleanup will free domain again.
Detected in valgrind run:
==21297== ERROR SUMMARY: 20 errors from 20 contexts (suppressed: 69 from 8)
==21297==
==21297== 1 errors in context 1 of 20:
==21297== Invalid read of size 4
==21297== at 0x40E209B: virDomainFree (libvirt.c:2096)
==21297== by 0x8065274: cmdBlkiotune (virsh.c:3695)
==21297== by 0x8054CC1: vshCommandRun (virsh.c:13135)
==21297== by 0x806B967: main (virsh.c:14487)
==21297== Address 0x446ad48 is 0 bytes inside a block of size 36 free'd
==21297== at 0x4005B0A: free (vg_replace_malloc.c:325)
==21297== by 0x406814D: virFree (memory.c:310)
==21297== by 0x40D6635: virReleaseDomain (datatypes.c:243)
==21297== by 0x40D6C5E: virUnrefDomain (datatypes.c:280)
==21297== by 0x40E20B9: virDomainFree (libvirt.c:2101)
==21297== by 0x8065297: cmdBlkiotune (virsh.c:3613)
==21297== by 0x8054CC1: vshCommandRun (virsh.c:13135)
==21297== by 0x806B967: main (virsh.c:14487)
==21297==
==21297==
==21297== 1 errors in context 2 of 20:
==21297== Invalid read of size 4
==21297== at 0x40E1FE6: virDomainFree (libvirt.c:2092)
==21297== by 0x8065274: cmdBlkiotune (virsh.c:3695)
==21297== by 0x8054CC1: vshCommandRun (virsh.c:13135)
==21297== by 0x806B967: main (virsh.c:14487)
==21297== Address 0x446ad48 is 0 bytes inside a block of size 36 free'd
==21297== at 0x4005B0A: free (vg_replace_malloc.c:325)
==21297== by 0x406814D: virFree (memory.c:310)
==21297== by 0x40D6635: virReleaseDomain (datatypes.c:243)
==21297== by 0x40D6C5E: virUnrefDomain (datatypes.c:280)
==21297== by 0x40E20B9: virDomainFree (libvirt.c:2101)
==21297== by 0x8065297: cmdBlkiotune (virsh.c:3613)
==21297== by 0x8054CC1: vshCommandRun (virsh.c:13135)
==21297== by 0x806B967: main (virsh.c:14487)
* how to reproduce?
% valgrind -v --leak-check=full virsh blkiotune guestname --weight -1
---
tools/virsh.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index e75a249..cba249a 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -3610,7 +3610,6 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd)
if (weight) {
nparams++;
if (weight < 0) {
- virDomainFree(dom);
vshError(ctl, _("Invalid value of %d for I/O weight"), weight);
goto cleanup;
}
--
1.7.3.4
13 years, 10 months
[libvirt] virsh vcpucount problem
by Eric Blake
Right now, 'virsh vcpucount' understands --current differently than all
other commands that understand --current. That is, --current is not a
synonym for whichever of --live or --config matches the current domain
state, but a counterpart of --maximum.
I'm about to teach VIR_AFFECT_CURRENT to the virDomainGetVcpusFlags
command. Do we fix 'virsh vcpucount --current' to map to this new flag
and come up with a new option that means the opposite of --maximum, or
do we just leave the virsh interface stuck the way it is?
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
13 years, 10 months
[libvirt] [PATCH] build: Fix protocol-structs generation in VPATH build
by Jiri Denemark
$@ already included $(srcdir)
---
src/Makefile.am | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 54b1ca0..94a9a43 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -241,7 +241,7 @@ PDWTAGS = \
-e '}' \
> $@-t; \
case $$? in 8) exit 0;; 0) ;; *) exit 1;; esac; \
- diff -u $@-t $(srcdir)/$@; st=$$?; rm -f $@-t; exit $$st; \
+ diff -u $@-t $@; st=$$?; rm -f $@-t; exit $$st; \
else \
echo 'WARNING: you lack pdwtags; skipping the $@ test' >&2; \
echo 'WARNING: install the dwarves package to get pdwtags' >&2; \
--
1.7.6
13 years, 10 months