[libvirt] [libvirt-glib] Add virStorageVolResize()
by Zeeshan Ali (Khattak)
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
Add a new function to allow changing of capacity of storage volumes.
---
include/libvirt/libvirt.h.in | 5 ++
src/driver.h | 5 ++
src/libvirt.c | 50 ++++++++++++++++++
src/libvirt_public.syms | 1 +
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 9 +++-
src/remote_protocol-structs | 6 ++
src/storage/storage_backend.h | 6 ++
src/storage/storage_backend_fs.c | 18 +++++++
src/storage/storage_driver.c | 83 ++++++++++++++++++++++++++++++
src/util/storage_file.c | 105 ++++++++++++++++++++++++++++++++++++++
src/util/storage_file.h | 4 ++
tools/virsh.c | 53 +++++++++++++++++++
13 files changed, 345 insertions(+), 1 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index e99cd00..b169592 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2386,6 +2386,11 @@ char * virStorageVolGetXMLDesc (virStorageVolPtr pool,
char * virStorageVolGetPath (virStorageVolPtr vol);
+int virStorageVolResize (virStorageVolPtr vol,
+ unsigned long long capacity,
+ unsigned int flags);
+
+
/**
* virKeycodeSet:
*
diff --git a/src/driver.h b/src/driver.h
index df2aa60..c850926 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -1261,6 +1261,10 @@ typedef int
unsigned long long offset,
unsigned long long length,
unsigned int flags);
+typedef int
+ (*virDrvStorageVolResize) (virStorageVolPtr vol,
+ unsigned long long capacity,
+ unsigned int flags);
typedef int
(*virDrvStoragePoolIsActive)(virStoragePoolPtr pool);
@@ -1323,6 +1327,7 @@ struct _virStorageDriver {
virDrvStorageVolGetInfo volGetInfo;
virDrvStorageVolGetXMLDesc volGetXMLDesc;
virDrvStorageVolGetPath volGetPath;
+ virDrvStorageVolResize volResize;
virDrvStoragePoolIsActive poolIsActive;
virDrvStoragePoolIsPersistent poolIsPersistent;
};
diff --git a/src/libvirt.c b/src/libvirt.c
index e9d638b..44865e8 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -12927,6 +12927,56 @@ error:
return NULL;
}
+/**
+ * virStorageVolResize:
+ * @vol: pointer to storage volume
+ * @capacity: new capacity
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Changes the capacity of the storage volume @vol to @capacity. The new
+ * capacity must not exceed the sum of current capacity of the volume and
+ * remainining free space of its parent pool. Also the new capacity must
+ * be greater than or equal to current allocation of the volume.
+ *
+ * Returns 0 on success, or -1 on error.
+ */
+int
+virStorageVolResize(virStorageVolPtr vol,
+ unsigned long long capacity,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+ VIR_DEBUG("vol=%p", vol);
+
+ virResetLastError();
+
+ if (!VIR_IS_STORAGE_VOL(vol)) {
+ virLibStorageVolError(VIR_ERR_INVALID_STORAGE_VOL, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ conn = vol->conn;
+
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->storageDriver && conn->storageDriver->volResize) {
+ int ret;
+ ret = conn->storageDriver->volResize(vol, capacity, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(vol->conn);
+ return -1;
+}
/**
* virNodeNumOfDevices:
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 1340b0c..67c113e 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -520,6 +520,7 @@ LIBVIRT_0.9.10 {
global:
virDomainShutdownFlags;
virStorageVolWipePattern;
+ virStorageVolResize;
} LIBVIRT_0.9.9;
# .... define new API here using predicted next version number ....
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index f79f53e..2bb4cbf 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -4837,6 +4837,7 @@ static virStorageDriver storage_driver = {
.volGetInfo = remoteStorageVolGetInfo, /* 0.4.1 */
.volGetXMLDesc = remoteStorageVolGetXMLDesc, /* 0.4.1 */
.volGetPath = remoteStorageVolGetPath, /* 0.4.1 */
+ .volResize = remoteStorageVolResize, /* 0.9.10 */
.poolIsActive = remoteStoragePoolIsActive, /* 0.7.3 */
.poolIsPersistent = remoteStoragePoolIsPersistent, /* 0.7.3 */
};
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 0f354bb..29f98fc 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -1676,6 +1676,12 @@ struct remote_storage_vol_get_path_ret {
remote_nonnull_string name;
};
+struct remote_storage_vol_resize_args {
+ remote_nonnull_storage_vol vol;
+ unsigned hyper capacity;
+ unsigned int flags;
+};
+
/* Node driver calls: */
struct remote_node_num_of_devices_args {
@@ -2667,7 +2673,8 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SET_INTERFACE_PARAMETERS = 256, /* autogen autogen */
REMOTE_PROC_DOMAIN_GET_INTERFACE_PARAMETERS = 257, /* skipgen skipgen */
REMOTE_PROC_DOMAIN_SHUTDOWN_FLAGS = 258, /* autogen autogen */
- REMOTE_PROC_STORAGE_VOL_WIPE_PATTERN = 259 /* autogen autogen */
+ REMOTE_PROC_STORAGE_VOL_WIPE_PATTERN = 259, /* autogen autogen */
+ REMOTE_PROC_STORAGE_VOL_RESIZE = 300 /* autogen autogen */
/*
* Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index de85862..9a60fc2 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1260,6 +1260,11 @@ struct remote_storage_vol_get_path_args {
struct remote_storage_vol_get_path_ret {
remote_nonnull_string name;
};
+struct remote_storage_vol_resize_args {
+ remote_nonnull_storage_vol vol;
+ uint64_t capacity;
+ u_int flags;
+};
struct remote_node_num_of_devices_args {
remote_string cap;
u_int flags;
@@ -2101,4 +2106,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_GET_INTERFACE_PARAMETERS = 257,
REMOTE_PROC_DOMAIN_SHUTDOWN_FLAGS = 258,
REMOTE_PROC_STORAGE_VOL_WIPE_PATTERN = 259,
+ REMOTE_PROC_STORAGE_VOL_RESIZE = 300,
};
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
index 75ed676..a37bf7c 100644
--- a/src/storage/storage_backend.h
+++ b/src/storage/storage_backend.h
@@ -44,6 +44,11 @@ typedef int (*virStorageBackendDeleteVol)(virConnectPtr conn, virStoragePoolObjP
typedef int (*virStorageBackendBuildVolFrom)(virConnectPtr conn, virStoragePoolObjPtr pool,
virStorageVolDefPtr origvol, virStorageVolDefPtr newvol,
unsigned int flags);
+typedef int (*virStorageBackendVolumeResize)(virConnectPtr conn,
+ virStoragePoolObjPtr pool,
+ virStorageVolDefPtr vol,
+ unsigned long long capacity,
+ unsigned int flags);
/* File creation/cloning functions used for cloning between backends */
int virStorageBackendCreateRaw(virConnectPtr conn,
@@ -78,6 +83,7 @@ struct _virStorageBackend {
virStorageBackendCreateVol createVol;
virStorageBackendRefreshVol refreshVol;
virStorageBackendDeleteVol deleteVol;
+ virStorageBackendVolumeResize resizeVol;
};
virStorageBackendPtr virStorageBackendForType(int type);
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index d8dc29c..20f5534 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -1187,6 +1187,21 @@ virStorageBackendFileSystemVolRefresh(virConnectPtr conn,
return 0;
}
+/**
+ * Resize a volume
+ */
+static int
+virStorageBackendFileSystemVolResize(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
+ virStorageVolDefPtr vol,
+ unsigned long long capacity,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ return virStorageFileResize(vol->target.path,
+ vol->target.format,
+ capacity);
+}
+
virStorageBackend virStorageBackendDirectory = {
.type = VIR_STORAGE_POOL_DIR,
@@ -1199,6 +1214,7 @@ virStorageBackend virStorageBackendDirectory = {
.createVol = virStorageBackendFileSystemVolCreate,
.refreshVol = virStorageBackendFileSystemVolRefresh,
.deleteVol = virStorageBackendFileSystemVolDelete,
+ .resizeVol = virStorageBackendFileSystemVolResize,
};
#if WITH_STORAGE_FS
@@ -1216,6 +1232,7 @@ virStorageBackend virStorageBackendFileSystem = {
.createVol = virStorageBackendFileSystemVolCreate,
.refreshVol = virStorageBackendFileSystemVolRefresh,
.deleteVol = virStorageBackendFileSystemVolDelete,
+ .resizeVol = virStorageBackendFileSystemVolResize,
};
virStorageBackend virStorageBackendNetFileSystem = {
.type = VIR_STORAGE_POOL_NETFS,
@@ -1232,5 +1249,6 @@ virStorageBackend virStorageBackendNetFileSystem = {
.createVol = virStorageBackendFileSystemVolCreate,
.refreshVol = virStorageBackendFileSystemVolRefresh,
.deleteVol = virStorageBackendFileSystemVolDelete,
+ .resizeVol = virStorageBackendFileSystemVolResize,
};
#endif /* WITH_STORAGE_FS */
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index a332ada..d3eff93 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -1695,7 +1695,89 @@ out:
return ret;
}
+static int
+storageVolumeResize(virStorageVolPtr obj,
+ unsigned long long capacity,
+ unsigned int flags)
+{
+ virStorageDriverStatePtr driver = obj->conn->storagePrivateData;
+ virStorageBackendPtr backend;
+ virStoragePoolObjPtr pool = NULL;
+ virStorageVolDefPtr vol = NULL;
+ int ret = -1;
+
+ virCheckFlags(0, -1);
+
+ storageDriverLock(driver);
+ pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
+ storageDriverUnlock(driver);
+ if (!pool) {
+ virStorageReportError(VIR_ERR_NO_STORAGE_POOL,
+ "%s", _("no storage pool with matching uuid"));
+ goto out;
+ }
+
+ if (!virStoragePoolObjIsActive(pool)) {
+ virStorageReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("storage pool is not active"));
+ goto out;
+ }
+
+ if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
+ goto out;
+
+ vol = virStorageVolDefFindByName(pool, obj->name);
+
+ if (vol == NULL) {
+ virStorageReportError(VIR_ERR_NO_STORAGE_VOL,
+ _("no storage vol with matching name '%s'"),
+ obj->name);
+ goto out;
+ }
+
+ if (vol->building) {
+ virStorageReportError(VIR_ERR_OPERATION_INVALID,
+ _("volume '%s' is still being allocated."),
+ vol->name);
+ goto out;
+ }
+
+ if (capacity < vol->allocation) {
+ virStorageReportError(VIR_ERR_INVALID_ARG,
+ "%s", _("can not shrink capacity below "
+ "existing allocation"));
+
+ goto out;
+ }
+
+ if (capacity > vol->allocation + pool->def->available) {
+ virStorageReportError(VIR_ERR_INVALID_ARG,
+ "%s", _("Not enough space left on storage pool"));
+
+ goto out;
+ }
+
+ if (!backend->resizeVol) {
+ virStorageReportError(VIR_ERR_NO_SUPPORT,
+ "%s", _("storage pool does not support changing "
+ "of volume capacity"));
+
+ goto out;
+ }
+
+ if (backend->resizeVol(obj->conn, pool, vol, capacity, flags) < 0)
+ goto out;
+
+ vol->capacity = capacity;
+ ret = 0;
+
+out:
+ if (pool)
+ virStoragePoolObjUnlock(pool);
+
+ return ret;
+}
/* If the volume we're wiping is already a sparse file, we simply
* truncate and extend it to its original size, filling it with
@@ -2243,6 +2325,7 @@ static virStorageDriver storageDriver = {
.volGetInfo = storageVolumeGetInfo, /* 0.4.0 */
.volGetXMLDesc = storageVolumeGetXMLDesc, /* 0.4.0 */
.volGetPath = storageVolumeGetPath, /* 0.4.0 */
+ .volResize = storageVolumeResize, /* 0.9.10 */
.poolIsActive = storagePoolIsActive, /* 0.7.3 */
.poolIsPersistent = storagePoolIsPersistent, /* 0.7.3 */
diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index ba9cfc5..f84feab 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -931,6 +931,111 @@ virStorageFileFreeMetadata(virStorageFileMetadata *meta)
VIR_FREE(meta);
}
+static int
+virStorageFileResizeForFD(const char *path,
+ int fd,
+ int format,
+ unsigned long long capacity)
+{
+ unsigned char *head = NULL;
+ ssize_t len = STORAGE_MAX_HEAD;
+ int ret = -1;
+ struct stat sb;
+
+ if (fstat(fd, &sb) < 0) {
+ virReportSystemError(errno,
+ _("cannot stat file '%s'"),
+ path);
+ return -1;
+ }
+
+ /* No header to probe for directories */
+ if (S_ISDIR(sb.st_mode)) {
+ return 0;
+ }
+
+ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
+ virReportSystemError(errno, _("cannot seek to start of '%s'"), path);
+ return -1;
+ }
+
+ if (VIR_ALLOC_N(head, len) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ if ((len = read(fd, head, len)) < 0) {
+ virReportSystemError(errno, _("cannot read header '%s'"), path);
+ goto cleanup;
+ }
+
+ if (format == VIR_STORAGE_FILE_AUTO)
+ format = virStorageFileProbeFormatFromBuf(path, head, len);
+
+ if (format < 0 ||
+ format >= VIR_STORAGE_FILE_LAST) {
+ virReportSystemError(EINVAL, _("unknown storage file format %d"),
+ format);
+ goto cleanup;
+ }
+
+ if (fileTypeInfo[format].sizeOffset != -1) {
+ unsigned long long *file_capacity;
+
+ if ((fileTypeInfo[format].sizeOffset + 8) > len)
+ return -1;
+
+ file_capacity = (unsigned long long *)(head + fileTypeInfo[format].sizeOffset);
+ if (fileTypeInfo[format].endian == LV_LITTLE_ENDIAN)
+ *file_capacity = htole64(capacity);
+ else
+ *file_capacity = htobe64(capacity);
+
+ *file_capacity /= fileTypeInfo[format].sizeMultiplier;
+ }
+
+ /* Move to start of file to write the header back with adjusted capacity */
+ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
+ virReportSystemError(errno, _("cannot seek to start of '%s'"), path);
+ return -1;
+ }
+
+ if ((len = write(fd, head, len)) < 0) {
+ virReportSystemError(errno, _("cannot write header '%s'"), path);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(head);
+ return ret;
+}
+
+/**
+ * virStorageFileResize:
+ *
+ * Change the capacity of the storage file at 'path'.
+ */
+int
+virStorageFileResize(const char *path,
+ int format,
+ unsigned long long capacity)
+{
+ int fd, ret;
+
+ if ((fd = open(path, O_RDWR)) < 0) {
+ virReportSystemError(errno, _("cannot open file '%s'"), path);
+ return -1;
+ }
+
+ ret = virStorageFileResizeForFD(path, fd, format, capacity);
+
+ VIR_FORCE_CLOSE(fd);
+
+ return ret;
+}
+
#ifdef __linux__
# ifndef NFS_SUPER_MAGIC
diff --git a/src/util/storage_file.h b/src/util/storage_file.h
index b8920d0..f6c6048 100644
--- a/src/util/storage_file.h
+++ b/src/util/storage_file.h
@@ -72,6 +72,10 @@ int virStorageFileGetMetadataFromFD(const char *path,
void virStorageFileFreeMetadata(virStorageFileMetadata *meta);
+int virStorageFileResize(const char *path,
+ int format,
+ unsigned long long capacity);
+
enum {
VIR_STORAGE_FILE_SHFS_NFS = (1 << 0),
VIR_STORAGE_FILE_SHFS_GFS2 = (1 << 1),
diff --git a/tools/virsh.c b/tools/virsh.c
index 74655c2..20d4bd0 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -11279,6 +11279,58 @@ cmdVolInfo(vshControl *ctl, const vshCmd *cmd)
return ret;
}
+/*
+ * "vol-resize" command
+ */
+static const vshCmdInfo info_vol_resize[] = {
+ {"help", N_("resize a vol")},
+ {"desc", N_("Resizes a storage vol.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_vol_resize[] = {
+ {"vol", VSH_OT_DATA, VSH_OFLAG_REQ, N_("vol name, key or path")},
+ {"capacity", VSH_OT_DATA, VSH_OFLAG_REQ, N_("new capacity for the vol with optional k,M,G,T suffix")},
+ {"pool", VSH_OT_STRING, 0, N_("pool name or uuid")},
+ {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdVolResize(vshControl *ctl, const vshCmd *cmd)
+{
+ virStorageVolPtr vol;
+ const char *capacityStr = NULL;
+ unsigned long long capacity = 0;
+ bool ret = true;
+
+ if (!vshConnectionUsability(ctl, ctl->conn))
+ return false;
+
+ if (!(vol = vshCommandOptVol(ctl, cmd, "vol", "pool", NULL)))
+ return false;
+
+ if (vshCommandOptString(cmd, "capacity", &capacityStr) <= 0)
+ goto cleanup;
+ if (cmdVolSize(capacityStr, &capacity) < 0) {
+ vshError(ctl, _("Malformed size %s"), capacityStr);
+ goto cleanup;
+ }
+
+ if (virStorageVolResize(vol, capacity, 0) == 0) {
+ vshPrint(ctl, "Size of volume '%s' successfully changed to %s\n",
+ virStorageVolGetName(vol), capacityStr);
+ ret = true;
+ } else {
+ vshError(ctl, "Failed to change size of volume '%s' to %s\n",
+ virStorageVolGetName(vol), capacityStr);
+ ret = false;
+ }
+
+cleanup:
+ virStorageVolFree(vol);
+ return ret;
+}
+
/*
* "vol-dumpxml" command
@@ -16141,6 +16193,7 @@ static const vshCmdDef storageVolCmds[] = {
{"vol-pool", cmdVolPool, opts_vol_pool, info_vol_pool, 0},
{"vol-upload", cmdVolUpload, opts_vol_upload, info_vol_upload, 0},
{"vol-wipe", cmdVolWipe, opts_vol_wipe, info_vol_wipe, 0},
+ {"vol-resize", cmdVolResize, opts_vol_resize, info_vol_resize, 0},
{NULL, NULL, NULL, NULL, 0}
};
--
1.7.7.5
13 years, 1 month
[libvirt] Feature Request: sniff a virtual interface of a guest
by Hendrik Schwartke
Hi,
there is currently no support for sniffing the network traffic of a virtual
nic, from local or remote. In some cases the debugging or monitoring of a guest
is therefore not as easy as it could be.
Although it's easy to start a network sniffer on the physical host, it requires
direct access to a shell and some knowledge of the current configuration of
the virtual networks.
I think it would be a great benefit for libvirt if network sniffing would be
possible out of the box.
One idea would be to start a local tshark sniffing on the card and connect this
to a local socket. This could then be forwarded by ssh to a wireshark process
running on a desktop.
I created a feature request for that: https://bugzilla.redhat.com/show_bug.cgi?id=784893
Any thoughts or hints to implement that?
Hendrik Schwartke
13 years, 1 month
[libvirt] [PATCH] simplify block of codes
by ajia@redhat.com
From: Alex Jia <ajia(a)redhat.com>
Using new function 'virTypedParameterArrayClear' to simplify block of codes.
* daemon/remote.c, src/remote/remote_driver.c: simplify codes.
Signed-off-by: Alex Jia <ajia(a)redhat.com>
---
daemon/remote.c | 10 ++--------
src/remote/remote_driver.c | 16 ++++------------
2 files changed, 6 insertions(+), 20 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index cb8423a..7e90bd7 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -847,14 +847,8 @@ remoteDeserializeTypedParameters(remote_typed_param *args_params_val,
rv = 0;
cleanup:
- if (rv < 0) {
- int j;
- for (j = 0; j < i; ++j) {
- if (params[j].type == VIR_TYPED_PARAM_STRING)
- VIR_FREE(params[j].value.s);
- }
- VIR_FREE(params);
- }
+ if (rv < 0)
+ virTypedParameterArrayClear(params, *nparams);
return params;
}
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 61b96e9..15a20ff 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -46,6 +46,7 @@
#include "virfile.h"
#include "command.h"
#include "intprops.h"
+#include "virtypedparam.h"
#define VIR_FROM_THIS VIR_FROM_REMOTE
@@ -1417,12 +1418,8 @@ remoteDeserializeTypedParameters(remote_typed_param *ret_params_val,
rv = 0;
cleanup:
- if (rv < 0) {
- int j;
- for (j = 0; j < i; j++)
- if (params[j].type == VIR_TYPED_PARAM_STRING)
- VIR_FREE(params[j].value.s);
- }
+ if (rv < 0)
+ virTypedParameterArrayClear(params, *nparams);
return rv;
}
@@ -2386,12 +2383,7 @@ static int remoteDomainGetCPUStats(virDomainPtr domain,
cleanup:
if (rv < 0) {
int max = nparams * ncpus;
- int i;
-
- for (i = 0; i < max; i++) {
- if (params[i].type == VIR_TYPED_PARAM_STRING)
- VIR_FREE(params[i].value.s);
- }
+ virTypedParameterArrayClear(params, max);
}
xdr_free ((xdrproc_t) xdr_remote_domain_get_cpu_stats_ret,
(char *) &ret);
--
1.7.1
13 years, 1 month
[libvirt] [PATCHv2] network: Avoid memory leaks on networkBuildDnsmasqArgv
by ajia@redhat.com
From: Alex Jia <ajia(a)redhat.com>
Detected by valgrind. Leaks introduced in commit 973af236.
* src/network/bridge_driver.c: fix memory leaks on failure and successful path.
* How to reproduce?
% make -C tests check TESTS=networkxml2argvtest
% cd tests && valgrind -v --leak-check=full ./networkxml2argvtest
* Actual result:
==2226== 3 bytes in 1 blocks are definitely lost in loss record 1 of 24
==2226== at 0x4A05FDE: malloc (vg_replace_malloc.c:236)
==2226== by 0x39CF0FEDE7: __vasprintf_chk (in /lib64/libc-2.12.so)
==2226== by 0x41DFF7: virVasprintf (stdio2.h:199)
==2226== by 0x41E0B7: virAsprintf (util.c:1695)
==2226== by 0x41A2D9: networkBuildDhcpDaemonCommandLine (bridge_driver.c:545)
==2226== by 0x4145C8: testCompareXMLToArgvHelper (networkxml2argvtest.c:47)
==2226== by 0x4156A1: virtTestRun (testutils.c:141)
==2226== by 0x414332: mymain (networkxml2argvtest.c:123)
==2226== by 0x414D97: virtTestMain (testutils.c:696)
==2226== by 0x39CF01ECDC: (below main) (in /lib64/libc-2.12.so)
==2226==
==2226== 3 bytes in 1 blocks are definitely lost in loss record 2 of 24
==2226== at 0x4A05FDE: malloc (vg_replace_malloc.c:236)
==2226== by 0x39CF0FEDE7: __vasprintf_chk (in /lib64/libc-2.12.so)
==2226== by 0x41DFF7: virVasprintf (stdio2.h:199)
==2226== by 0x41E0B7: virAsprintf (util.c:1695)
==2226== by 0x41A307: networkBuildDhcpDaemonCommandLine (bridge_driver.c:551)
==2226== by 0x4145C8: testCompareXMLToArgvHelper (networkxml2argvtest.c:47)
==2226== by 0x4156A1: virtTestRun (testutils.c:141)
==2226== by 0x414332: mymain (networkxml2argvtest.c:123)
==2226== by 0x414D97: virtTestMain (testutils.c:696)
==2226== by 0x39CF01ECDC: (below main) (in /lib64/libc-2.12.so)
==2226==
==2226== 5 bytes in 1 blocks are definitely lost in loss record 4 of 24
==2226== at 0x4A05FDE: malloc (vg_replace_malloc.c:236)
==2226== by 0x39CF0FEDE7: __vasprintf_chk (in /lib64/libc-2.12.so)
==2226== by 0x41DFF7: virVasprintf (stdio2.h:199)
==2226== by 0x41E0B7: virAsprintf (util.c:1695)
==2226== by 0x41A2AB: networkBuildDhcpDaemonCommandLine (bridge_driver.c:539)
==2226== by 0x4145C8: testCompareXMLToArgvHelper (networkxml2argvtest.c:47)
==2226== by 0x4156A1: virtTestRun (testutils.c:141)
==2226== by 0x414332: mymain (networkxml2argvtest.c:123)
==2226== by 0x414D97: virtTestMain (testutils.c:696)
==2226== by 0x39CF01ECDC: (below main) (in /lib64/libc-2.12.so)
==2226==
==2226== LEAK SUMMARY:
==2226== definitely lost: 11 bytes in 3 blocks
Signed-off-by: Alex Jia <ajia(a)redhat.com>
---
src/network/bridge_driver.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 5d0d528..5bd5a50 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -459,6 +459,9 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
int r, ret = -1;
int nbleases = 0;
int ii;
+ char *recordPort = NULL;
+ char *recordPriority = NULL;
+ char *recordWeight = NULL;
virNetworkIpDefPtr tmpipdef;
/*
@@ -530,9 +533,6 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
for (i = 0; i < dns->nsrvrecords; i++) {
char *record = NULL;
- char *recordPort = NULL;
- char *recordPriority = NULL;
- char *recordWeight = NULL;
if (dns->srvrecords[i].service && dns->srvrecords[i].protocol) {
if (dns->srvrecords[i].port) {
@@ -671,6 +671,9 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
ret = 0;
cleanup:
+ VIR_FREE(recordPort);
+ VIR_FREE(recordWeight);
+ VIR_FREE(recordPriority);
return ret;
}
--
1.7.1
13 years, 2 months
[libvirt] Schedule for libvirt-0.9.10 release
by Daniel Veillard
First I don't see any good reason to try to bump the major release
number :-) so next release is expected to be 0.9.10, hope there isn't
disapointment ;-) [1]
Second I would really like to keep the monthly shedule, and have the
release done by February 6 or earlier, so this would mean entering the
0.9.10 freeze on Monday 30, i.e. in a bit less than two weeks.
I hope this is okay,
Daniel
[1] actually the addition of fine grained access control would be
a good reason for such a version bump
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
13 years, 2 months
[libvirt] [PATCH 0/4] API for modification of domain metadata
by Peter Krempa
This patchset is based on my previous work to add a domain title.
I chose a more general aproach to allow working with the <metadata>
element as suggested by Eric and Daniel, although I did not implement
the <metadata> operations code.
I only provided a patch for the qemu driver for review, but I'll follow
up with a patch for LXC as well as I'll have a final version of this.
Peter Krempa (4):
xml: Add element <title> to allow short description of domains
API: Add api to set and get domain metadata
virsh: Add support for modifying domain description and titles
qemu: Add support for virDomainGetMetadata and virDomainSetMetadata
docs/formatdomain.html.in | 6 +
docs/schemas/domaincommon.rng | 13 +-
include/libvirt/libvirt.h.in | 31 +++
include/libvirt/virterror.h | 1 +
src/conf/domain_conf.c | 19 ++
src/conf/domain_conf.h | 1 +
src/driver.h | 15 +
src/libvirt.c | 125 +++++++++
src/libvirt_public.syms | 2 +
src/qemu/qemu_driver.c | 195 ++++++++++++++
src/remote/remote_driver.c | 2 +
src/remote/remote_protocol.x | 25 ++-
src/util/virterror.c | 6 +
.../qemu-simple-description-title.xml | 27 ++
tests/qemuxml2argvdata/qemuxml2argv-minimal.xml | 5 +
tools/virsh.c | 274 ++++++++++++++++++--
tools/virsh.pod | 34 +++-
17 files changed, 758 insertions(+), 23 deletions(-)
create mode 100644 tests/domainschemadata/qemu-simple-description-title.xml
--
1.7.3.4
13 years, 2 months
[libvirt] [PATCH] tests: fix reversed comparisons
by Eric Blake
Otherwise, a failed test gives misleading output.
* tests/commandtest.c (test13, test14, test16): Pass arguments in
correct order.
---
Pushing under the trivial rule.
tests/commandtest.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tests/commandtest.c b/tests/commandtest.c
index b4b6044..9b9130c 100644
--- a/tests/commandtest.c
+++ b/tests/commandtest.c
@@ -1,7 +1,7 @@
/*
* commandtest.c: Test the libCommand API
*
- * Copyright (C) 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2010-2012 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -481,7 +481,7 @@ static int test13(const void *unused ATTRIBUTE_UNUSED)
cmd = NULL;
if (!STREQ(outactual, outexpect)) {
- virtTestDifference(stderr, outactual, outexpect);
+ virtTestDifference(stderr, outexpect, outactual);
goto cleanup;
}
@@ -526,11 +526,11 @@ static int test14(const void *unused ATTRIBUTE_UNUSED)
cmd = NULL;
if (!STREQ(outactual, outexpect)) {
- virtTestDifference(stderr, outactual, outexpect);
+ virtTestDifference(stderr, outexpect, outactual);
goto cleanup;
}
if (!STREQ(erractual, errexpect)) {
- virtTestDifference(stderr, erractual, errexpect);
+ virtTestDifference(stderr, errexpect, erractual);
goto cleanup;
}
@@ -604,7 +604,7 @@ static int test16(const void *unused ATTRIBUTE_UNUSED)
}
if (!STREQ(outactual, outexpect)) {
- virtTestDifference(stderr, outactual, outexpect);
+ virtTestDifference(stderr, outexpect, outactual);
goto cleanup;
}
--
1.7.7.6
13 years, 2 months
[libvirt] [PATCH v2] Return more error output if policykit auth fails.
by Cole Robinson
Several not uncommon issues can be diagnosed through pkcheck output, like
lack of/malfunctioning desktop agent, or lack of/malfunctioning polkit
dbus agent.
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
v2:
Don't print (null) for empty output
daemon/remote.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 4725896..d2150bf 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -2472,7 +2472,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
int status = -1;
char *ident = NULL;
bool authdismissed = 0;
- char *pkout = NULL;
+ char *pkout = NULL, *pkerr = NULL;
struct daemonClientPrivate *priv =
virNetServerClientGetPrivateData(client);
virCommandPtr cmd = NULL;
@@ -2484,6 +2484,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
cmd = virCommandNewArgList(PKCHECK_PATH, "--action-id", action, NULL);
virCommandSetOutputBuffer(cmd, &pkout);
+ virCommandSetErrorBuffer(cmd, &pkerr);
VIR_DEBUG("Start PolicyKit auth %d", virNetServerClientGetFD(client));
if (virNetServerClientGetAuth(client) != VIR_NET_SERVER_SERVICE_AUTH_POLKIT) {
@@ -2537,15 +2538,22 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
error:
virCommandFree(cmd);
VIR_FREE(ident);
- VIR_FREE(pkout);
virResetLastError();
+
if (authdismissed) {
virNetError(VIR_ERR_AUTH_CANCELLED, "%s",
_("authentication cancelled by user"));
+ } else if (pkout || pkerr) {
+ virNetError(VIR_ERR_AUTH_FAILED, "%s %s",
+ pkerr ? pkerr : "",
+ pkout ? pkout : "");
} else {
virNetError(VIR_ERR_AUTH_FAILED, "%s",
_("authentication failed"));
}
+
+ VIR_FREE(pkout);
+ VIR_FREE(pkerr);
virNetMessageSaveError(rerr);
virMutexUnlock(&priv->lock);
return -1;
--
1.7.7.5
13 years, 2 months
[libvirt] [PATCH v2] Add new error code VIR_ERROR_AUTH_CANCELLED
by Cole Robinson
And hook it up for policykit auth. This allows virt-manager to detect
that the user clicked the policykit 'cancel' button and not throw
an 'authentication failed' error message at the user.
v2:
Don't leak pkout
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
daemon/remote.c | 14 ++++++++++++--
include/libvirt/virterror.h | 1 +
src/util/virterror.c | 6 ++++++
3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 1ada146..cedc26a 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -2471,6 +2471,8 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
const char *action;
int status = -1;
char *ident = NULL;
+ int authdismissed = 0;
+ char *pkout = NULL;
struct daemonClientPrivate *priv =
virNetServerClientGetPrivateData(client);
virCommandPtr cmd = NULL;
@@ -2481,6 +2483,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
"org.libvirt.unix.manage";
cmd = virCommandNewArgList(PKCHECK_PATH, "--action-id", action, NULL);
+ virCommandSetOutputBuffer(cmd, &pkout);
VIR_DEBUG("Start PolicyKit auth %d", virNetServerClientGetFD(client));
if (virNetServerClientGetAuth(client) != VIR_NET_SERVER_SERVICE_AUTH_POLKIT) {
@@ -2509,6 +2512,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
if (virCommandRun(cmd, &status) < 0)
goto authfail;
+ authdismissed = (pkout && strstr(pkout, "dismissed=true"));
if (status != 0) {
char *tmp = virCommandTranslateStatus(status);
VIR_ERROR(_("Policy kit denied action %s from pid %lld, uid %d: %s"),
@@ -2533,9 +2537,15 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
error:
virCommandFree(cmd);
VIR_FREE(ident);
+ VIR_FREE(pkout);
virResetLastError();
- virNetError(VIR_ERR_AUTH_FAILED, "%s",
- _("authentication failed"));
+ if (authdismissed) {
+ virNetError(VIR_ERR_AUTH_CANCELLED, "%s",
+ _("authentication cancelled by user"));
+ } else {
+ virNetError(VIR_ERR_AUTH_FAILED, "%s",
+ _("authentication failed"));
+ }
virNetMessageSaveError(rerr);
virMutexUnlock(&priv->lock);
return -1;
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index e896d67..9844cbe 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -243,6 +243,7 @@ typedef enum {
risky domain snapshot revert */
VIR_ERR_OPERATION_ABORTED = 78, /* operation on a domain was
canceled/aborted by user */
+ VIR_ERR_AUTH_CANCELLED = 79, /* authentication cancelled */
} virErrorNumber;
/**
diff --git a/src/util/virterror.c b/src/util/virterror.c
index 85eec8d..31ddd9d 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -1022,6 +1022,12 @@ virErrorMsg(virErrorNumber error, const char *info)
else
errmsg = _("authentication failed: %s");
break;
+ case VIR_ERR_AUTH_CANCELLED:
+ if (info == NULL)
+ errmsg = _("authentication cancelled");
+ else
+ errmsg = _("authentication cancelled: %s");
+ break;
case VIR_ERR_NO_STORAGE_POOL:
if (info == NULL)
errmsg = _("Storage pool not found");
--
1.7.7.5
13 years, 2 months