[libvirt] [PATCH 3/5] add virDomainQemuAgentCommand() to qemu driver and remote driver
by MATSUDA, Daiki
Add virDomainQemuAgentCommand() to qemu driver and remote driver
to support qemuAgentCommand().
daemon/remote.c | 35 ++++++++++++++++++++
include/libvirt/libvirt-qemu.h | 3 +
src/driver.h | 6 +++
src/libvirt-qemu.c | 58 +++++++++++++++++++++++++++++++++
src/libvirt_qemu.syms | 5 ++
src/qemu/qemu_driver.c | 71 +++++++++++++++++++++++++++++++++++++++++
src/qemu_protocol-structs | 10 +++++
src/remote/qemu_protocol.x | 14 +++++++-
src/remote/remote_driver.c | 41 +++++++++++++++++++++++
9 files changed, 242 insertions(+), 1 deletion(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 832307e..4fd5c9b 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -3948,6 +3948,41 @@ cleanup:
return rv;
}
+static int
+qemuDispatchAgentCommand(virNetServerPtr server ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client ATTRIBUTE_UNUSED,
+ virNetMessagePtr msg ATTRIBUTE_UNUSED,
+ virNetMessageErrorPtr rerr,
+ qemu_agent_command_args *args,
+ qemu_agent_command_ret *ret)
+{
+ virDomainPtr dom = NULL;
+ int rv = -1;
+ struct daemonClientPrivate *priv =
+ virNetServerClientGetPrivateData(client);
+
+ if (!priv->conn) {
+ virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+ goto cleanup;
+ }
+
+ if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
+ goto cleanup;
+
+ if (virDomainQemuAgentCommand(dom, args->cmd, &ret->result,
+ args->timeout, args->flags) < 0) {
+ goto cleanup;
+ }
+
+ rv = 0;
+cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ if (dom)
+ virDomainFree(dom);
+ return rv;
+}
+
/*----- Helpers. -----*/
/* get_nonnull_domain and get_nonnull_network turn an on-wire
diff --git a/include/libvirt/libvirt-qemu.h b/include/libvirt/libvirt-qemu.h
index ffc5ae5..aed1259 100644
--- a/include/libvirt/libvirt-qemu.h
+++ b/include/libvirt/libvirt-qemu.h
@@ -49,6 +49,9 @@ typedef enum {
VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT = 0,
} virDomainQemuAgentCommandTimeoutFlags;
+int virDomainQemuAgentCommand(virDomainPtr domain, const char *cmd,
+ char **result, int timeout, unsigned int flags);
+
# ifdef __cplusplus
}
# endif
diff --git a/src/driver.h b/src/driver.h
index aab9766..c368273 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -689,6 +689,11 @@ typedef int
(*virDrvDomainQemuMonitorCommand)(virDomainPtr domain, const char *cmd,
char **result, unsigned int flags);
+typedef int
+ (*virDrvDomainQemuAgentCommand)(virDomainPtr domain, const char *cmd,
+ char **result, int timeout,
+ unsigned int flags);
+
/* Choice of unsigned int rather than pid_t is intentional. */
typedef virDomainPtr
(*virDrvDomainQemuAttach)(virConnectPtr conn,
@@ -1048,6 +1053,7 @@ struct _virDriver {
virDrvDomainGetDiskErrors domainGetDiskErrors;
virDrvDomainSetMetadata domainSetMetadata;
virDrvDomainGetMetadata domainGetMetadata;
+ virDrvDomainQemuAgentCommand qemuDomainQemuAgentCommand;
};
typedef int
diff --git a/src/libvirt-qemu.c b/src/libvirt-qemu.c
index 78480bb..0e12425 100644
--- a/src/libvirt-qemu.c
+++ b/src/libvirt-qemu.c
@@ -185,3 +185,61 @@ error:
virDispatchError(conn);
return NULL;
}
+
+/**
+ * virDomainQemuAgentCommand:
+ * @domain: a domain object
+ * @cmd: the guest agent command string
+ * @result: a string returned by @cmd
+ * @timeout: timeout seconds
+ * @flags: execution flags
+ *
+ * Execution Guest Agent Command
+ *
+ * Issue @cmd to the guest agent running in @domain.
+ * If @result is NULL, then don't wait for a result (and @timeout
+ * must be 0). Otherwise, wait for @timeout seconds for a
+ * successful result to be populated into *@result, with
+ * VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK (-1) meaning to block
+ * forever waiting for a result.
+ *
+ * Returns 0 if succeeded, -1 in failing.
+ */
+int
+virDomainQemuAgentCommand(virDomainPtr domain,
+ const char *cmd,
+ char **result,
+ int timeout,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DEBUG("domain=%p, cmd=%s, result=%p, timeout=%d, flags=%x",
+ domain, cmd, result, timeout, flags);
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(result, error);
+
+ if (conn->driver->qemuDomainQemuAgentCommand) {
+ int ret;
+ ret = conn->driver->qemuDomainQemuAgentCommand(domain, cmd, result,
+ timeout, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virDispatchError(domain->conn);
+ return -1;
+}
diff --git a/src/libvirt_qemu.syms b/src/libvirt_qemu.syms
index 8447730..f968d91 100644
--- a/src/libvirt_qemu.syms
+++ b/src/libvirt_qemu.syms
@@ -19,3 +19,8 @@ LIBVIRT_QEMU_0.9.4 {
global:
virDomainQemuAttach;
} LIBVIRT_QEMU_0.8.3;
+
+LIBVIRT_QEMU_0.10.0 {
+ global:
+ virDomainQemuAgentCommand;
+} LIBVIRT_QEMU_0.9.4;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index dee1268..750577e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13204,6 +13204,76 @@ qemuListAllDomains(virConnectPtr conn,
return ret;
}
+static int
+qemuDomainQemuAgentCommand(virDomainPtr domain,
+ const char *cmd,
+ char **result,
+ int timeout,
+ unsigned int flags)
+{
+ struct qemud_driver *driver = domain->conn->privateData;
+ virDomainObjPtr vm;
+ int ret = -1;
+ qemuDomainObjPrivatePtr priv;
+
+ virCheckFlags(0, -1);
+
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, domain->uuid);
+ qemuDriverUnlock(driver);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(domain->uuid, uuidstr);
+ qemuReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
+ goto cleanup;
+ }
+
+ priv = vm->privateData;
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ if (priv->agentError) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("QEMU guest agent is not available due to an error"));
+ goto cleanup;
+ }
+
+ if (!priv->agent) {
+ qemuReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("QEMU guest agent is not configured"));
+ goto cleanup;
+ }
+
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
+ qemuDomainObjEnterAgent(driver, vm);
+ ret = qemuAgentQemuAgentCommand(priv->agent, cmd, result, timeout);
+ qemuDomainObjExitAgent(driver, vm);
+
+endjob:
+ if (qemuDomainObjEndJob(driver, vm) == 0) {
+ vm = NULL;
+ }
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ return ret;
+}
+
static virDriver qemuDriver = {
.no = VIR_DRV_QEMU,
.name = QEMU_DRIVER_NAME,
@@ -13369,6 +13439,7 @@ static virDriver qemuDriver = {
.domainPMSuspendForDuration = qemuDomainPMSuspendForDuration, /* 0.9.11 */
.domainPMWakeup = qemuDomainPMWakeup, /* 0.9.11 */
.domainGetCPUStats = qemuDomainGetCPUStats, /* 0.9.11 */
+ .qemuDomainQemuAgentCommand = qemuDomainQemuAgentCommand, /* 0.10.0 */
};
diff --git a/src/qemu_protocol-structs b/src/qemu_protocol-structs
index 67968eb..624fa7b 100644
--- a/src/qemu_protocol-structs
+++ b/src/qemu_protocol-structs
@@ -19,7 +19,17 @@ struct qemu_domain_attach_args {
struct qemu_domain_attach_ret {
remote_nonnull_domain dom;
};
+struct qemu_agent_command_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string cmd;
+ int timeout;
+ u_int flags;
+};
+struct qemu_agent_command_ret {
+ remote_nonnull_string result;
+};
enum qemu_procedure {
QEMU_PROC_MONITOR_COMMAND = 1,
QEMU_PROC_DOMAIN_ATTACH = 2,
+ QEMU_PROC_AGENT_COMMAND = 3,
};
diff --git a/src/remote/qemu_protocol.x b/src/remote/qemu_protocol.x
index c06339c..67c6493 100644
--- a/src/remote/qemu_protocol.x
+++ b/src/remote/qemu_protocol.x
@@ -47,6 +47,17 @@ struct qemu_domain_attach_ret {
remote_nonnull_domain dom;
};
+struct qemu_agent_command_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string cmd;
+ int timeout;
+ unsigned int flags;
+};
+
+struct qemu_agent_command_ret {
+ remote_nonnull_string result;
+};
+
/* Define the program number, protocol version and procedure numbers here. */
const QEMU_PROGRAM = 0x20008087;
const QEMU_PROTOCOL_VERSION = 1;
@@ -61,5 +72,6 @@ enum qemu_procedure {
* are some exceptions to this rule, e.g. domainDestroy. Other APIs MAY
* be marked as high priority. If in doubt, it's safe to choose low. */
QEMU_PROC_MONITOR_COMMAND = 1, /* skipgen skipgen priority:low */
- QEMU_PROC_DOMAIN_ATTACH = 2 /* autogen autogen priority:low */
+ QEMU_PROC_DOMAIN_ATTACH = 2, /* autogen autogen priority:low */
+ QEMU_PROC_AGENT_COMMAND = 3 /* skipgen skipgen priority:low */
};
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 353a153..6f27f59 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -5191,6 +5191,46 @@ make_nonnull_domain_snapshot (remote_nonnull_domain_snapshot *snapshot_dst, virD
make_nonnull_domain(&snapshot_dst->dom, snapshot_src->domain);
}
+static int
+remoteQemuDomainQemuAgentCommand (virDomainPtr domain, const char *cmd,
+ char **result, int timeout,
+ unsigned int flags)
+{
+ int rv = -1;
+ qemu_agent_command_args args;
+ qemu_agent_command_ret ret;
+ struct private_data *priv = domain->conn->privateData;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_domain(&args.dom, domain);
+ args.cmd = (char *)cmd;
+ args.timeout = timeout;
+ args.flags = flags;
+
+ memset (&ret, 0, sizeof(ret));
+
+ if (call (domain->conn, priv, REMOTE_CALL_QEMU, QEMU_PROC_AGENT_COMMAND,
+ (xdrproc_t) xdr_qemu_agent_command_args, (char *) &args,
+ (xdrproc_t) xdr_qemu_agent_command_ret, (char *) &ret) == -1)
+ goto done;
+
+ *result = strdup(ret.result);
+ if (*result == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ rv = 0;
+
+cleanup:
+ xdr_free ((xdrproc_t) xdr_qemu_agent_command_ret, (char *) &ret);
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
/*----------------------------------------------------------------------*/
unsigned long remoteVersion(void)
@@ -5368,6 +5408,7 @@ static virDriver remote_driver = {
.domainSetMetadata = remoteDomainSetMetadata, /* 0.9.10 */
.domainGetMetadata = remoteDomainGetMetadata, /* 0.9.10 */
.domainGetHostname = remoteDomainGetHostname, /* 0.10.0 */
+ .qemuDomainQemuAgentCommand = remoteQemuDomainQemuAgentCommand, /* 0.10.0 */
};
static virNetworkDriver network_driver = {
12 years, 8 months
[libvirt] sending openvswitch "port db" info during libvirt migration
by Laine Stump
Someone asked on IRC the other day about sending openvswitch per-port
data (normally stored in the switch) to the destination host during a
migration. I suggested maybe this could be handled by encoding the
information into the interface's <virtualport> prior to migration, and
then writing it back out to openvswitch on the destination when the
interface was reconnected there.
I think there's a problem with that, though - they don't want to save
the port data on the source until the instant that the interface is
disconnected (since it is constantly changing), but by then the domain
XML has already long ago been formatted and sent to the destination.
So is there some other way within the confines of the current migration
protocol that this information can be sent from migration source to
destination?
12 years, 8 months
[libvirt] [PATCH] [libvirt-java] Fix Array IndexOutOfBoundsException for unknown error codes
by Claudio Bley
Hi.
I sent a few mails on friday, 6th July, via gmane.org but they haven't
made it to the list yet. As I'm a subscriber now, I'm resending them
directly. Sorry for any duplicates in advance.
I'm using libvirt-java 0.4.7 and libvirt 0.9.8.
When libvirt returns an error code which is not mapped in enum
ErrorNumber, an IndexOutOfBoundsException is thrown.
I realize that the freshly released libvirt-java 0.4.8 supports all
error codes up to libvirt 0.9.12. But that doesn't fix the problem.
Would it be feasible to add a special UNKNOWN enum value?
---
diff --git a/src/main/java/org/libvirt/Error.java b/src/main/java/org/libvirt/Error.java
index 0946030..72bc698 100644
--- a/src/main/java/org/libvirt/Error.java
+++ b/src/main/java/org/libvirt/Error.java
@@ -151,9 +151,12 @@ public class Error implements Serializable {
}
public Error(virError vError) {
- code = ErrorNumber.values()[vError.code];
- domain = ErrorDomain.values()[vError.domain];
- level = ErrorLevel.values()[vError.level];
+ if (ErrorNumber.values().length > vError.code)
+ code = ErrorNumber.values()[vError.code];
+ if (ErrorDomain.values().length > vError.domain)
+ domain = ErrorDomain.values()[vError.domain];
+ if (ErrorLevel.values().length > vError.level)
+ level = ErrorLevel.values()[vError.level];
message = vError.message;
str1 = vError.str1;
str2 = vError.str2;
---
Best regards,
Claudio.
--
AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany
Phone: +49 341 265 310 19
Web:<http://www.av-test.org>
Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076)
Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern
12 years, 8 months
[libvirt] [PATCH] qemu: Migrate at unlimited speed by default
by Jiri Denemark
Previously, qemu did not respond to monitor commands during migration if
the limit was too high. This prevented us from raising the limit
earlier. The qemu issue seems to be fixed (according to my testing) and
we may remove the 32Mb/s limit.
---
src/qemu/qemu_domain.c | 2 +-
src/qemu/qemu_domain.h | 5 ++---
src/qemu/qemu_migration.c | 4 ++--
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 86f0265..a54df2f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -217,7 +217,7 @@ static void *qemuDomainObjPrivateAlloc(void)
if (!(priv->cons = virConsoleAlloc()))
goto error;
- priv->migMaxBandwidth = QEMU_DOMAIN_DEFAULT_MIG_BANDWIDTH_MAX;
+ priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
return priv;
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 9f9467d..23a5111 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -38,13 +38,12 @@
(1 << VIR_DOMAIN_VIRT_KVM) | \
(1 << VIR_DOMAIN_VIRT_XEN))
-# define QEMU_DOMAIN_DEFAULT_MIG_BANDWIDTH_MAX 32
# if ULONG_MAX == 4294967295
/* Qemu has a 64-bit limit, but we are limited by our historical choice of
* representing bandwidth in a long instead of a 64-bit int. */
-# define QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX ULONG_MAX
+# define QEMU_DOMAIN_MIG_BANDWIDTH_MAX ULONG_MAX
# else
-# define QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX (INT64_MAX / (1024 * 1024))
+# define QEMU_DOMAIN_MIG_BANDWIDTH_MAX (INT64_MAX / (1024 * 1024))
# endif
# define JOB_MASK(job) (1 << (job - 1))
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index b792456..6eddce6 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3189,8 +3189,8 @@ qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm,
* Failure to change migration speed is not fatal. */
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
qemuMonitorSetMigrationSpeed(priv->mon,
- QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX);
- priv->migMaxBandwidth = QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX;
+ QEMU_DOMAIN_MIG_BANDWIDTH_MAX);
+ priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
qemuDomainObjExitMonitorWithDriver(driver, vm);
}
--
1.7.11.1
12 years, 8 months
[libvirt] [PATCH] examples: Update strings for event details
by Jiri Denemark
---
examples/domain-events/events-c/event-test.c | 2 +-
examples/domain-events/events-python/event-test.py | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c
index f11c7a3..347ee5a 100644
--- a/examples/domain-events/events-c/event-test.c
+++ b/examples/domain-events/events-c/event-test.c
@@ -176,7 +176,7 @@ static const char *eventDetailToString(int event, int detail) {
ret = "Migrated";
break;
case VIR_DOMAIN_EVENT_STOPPED_SAVED:
- ret = "Failed";
+ ret = "Saved";
break;
case VIR_DOMAIN_EVENT_STOPPED_FAILED:
ret = "Failed";
diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py
index 736c225..e3b6ed2 100644
--- a/examples/domain-events/events-python/event-test.py
+++ b/examples/domain-events/events-python/event-test.py
@@ -443,9 +443,9 @@ def detailToString(event, detail):
eventStrings = (
( "Added", "Updated" ),
( "Removed" ),
- ( "Booted", "Migrated", "Restored", "Snapshot" ),
- ( "Paused", "Migrated", "IOError", "Watchdog" ),
- ( "Unpaused", "Migrated"),
+ ( "Booted", "Migrated", "Restored", "Snapshot", "Wakeup" ),
+ ( "Paused", "Migrated", "IOError", "Watchdog", "Restored", "Snapshot" ),
+ ( "Unpaused", "Migrated", "Snapshot" ),
( "Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot"),
( "Finished" )
)
--
1.7.11.1
12 years, 8 months
[libvirt] [PATCH] qemu: Fixe debug message in p2p migration
by Jiri Denemark
When entering "confirm" phase, we are interested in the value of
cancelled rather then ret variable which was interesting before "finish"
phase and didn't change since then.
---
src/qemu/qemu_migration.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 74b70c7..f65c81a 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2459,7 +2459,7 @@ finish:
* If cancelled, then src VM will be restarted, else
* it will be killed
*/
- VIR_DEBUG("Confirm3 %p ret=%d vm=%p", sconn, ret, vm);
+ VIR_DEBUG("Confirm3 %p cancelled=%d vm=%p", sconn, cancelled, vm);
VIR_FREE(cookiein);
cookiein = cookieout;
cookieinlen = cookieoutlen;
--
1.7.11.1
12 years, 8 months
[libvirt] [PATCH v7 0/6] file descriptor passing using fd sets
by Corey Bryant
libvirt's sVirt security driver provides SELinux MAC isolation for
Qemu guest processes and their corresponding image files. In other
words, sVirt uses SELinux to prevent a QEMU process from opening
files that do not belong to it.
sVirt provides this support by labeling guests and resources with
security labels that are stored in file system extended attributes.
Some file systems, such as NFS, do not support the extended
attribute security namespace, and therefore cannot support sVirt
isolation.
A solution to this problem is to provide fd passing support, where
libvirt opens files and passes file descriptors to QEMU. This,
along with SELinux policy to prevent QEMU from opening files, can
provide image file isolation for NFS files stored on the same NFS
mount.
This patch series adds the add-fd, remove-fd, and query-fdsets
QMP monitor commands, which allow file descriptors to be passed
via SCM_RIGHTS, and assigned to specified fd sets. This allows
fd sets to be created per file with fds having, for example,
different access rights. When QEMU needs to reopen a file with
different access rights, it can search for a matching fd in the
fd set. Fd sets also allow for easy tracking of fds per file,
helping to prevent fd leaks.
Support is also added to the block layer to allow QEMU to dup an
fd from an fdset when the filename is of the /dev/fdset/nnn format,
where nnn is the fd set ID.
No new SELinux policy is required to prevent open of NFS files
(files with type nfs_t). The virt_use_nfs boolean type simply
needs to be set to false, and open will be prevented (and dup will
be allowed). For example:
# setsebool virt_use_nfs 0
# getsebool virt_use_nfs
virt_use_nfs --> off
Corey Bryant (6):
qemu-char: Add MSG_CMSG_CLOEXEC flag to recvmsg
qapi: Introduce add-fd, remove-fd, query-fdsets
monitor: Clean up fd sets on monitor disconnect
block: Convert open calls to qemu_open
block: Convert close calls to qemu_close
block: Enable qemu_open/close to work with fd sets
block/raw-posix.c | 42 ++++-----
block/raw-win32.c | 6 +-
block/vdi.c | 5 +-
block/vmdk.c | 25 +++--
block/vpc.c | 4 +-
block/vvfat.c | 16 ++--
cutils.c | 5 +
monitor.c | 273 +++++++++++++++++++++++++++++++++++++++++++++++++++++
monitor.h | 5 +
osdep.c | 117 +++++++++++++++++++++++
qapi-schema.json | 110 +++++++++++++++++++++
qemu-char.c | 12 ++-
qemu-common.h | 2 +
qemu-tool.c | 20 ++++
qerror.c | 4 +
qerror.h | 3 +
qmp-commands.hx | 131 +++++++++++++++++++++++++
savevm.c | 4 +-
18 files changed, 730 insertions(+), 54 deletions(-)
--
1.7.10.4
12 years, 8 months
[libvirt] [libvirt-glib] Fix small typo in error message ('downlaod')
by Christophe Fergeau
---
Pushed under the trivial rule.
libvirt-gobject/libvirt-gobject-storage-vol.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.c b/libvirt-gobject/libvirt-gobject-storage-vol.c
index 99ccbab..9256445 100644
--- a/libvirt-gobject/libvirt-gobject-storage-vol.c
+++ b/libvirt-gobject/libvirt-gobject-storage-vol.c
@@ -384,7 +384,7 @@ gboolean gvir_storage_vol_download(GVirStorageVol *vol,
gvir_set_error_literal(err,
GVIR_STORAGE_VOL_ERROR,
0,
- "Unable to downlaod volume storage");
+ "Unable to download volume storage");
goto cleanup;
}
--
1.7.11.2
12 years, 8 months
[libvirt] [PATCH] qemu: Refactor parsing of block device IO tuning parameters.
by Peter Krempa
This patch refactors the JSON parsing function that extracts the block
IO tuning parameters from qemu's output. The most impacting change
concerns the error message that is returned if the reply from qemu does
not contain the needed data. The data for IO parameter tuning were added
in qemu 1.1 and the previous error message was confusing.
This patch also breaks long lines and extracts a multiple time used code
pattern to a macro.
---
Old error message looks like:
# virsh blkdeviotune asdf hda
error: Unable to get block I/O throttle parameters
error: internal error cannot read total_bytes_sec
and the new:
# virsh blkdeviotune asdf hda
error: Unable to get block I/O throttle parameters
error: internal error block_io_throttle field 'total_bytes_sec' missing in qemu's output
src/qemu/qemu_monitor_json.c | 66 ++++++++++++++++-------------------------
1 files changed, 26 insertions(+), 40 deletions(-)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index dd6536f..3ede88d 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3648,6 +3648,16 @@ int qemuMonitorJSONOpenGraphics(qemuMonitorPtr mon,
}
+#define GET_THROTTLE_STATS(FIELD, STORE) \
+ if (virJSONValueObjectGetNumberUlong(inserted, \
+ FIELD, \
+ &reply->STORE) < 0) { \
+ virReportError(VIR_ERR_INTERNAL_ERROR, \
+ _("block_io_throttle field '%s' missing " \
+ "in qemu's output"), \
+ #STORE); \
+ goto cleanup; \
+ }
static int
qemuMonitorJSONBlockIoThrottleInfo(virJSONValuePtr result,
const char *device,
@@ -3656,7 +3666,7 @@ qemuMonitorJSONBlockIoThrottleInfo(virJSONValuePtr result,
virJSONValuePtr io_throttle;
int ret = -1;
int i;
- int found = 0;
+ bool found = false;
io_throttle = virJSONValueObjectGet(result, "return");
@@ -3673,13 +3683,15 @@ qemuMonitorJSONBlockIoThrottleInfo(virJSONValuePtr result,
if (!temp_dev || temp_dev->type != VIR_JSON_TYPE_OBJECT) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("block_io_throttle device entry was not in expected format"));
+ _("block_io_throttle device entry "
+ "was not in expected format"));
goto cleanup;
}
- if ((current_dev = virJSONValueObjectGetString(temp_dev, "device")) == NULL) {
+ if (!(current_dev = virJSONValueObjectGetString(temp_dev, "device"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("block_io_throttle device entry was not in expected format"));
+ _("block_io_throttle device entry "
+ "was not in expected format"));
goto cleanup;
}
@@ -3689,49 +3701,22 @@ qemuMonitorJSONBlockIoThrottleInfo(virJSONValuePtr result,
if (STREQ(current_dev, device))
continue;
- found = 1;
+ found = true;
if ((inserted = virJSONValueObjectGet(temp_dev, "inserted")) == NULL ||
inserted->type != VIR_JSON_TYPE_OBJECT) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("block_io_throttle inserted entry was not in expected format"));
+ _("block_io_throttle inserted entry "
+ "was not in expected format"));
goto cleanup;
}
- if (virJSONValueObjectGetNumberUlong(inserted, "bps", &reply->total_bytes_sec) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot read total_bytes_sec"));
- goto cleanup;
- }
+ GET_THROTTLE_STATS("bps", total_bytes_sec);
+ GET_THROTTLE_STATS("bps_rd", read_bytes_sec);
+ GET_THROTTLE_STATS("bps_wr", write_bytes_sec);
+ GET_THROTTLE_STATS("iops", total_iops_sec);
+ GET_THROTTLE_STATS("iops_rd", read_iops_sec);
+ GET_THROTTLE_STATS("iops_wr", write_iops_sec);
- if (virJSONValueObjectGetNumberUlong(inserted, "bps_rd", &reply->read_bytes_sec) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot read read_bytes_sec"));
- goto cleanup;
- }
-
- if (virJSONValueObjectGetNumberUlong(inserted, "bps_wr", &reply->write_bytes_sec) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot read write_bytes_sec"));
- goto cleanup;
- }
-
- if (virJSONValueObjectGetNumberUlong(inserted, "iops", &reply->total_iops_sec) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot read total_iops_sec"));
- goto cleanup;
- }
-
- if (virJSONValueObjectGetNumberUlong(inserted, "iops_rd", &reply->read_iops_sec) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot read read_iops_sec"));
- goto cleanup;
- }
-
- if (virJSONValueObjectGetNumberUlong(inserted, "iops_wr", &reply->write_iops_sec) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot read write_iops_sec"));
- goto cleanup;
- }
break;
}
@@ -3746,6 +3731,7 @@ qemuMonitorJSONBlockIoThrottleInfo(virJSONValuePtr result,
cleanup:
return ret;
}
+#undef GET_THROTTLE_STATS
int qemuMonitorJSONSetBlockIoThrottle(qemuMonitorPtr mon,
const char *device,
--
1.7.8.6
12 years, 8 months