[libvirt] [PATCH] add sendevent command and related APIs
by Lai Jiangshan
Enable libvirt send some events to the guest.
This command currently only supports NMI and key events.
Signed-off-by: Lai Jiangshan <laijs(a)cn.fujitsu.com>
---
daemon/remote.c | 52 +++++++++++++++++++++
daemon/remote_dispatch_args.h | 2
daemon/remote_dispatch_prototypes.h | 16 ++++++
daemon/remote_dispatch_table.h | 10 ++++
include/libvirt/libvirt.h.in | 3 +
src/driver.h | 7 ++
src/esx/esx_driver.c | 2
src/libvirt.c | 88 ++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 2
src/libxl/libxl_driver.c | 2
src/lxc/lxc_driver.c | 2
src/openvz/openvz_driver.c | 2
src/phyp/phyp_driver.c | 4 +
src/qemu/qemu_driver.c | 86 +++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor.c | 27 +++++++++++
src/qemu/qemu_monitor.h | 3 +
src/qemu/qemu_monitor_json.c | 68 +++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 3 +
src/qemu/qemu_monitor_text.c | 56 ++++++++++++++++++++++
src/qemu/qemu_monitor_text.h | 2
src/remote/remote_driver.c | 50 ++++++++++++++++++++
src/remote/remote_protocol.c | 22 +++++++++
src/remote/remote_protocol.h | 19 +++++++
src/remote/remote_protocol.x | 14 +++++
src/test/test_driver.c | 2
src/uml/uml_driver.c | 2
src/vbox/vbox_tmpl.c | 2
src/vmware/vmware_driver.c | 2
src/xen/xen_driver.c | 2
src/xenapi/xenapi_driver.c | 2
tools/virsh.c | 56 ++++++++++++++++++++++
31 files changed, 608 insertions(+), 2 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 1700c2d..5f9e78a 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -2836,6 +2836,58 @@ remoteDispatchDomainGetBlkioParameters(struct qemud_server *server
}
static int
+remoteDispatchDomainSendEventNMI(struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_message_header *hdr ATTRIBUTE_UNUSED,
+ remote_error *rerr,
+ remote_domain_send_event_nmi_args *args,
+ void *ret ATTRIBUTE_UNUSED)
+{
+ virDomainPtr dom;
+
+ dom = get_nonnull_domain(conn, args->dom);
+ if (dom == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ if (virDomainSendEventNMI(dom, args->vcpu) == -1) {
+ virDomainFree(dom);
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+ virDomainFree(dom);
+ return 0;
+}
+
+static int
+remoteDispatchDomainSendEventKey(struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_message_header *hdr ATTRIBUTE_UNUSED,
+ remote_error *rerr,
+ remote_domain_send_event_key_args *args,
+ void *ret ATTRIBUTE_UNUSED)
+{
+ virDomainPtr dom;
+
+ dom = get_nonnull_domain(conn, args->dom);
+ if (dom == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ if (virDomainSendEventKey(dom, args->key) == -1) {
+ virDomainFree(dom);
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+ virDomainFree(dom);
+ return 0;
+}
+
+static int
remoteDispatchDomainSetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_client *client ATTRIBUTE_UNUSED,
virConnectPtr conn,
diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h
index f9537d7..289a42e 100644
--- a/daemon/remote_dispatch_args.h
+++ b/daemon/remote_dispatch_args.h
@@ -178,3 +178,5 @@
remote_domain_migrate_set_max_speed_args val_remote_domain_migrate_set_max_speed_args;
remote_storage_vol_upload_args val_remote_storage_vol_upload_args;
remote_storage_vol_download_args val_remote_storage_vol_download_args;
+ remote_domain_send_event_nmi_args val_remote_domain_send_event_nmi_args;
+ remote_domain_send_event_key_args val_remote_domain_send_event_key_args;
diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h
index 18bf41d..f920193 100644
--- a/daemon/remote_dispatch_prototypes.h
+++ b/daemon/remote_dispatch_prototypes.h
@@ -1618,3 +1618,19 @@ static int remoteDispatchSupportsFeature(
remote_error *err,
remote_supports_feature_args *args,
remote_supports_feature_ret *ret);
+static int remoteDispatchDomainSendEventNMI(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_message_header *hdr,
+ remote_error *err,
+ remote_domain_send_event_nmi_args *args,
+ void *ret);
+static int remoteDispatchDomainSendEventKey(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_message_header *hdr,
+ remote_error *err,
+ remote_domain_send_event_key_args *args,
+ void *ret);
diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h
index b39f7c2..a706b19 100644
--- a/daemon/remote_dispatch_table.h
+++ b/daemon/remote_dispatch_table.h
@@ -1052,3 +1052,13 @@
.args_filter = (xdrproc_t) xdr_remote_storage_vol_download_args,
.ret_filter = (xdrproc_t) xdr_void,
},
+{ /* DomainSendEventNmi => 210 */
+ .fn = (dispatch_fn) remoteDispatchDomainSendEventNMI,
+ .args_filter = (xdrproc_t) xdr_remote_domain_send_event_nmi_args,
+ .ret_filter = (xdrproc_t) xdr_void,
+},
+{ /* DomainSendEventKey => 211 */
+ .fn = (dispatch_fn) remoteDispatchDomainSendEventKey,
+ .args_filter = (xdrproc_t) xdr_remote_domain_send_event_key_args,
+ .ret_filter = (xdrproc_t) xdr_void,
+},
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index bd36015..adbe482 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2517,6 +2517,9 @@ int virDomainOpenConsole(virDomainPtr dom,
virStreamPtr st,
unsigned int flags);
+int virDomainSendEventNMI(virDomainPtr domain, unsigned int vcpu);
+int virDomainSendEventKey(virDomainPtr domain, const char *key);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/driver.h b/src/driver.h
index e5f91ca..6caf13f 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -515,6 +515,11 @@ typedef int
virStreamPtr st,
unsigned int flags);
+typedef int
+ (*virDrvDomainSendEventNMI)(virDomainPtr dom, unsigned int vcpu);
+
+typedef int
+ (*virDrvDomainSendEventKey)(virDomainPtr dom, const char *key);
/**
* _virDriver:
@@ -639,6 +644,8 @@ struct _virDriver {
virDrvDomainSnapshotDelete domainSnapshotDelete;
virDrvQemuDomainMonitorCommand qemuDomainMonitorCommand;
virDrvDomainOpenConsole domainOpenConsole;
+ virDrvDomainSendEventNMI domainSendEventNMI;
+ virDrvDomainSendEventKey domainSendEventKey;
};
typedef int
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index deda372..7167712 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -4675,6 +4675,8 @@ static virDriver esxDriver = {
esxDomainSnapshotDelete, /* domainSnapshotDelete */
NULL, /* qemuDomainMonitorCommand */
NULL, /* domainOpenConsole */
+ NULL, /* domainSendEventNMI */
+ NULL, /* domainSendEventKey */
};
diff --git a/src/libvirt.c b/src/libvirt.c
index 9bdb4c8..245247f 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -5245,6 +5245,94 @@ error:
}
/**
+ * virDomainSendEvnetNMI:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @vcpu: the virtual CPU id to send NMI to
+ *
+ * Send NMI to a special vcpu of the guest
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+
+int virDomainSendEventNMI(virDomainPtr domain, unsigned int vcpu)
+{
+ virConnectPtr conn;
+ VIR_DOMAIN_DEBUG(domain, "vcpu=%u", vcpu);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainSendEventNMI) {
+ int ret;
+ ret = conn->driver->domainSendEventNMI(domain, vcpu);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+/**
+ * virDomainSendEventKey:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @key: the string of key or key sequence
+ *
+ * Send a special key or key sequence to the guest
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+
+int virDomainSendEventKey(virDomainPtr domain, const char *key)
+{
+ virConnectPtr conn;
+ VIR_DOMAIN_DEBUG(domain, "key=%s", key);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return (-1);
+ }
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainSendEventKey) {
+ int ret;
+ ret = conn->driver->domainSendEventKey(domain, key);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+/**
* virDomainSetVcpus:
* @domain: pointer to domain object, or NULL for Domain0
* @nvcpus: the new number of virtual CPUs for this domain
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index b4aed41..cd0f474 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -434,6 +434,8 @@ LIBVIRT_0.9.0 {
virEventRunDefaultImpl;
virStorageVolDownload;
virStorageVolUpload;
+ virDomainSendEventNMI;
+ virDomainSendEventKey;
} LIBVIRT_0.8.8;
# .... define new API here using predicted next version number ....
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index e996ff6..040fc16 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -2353,6 +2353,8 @@ static virDriver libxlDriver = {
NULL, /* domainSnapshotDelete */
NULL, /* qemuDomainMonitorCommand */
NULL, /* domainOpenConsole */
+ NULL, /* domainSendEventNMI */
+ NULL, /* domainSendEventKey */
};
static virStateDriver libxlStateDriver = {
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index e905302..1284ab1 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -2906,6 +2906,8 @@ static virDriver lxcDriver = {
NULL, /* domainSnapshotDelete */
NULL, /* qemuDomainMonitorCommand */
lxcDomainOpenConsole, /* domainOpenConsole */
+ NULL, /* domainSendEventNMI */
+ NULL, /* domainSendEventKey */
};
static virStateDriver lxcStateDriver = {
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index fb30c37..26ba0a5 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -1654,6 +1654,8 @@ static virDriver openvzDriver = {
NULL, /* domainSnapshotDelete */
NULL, /* qemuDomainMonitorCommand */
NULL, /* domainOpenConsole */
+ NULL, /* domainSendEventNMI */
+ NULL, /* domainSendEventKey */
};
int openvzRegister(void) {
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index 51f9ff6..d5d0ea6 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -4054,7 +4054,9 @@ static virDriver phypDriver = {
NULL, /* domainRevertToSnapshot */
NULL, /* domainSnapshotDelete */
NULL, /* qemuMonitorCommand */
- NULL, /* domainOpenConsole */
+ NULL, /* domainOpenConsole */
+ NULL, /* domainSendEventNMI */
+ NULL, /* domainSendEventKey */
};
static virStorageDriver phypStorageDriver = {
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index dd12dc8..02af591 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1659,6 +1659,90 @@ static int qemudDomainSetMemory(virDomainPtr dom, unsigned long newmem) {
return qemudDomainSetMemoryFlags(dom, newmem, VIR_DOMAIN_MEM_LIVE);
}
+static int qemuDomainSendEventNMI(virDomainPtr domain, unsigned int vcpu)
+{
+ struct qemud_driver *driver = domain->conn->privateData;
+ virDomainObjPtr vm = NULL;
+ int ret = -1;
+ qemuDomainObjPrivatePtr priv;
+
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, domain->uuid);
+ 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;
+ }
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ priv = vm->privateData;
+
+ if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
+ goto cleanup;
+ qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ ret = qemuMonitorSendEventNMI(priv->mon, vcpu);
+ qemuDomainObjExitMonitorWithDriver(driver, vm);
+ if (qemuDomainObjEndJob(vm) == 0) {
+ vm = NULL;
+ goto cleanup;
+ }
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
+ return ret;
+}
+
+static int qemuDomainSendEventKey(virDomainPtr domain, const char *key)
+{
+ struct qemud_driver *driver = domain->conn->privateData;
+ virDomainObjPtr vm = NULL;
+ int ret = -1;
+ qemuDomainObjPrivatePtr priv;
+
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, domain->uuid);
+ 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;
+ }
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ priv = vm->privateData;
+
+ if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
+ goto cleanup;
+ qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ ret = qemuMonitorSendEventKey(priv->mon, key);
+ qemuDomainObjExitMonitorWithDriver(driver, vm);
+ if (qemuDomainObjEndJob(vm) == 0) {
+ vm = NULL;
+ goto cleanup;
+ }
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
+ return ret;
+}
+
static int qemudDomainGetInfo(virDomainPtr dom,
virDomainInfoPtr info) {
struct qemud_driver *driver = dom->conn->privateData;
@@ -6923,6 +7007,8 @@ static virDriver qemuDriver = {
qemuDomainSnapshotDelete, /* domainSnapshotDelete */
qemuDomainMonitorCommand, /* qemuDomainMonitorCommand */
qemuDomainOpenConsole, /* domainOpenConsole */
+ qemuDomainSendEventNMI, /* domainSendEventNMI */
+ qemuDomainSendEventKey, /* domainSendEventKey */
};
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 2d28f8d..bc2e269 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2228,3 +2228,30 @@ int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
ret = qemuMonitorTextArbitraryCommand(mon, cmd, reply);
return ret;
}
+
+
+int qemuMonitorSendEventNMI(qemuMonitorPtr mon, unsigned int vcpu)
+{
+ int ret;
+
+ VIR_DEBUG("mon=%p, vcpu=%u", mon, vcpu);
+
+ if (mon->json)
+ ret = qemuMonitorJSONSendEventNMI(mon, vcpu);
+ else
+ ret = qemuMonitorTextSendEventNMI(mon, vcpu);
+ return ret;
+}
+
+int qemuMonitorSendEventKey(qemuMonitorPtr mon, const char *key)
+{
+ int ret;
+
+ VIR_DEBUG("mon=%p, key sequence=%s", mon, key);
+
+ if (mon->json)
+ ret = qemuMonitorJSONSendEventKey(mon, key);
+ else
+ ret = qemuMonitorTextSendEventKey(mon, key);
+ return ret;
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index c90219b..fdc9859 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -423,6 +423,9 @@ int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
char **reply,
bool hmp);
+int qemuMonitorSendEventNMI(qemuMonitorPtr mon, unsigned int vcpu);
+int qemuMonitorSendEventKey(qemuMonitorPtr mon, const char *key);
+
/**
* When running two dd process and using <> redirection, we need a
* shell that will not truncate files. These two strings serve that
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 20a78e1..5149d9e 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2513,3 +2513,71 @@ cleanup:
return ret;
}
+
+int qemuMonitorJSONSendEventNMI(qemuMonitorPtr mon, unsigned int vcpu)
+{
+ int ret = -1;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+ char *hmp_cmd;
+
+ /*
+ * FIXME: qmp nmi is not supported until qemu-0.16.0,
+ * use human-monitor-command instead temporary.
+ */
+ if (virAsprintf(&hmp_cmd, "nmi %u", vcpu) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ cmd = qemuMonitorJSONMakeCommand("human-monitor-command",
+ "s:command-line", hmp_cmd,
+ NULL);
+ if (!cmd)
+ goto out_free_hmp_cmd;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0)
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+out_free_hmp_cmd:
+ VIR_FREE(hmp_cmd);
+ return ret;
+}
+
+int qemuMonitorJSONSendEventKey(qemuMonitorPtr mon, const char *key_seq)
+{
+ int ret = -1;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+ char *hmp_cmd;
+
+ /*
+ * FIXME: qmp sendkey is not supported until qemu-0.16.0,
+ * use human-monitor-command instead temporary.
+ */
+ if (virAsprintf(&hmp_cmd, "sendkey %s", key_seq) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ cmd = qemuMonitorJSONMakeCommand("human-monitor-command",
+ "s:command-line", hmp_cmd,
+ NULL);
+ if (!cmd)
+ goto out_free_hmp_cmd;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0)
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+out_free_hmp_cmd:
+ VIR_FREE(hmp_cmd);
+ return ret;
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 086f0e1..dc206df 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -204,4 +204,7 @@ int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
char **reply_str,
bool hmp);
+int qemuMonitorJSONSendEventNMI(qemuMonitorPtr mon, unsigned int vcpu);
+int qemuMonitorJSONSendEventKey(qemuMonitorPtr mon, const char *key);
+
#endif /* QEMU_MONITOR_JSON_H */
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index e0e3292..d3416a8 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -2627,3 +2627,59 @@ int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd,
return ret;
}
+
+int qemuMonitorTextSendEventNMI(qemuMonitorPtr mon, unsigned int vcpu)
+{
+ char *cmd;
+ char *reply = NULL;
+ int ret = -1;
+
+ if (virAsprintf(&cmd, "nmi %u", vcpu) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ if (qemuMonitorTextArbitraryCommand(mon, cmd, &reply)) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("failed to send NMI using command '%s'"),
+ cmd);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(cmd);
+ VIR_FREE(reply);
+ return ret;
+}
+
+int qemuMonitorTextSendEventKey(qemuMonitorPtr mon, const char *key)
+{
+ char *cmd;
+ char *reply = NULL;
+ int ret = -1;
+
+ if (virAsprintf(&cmd, "sendkey %s", key) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ if (qemuMonitorTextArbitraryCommand(mon, cmd, &reply)) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("failed to send key using command '%s'"),
+ cmd);
+ goto cleanup;
+ }
+
+ if (strstr(reply, "unknown key") != NULL) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("sent unknown key"));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(cmd);
+ VIR_FREE(reply);
+ return ret;
+}
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index 0838a2b..4a03c40 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -198,4 +198,6 @@ int qemuMonitorTextDeleteSnapshot(qemuMonitorPtr mon, const char *name);
int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd,
char **reply);
+int qemuMonitorTextSendEventNMI(qemuMonitorPtr mon, unsigned int vcpu);
+int qemuMonitorTextSendEventKey(qemuMonitorPtr mon, const char *key);
#endif /* QEMU_MONITOR_TEXT_H */
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index bf94e70..676f473 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -2929,6 +2929,54 @@ done:
}
static int
+remoteDomainSendEventNMI(virDomainPtr domain, unsigned int vcpu)
+{
+ int rv = -1;
+ remote_domain_send_event_nmi_args args;
+ struct private_data *priv = domain->conn->privateData;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_domain (&args.dom, domain);
+ args.vcpu = vcpu;
+
+ if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SEND_EVENT_NMI,
+ (xdrproc_t) xdr_remote_domain_send_event_nmi_args, (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ goto done;
+
+ rv = 0;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+static int
+remoteDomainSendEventKey(virDomainPtr domain, const char *key)
+{
+ int rv = -1;
+ remote_domain_send_event_key_args args;
+ struct private_data *priv = domain->conn->privateData;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_domain (&args.dom, domain);
+ args.key = (char *)key;
+
+ if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SEND_EVENT_KEY,
+ (xdrproc_t) xdr_remote_domain_send_event_key_args, (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ goto done;
+
+ rv = 0;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+static int
remoteDomainSetVcpus (virDomainPtr domain, unsigned int nvcpus)
{
int rv = -1;
@@ -11296,6 +11344,8 @@ static virDriver remote_driver = {
remoteDomainSnapshotDelete, /* domainSnapshotDelete */
remoteQemuDomainMonitorCommand, /* qemuDomainMonitorCommand */
remoteDomainOpenConsole, /* domainOpenConsole */
+ remoteDomainSendEventNMI, /* domainSendEventNMI */
+ remoteDomainSendEventKey, /* domainSendEventKey */
};
static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c
index 5604371..a829219 100644
--- a/src/remote/remote_protocol.c
+++ b/src/remote/remote_protocol.c
@@ -1463,6 +1463,28 @@ xdr_remote_domain_undefine_args (XDR *xdrs, remote_domain_undefine_args *objp)
}
bool_t
+xdr_remote_domain_send_event_nmi_args (XDR *xdrs, remote_domain_send_event_nmi_args *objp)
+{
+
+ if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->vcpu))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_domain_send_event_key_args (XDR *xdrs, remote_domain_send_event_key_args *objp)
+{
+
+ if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+ return FALSE;
+ if (!xdr_remote_nonnull_string (xdrs, &objp->key))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_remote_domain_set_vcpus_args (XDR *xdrs, remote_domain_set_vcpus_args *objp)
{
diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h
index d9bf151..027ef88 100644
--- a/src/remote/remote_protocol.h
+++ b/src/remote/remote_protocol.h
@@ -2200,6 +2200,19 @@ struct remote_storage_vol_download_args {
u_int flags;
};
typedef struct remote_storage_vol_download_args remote_storage_vol_download_args;
+
+struct remote_domain_send_event_nmi_args {
+ remote_nonnull_domain dom;
+ u_int vcpu;
+};
+typedef struct remote_domain_send_event_nmi_args remote_domain_send_event_nmi_args;
+
+struct remote_domain_send_event_key_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string key;
+};
+typedef struct remote_domain_send_event_key_args remote_domain_send_event_key_args;
+
#define REMOTE_PROGRAM 0x20008086
#define REMOTE_PROTOCOL_VERSION 1
@@ -2413,6 +2426,8 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207,
REMOTE_PROC_STORAGE_VOL_UPLOAD = 208,
REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209,
+ REMOTE_PROC_DOMAIN_SEND_EVENT_NMI = 210,
+ REMOTE_PROC_DOMAIN_SEND_EVENT_KEY = 211,
};
typedef enum remote_procedure remote_procedure;
@@ -2561,6 +2576,8 @@ extern bool_t xdr_remote_domain_create_with_flags_ret (XDR *, remote_domain_cre
extern bool_t xdr_remote_domain_define_xml_args (XDR *, remote_domain_define_xml_args*);
extern bool_t xdr_remote_domain_define_xml_ret (XDR *, remote_domain_define_xml_ret*);
extern bool_t xdr_remote_domain_undefine_args (XDR *, remote_domain_undefine_args*);
+extern bool_t xdr_remote_domain_send_event_nmi_args (XDR *, remote_domain_send_event_nmi_args*);
+extern bool_t xdr_remote_domain_send_event_key_args (XDR *, remote_domain_send_event_key_args*);
extern bool_t xdr_remote_domain_set_vcpus_args (XDR *, remote_domain_set_vcpus_args*);
extern bool_t xdr_remote_domain_set_vcpus_flags_args (XDR *, remote_domain_set_vcpus_flags_args*);
extern bool_t xdr_remote_domain_get_vcpus_flags_args (XDR *, remote_domain_get_vcpus_flags_args*);
@@ -2918,6 +2935,8 @@ extern bool_t xdr_remote_domain_create_with_flags_ret ();
extern bool_t xdr_remote_domain_define_xml_args ();
extern bool_t xdr_remote_domain_define_xml_ret ();
extern bool_t xdr_remote_domain_undefine_args ();
+extern bool_t xdr_remote_domain_send_event_nmi_args ();
+extern bool_t xdr_remote_domain_send_event_key_args ();
extern bool_t xdr_remote_domain_set_vcpus_args ();
extern bool_t xdr_remote_domain_set_vcpus_flags_args ();
extern bool_t xdr_remote_domain_get_vcpus_flags_args ();
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 675eccd..34600d7 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -817,6 +817,16 @@ struct remote_domain_undefine_args {
remote_nonnull_domain dom;
};
+struct remote_domain_send_event_nmi_args {
+ remote_nonnull_domain dom;
+ unsigned int vcpu;
+};
+
+struct remote_domain_send_event_key_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string key;
+};
+
struct remote_domain_set_vcpus_args {
remote_nonnull_domain dom;
int nvcpus;
@@ -2176,8 +2186,10 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 206,
REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207,
REMOTE_PROC_STORAGE_VOL_UPLOAD = 208,
- REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209
+ REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209,
+ REMOTE_PROC_DOMAIN_SEND_EVENT_NMI = 210,
+ REMOTE_PROC_DOMAIN_SEND_EVENT_KEY = 211,
/*
* Notice how the entries are grouped in sets of 10 ?
* Nice isn't it. Please keep it this way when adding more.
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 17f5ad9..2163850 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -5447,6 +5447,8 @@ static virDriver testDriver = {
NULL, /* domainSnapshotDelete */
NULL, /* qemuDomainMonitorCommand */
NULL, /* domainOpenConsole */
+ NULL, /* domainSendEventNMI */
+ NULL, /* domainSendEventKey */
};
static virNetworkDriver testNetworkDriver = {
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index e2bd5f2..756877d 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -2249,6 +2249,8 @@ static virDriver umlDriver = {
NULL, /* domainSnapshotDelete */
NULL, /* qemuDomainMonitorCommand */
umlDomainOpenConsole, /* domainOpenConsole */
+ NULL, /* domainSendEventNMI */
+ NULL, /* domainSendEventKey */
};
static int
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 8bd27dd..73c5c87 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -8647,6 +8647,8 @@ virDriver NAME(Driver) = {
vboxDomainSnapshotDelete, /* domainSnapshotDelete */
NULL, /* qemuDomainMonitorCommand */
NULL, /* domainOpenConsole */
+ NULL, /* domainSendEventNMI */
+ NULL, /* domainSendEventKey */
};
virNetworkDriver NAME(NetworkDriver) = {
diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c
index b5e416b..eb64087 100644
--- a/src/vmware/vmware_driver.c
+++ b/src/vmware/vmware_driver.c
@@ -1007,6 +1007,8 @@ static virDriver vmwareDriver = {
NULL, /* domainSnapshotDelete */
NULL, /* qemuDomainMonitorCommand */
NULL, /* domainOpenConsole */
+ NULL, /* domainSendEventNMI */
+ NULL, /* domainSendEventKey */
};
int
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 9f47722..bd82001 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -2141,6 +2141,8 @@ static virDriver xenUnifiedDriver = {
NULL, /* domainSnapshotDelete */
NULL, /* qemuDomainMonitorCommand */
xenUnifiedDomainOpenConsole, /* domainOpenConsole */
+ NULL, /* domainSendEventNMI */
+ NULL, /* domainSendEventKey */
};
/**
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
index 27206a0..0f85ad8 100644
--- a/src/xenapi/xenapi_driver.c
+++ b/src/xenapi/xenapi_driver.c
@@ -1885,6 +1885,8 @@ static virDriver xenapiDriver = {
NULL, /* domainSnapshotDelete */
NULL, /* qemuDomainMonitorCommand */
NULL, /* domainOpenConsole */
+ NULL, /* domainSendEventNMI */
+ NULL, /* domainSendEventKey */
};
/**
diff --git a/tools/virsh.c b/tools/virsh.c
index faeaf47..0b78c6d 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2910,6 +2910,61 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd)
}
/*
+ * "sendevent" command
+ */
+static const vshCmdInfo info_sendevent[] = {
+ {"help", N_("send events to the guest")},
+ {"desc", N_("Send events (NMI or Keys) to the guest domain.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_sendevent[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
+ {"eventtype", VSH_OT_DATA, VSH_OFLAG_REQ, N_("the type of event (nmi or key)")},
+ {"eventcontent", VSH_OT_DATA, VSH_OFLAG_REQ, N_("content for the event.")},
+ {NULL, 0, 0, NULL}
+};
+
+
+static int
+cmdSendEvent(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom;
+ const char *type;
+ int ret = TRUE;
+
+ if (!vshConnectionUsability(ctl, ctl->conn))
+ return FALSE;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+ return FALSE;
+
+ if (vshCommandOptString(cmd, "eventtype", &type) < 0)
+ return FALSE;
+
+ if (STREQ(type, "nmi")) {
+ int cpu;
+
+ if ((vshCommandOptInt(cmd, "eventcontent", &cpu) < 0)
+ || (virDomainSendEventNMI(dom, cpu) < 0))
+ ret = FALSE;
+ } else if (STREQ(type, "key")) {
+ const char *key;
+
+ if ((vshCommandOptString(cmd, "eventcontent", &key) < 0)
+ || (virDomainSendEventKey(dom, key) < 0))
+ ret = FALSE;
+ } else {
+ virDomainFree(dom);
+ vshError(ctl, _("Invalid event type: %s, only \"nmi\" or \"key\" supported currently."), type);
+ return FALSE;
+ }
+
+ virDomainFree(dom);
+ return ret;
+}
+
+/*
* "setmemory" command
*/
static const vshCmdInfo info_setmem[] = {
@@ -10693,6 +10748,7 @@ static const vshCmdDef domManagementCmds[] = {
{"setmaxmem", cmdSetmaxmem, opts_setmaxmem, info_setmaxmem},
{"setmem", cmdSetmem, opts_setmem, info_setmem},
{"setvcpus", cmdSetvcpus, opts_setvcpus, info_setvcpus},
+ {"sendevent", cmdSendEvent, opts_sendevent, info_sendevent},
{"shutdown", cmdShutdown, opts_shutdown, info_shutdown},
{"start", cmdStart, opts_start, info_start},
{"suspend", cmdSuspend, opts_suspend, info_suspend},
13 years, 7 months
[libvirt] snapshots += domain description?
by Philipp Hahn
Hello,
I just encountered a problem with the current snapshot implementation for
qemu/kvm: To revert back to a snapshot, the domain description must closely
match the domain description when the snapshot was created. If the ram-size
doesn't match or the VM now contains fewer CPUs or contains additional disks,
kvm will either not load the snapshot or the machine will be broken
afterwarts.
Is this a known problem?
Without looking into the implementation details I think saving the full domain
description instead of just a reference to the domain uuid as part of the
snapshot description would work better. Or am I supposed to save the domain
description myself in addition the the data saved
in /var/lib/libvirt/qemu/snapshot/$DOMAIN_NAME/$SNAPSHOT_NAME.xml. I think
this is very important feature, because when you - for example - notice that
you need additional disk space and would like to include an additional block
device, this is your ideal time to take a snapshot you can revert to when you
do something wrong.
Looking at VMware I see that reverting a VM there will not only revert the
disks and ram back to the saved state, but also the description including
name, ram size, etc.
Any comment or advise is appreciated.
Sincerely
Philipp Hahn
--
Philipp Hahn Open Source Software Engineer hahn(a)univention.de
Univention GmbH Linux for Your Business fon: +49 421 22 232- 0
Mary-Somerville-Str.1 28359 Bremen fax: +49 421 22 232-99
http://www.univention.de
13 years, 8 months
[libvirt] Is there smt missing at Java bindings?
by kadir yüceer
Hello all,
I've been posting questions about my issue to the user list but it seems
nobody can answer, so I had to try this list, sorry if there is any
disturbance.
Here is the case:
I've been trying to develop a java app that can register callbacks for
domain lifecycle events(suspend,resume,etc.). Only method that I've seen is
Connect.VirDomainEventRegisterAny, and there is an abstract callback method
inside VirConnectDomainEventGenericCallback. I implement the callback, and
register it for all the domains by passing the domain pointer as NULL.
Additionally for testing, I've added a println into the suspend function in
org.libvirt.Domain.java, and compiled the java bindings and used the new jar
file, and I was successful, I can see the message whenever I suspend the
domain either by clicking *pause* or by writing dom.suspend() in my java
app.
However, when I try to register a callback as I mentioned in the beginning
(with eventID 0, which is life_cycle ID), after the suspend operation, I get
the error that you can see at the end of the mail.
But before you check it out, I have to ask, are some of the event-related
features of libvirt missing in java bindings? For example;
VirEventAddHandleFunc, VirEventAddHandleCallback, and their derivatives. Is
this a problem or the only Connect.VirDomainEventRegisterAny method of java
binding suffice for providing callbacks for domain events?
Thanks in advance for your responses. The error is below.
Kind Regards
Kadir
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00000000, pid=5692, tid=3077520240
#
# JRE version: 6.0_20-b20
# Java VM: OpenJDK Server VM (19.0-b09 mixed mode linux-x86 )
# Derivative: IcedTea6 1.9.7
# Distribution: Ubuntu 10.10, package 6b20-1.9.7-0ubuntu1
# Problematic frame:
# C 0x00000000
#
# An error report file with more information is saved as:
# /root/NetBeansProjects/NovaTest_v0.3/hs_err_pid5692.log
#
# If you would like to submit a bug report, please include
# instructions how to reproduce the bug and visit:
# https://bugs.launchpad.net/ubuntu/+source/openjdk-6/
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Java Result: 134
13 years, 8 months
[libvirt] [PATCH] qemu: Fix -chardev udp if parameters are omitted
by Cole Robinson
The following XML:
<serial type='udp'>
<source mode='connect' service='9999'/>
</serial>
is accepted by domain_conf.c but maps to the qemu command line:
-chardev udp,host=127.0.0.1,port=2222,localaddr=(null),localport=(null)
qemu can cope with everything omitting except the connection port, which
seems to also be the intent of domain_conf validation, so let's not
generate bogus command lines for that case.
Additionally, tweak the qemu cli parsing to handle omitted host parameters
for -serial udp
---
src/qemu/qemu_command.c | 48 +++++++++++---------
.../qemuxml2argv-serial-udp-chardev.args | 6 ++-
.../qemuxml2argv-serial-udp-chardev.xml | 4 ++
.../qemuxml2argvdata/qemuxml2argv-serial-udp.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml | 4 ++
5 files changed, 39 insertions(+), 25 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c9b9850..231d7c3 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2119,14 +2119,17 @@ qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias,
break;
case VIR_DOMAIN_CHR_TYPE_UDP:
- virBufferVSprintf(&buf,
- "udp,id=char%s,host=%s,port=%s,localaddr=%s,"
- "localport=%s",
+ virBufferVSprintf(&buf, "udp,id=char%s,port=%s",
alias,
- dev->data.udp.connectHost,
- dev->data.udp.connectService,
- dev->data.udp.bindHost,
- dev->data.udp.bindService);
+ dev->data.udp.connectService);
+
+ if (dev->data.udp.connectHost)
+ virBufferVSprintf(&buf, ",host=%s", dev->data.udp.connectHost);
+ if (dev->data.udp.bindHost)
+ virBufferVSprintf(&buf, ",localaddr=%s", dev->data.udp.bindHost);
+ if (dev->data.udp.bindService)
+ virBufferVSprintf(&buf, ",localport=%s",
+ dev->data.udp.bindService);
break;
case VIR_DOMAIN_CHR_TYPE_TCP:
@@ -2216,11 +2219,13 @@ qemuBuildChrArgStr(virDomainChrSourceDefPtr dev, const char *prefix)
break;
case VIR_DOMAIN_CHR_TYPE_UDP:
- virBufferVSprintf(&buf, "udp:%s:%s@%s:%s",
- dev->data.udp.connectHost,
- dev->data.udp.connectService,
- dev->data.udp.bindHost,
- dev->data.udp.bindService);
+ virBufferVSprintf(&buf, "udp:%s:%s",
+ dev->data.udp.connectHost ?: "",
+ dev->data.udp.connectService);
+ if (dev->data.udp.bindService)
+ virBufferVSprintf(&buf, "@%s:%s",
+ dev->data.udp.bindHost ?: "",
+ dev->data.udp.bindService);
break;
case VIR_DOMAIN_CHR_TYPE_TCP:
@@ -5302,13 +5307,12 @@ qemuParseCommandLineChr(const char *val)
host2 = svc1 ? strchr(svc1, '@') : NULL;
svc2 = host2 ? strchr(host2, ':') : NULL;
- if (svc1)
+ if (svc1 && (svc1 != val)) {
def->source.data.udp.connectHost = strndup(val, svc1-val);
- else
- def->source.data.udp.connectHost = strdup(val);
- if (!def->source.data.udp.connectHost)
- goto no_memory;
+ if (!def->source.data.udp.connectHost)
+ goto no_memory;
+ }
if (svc1) {
svc1++;
@@ -5323,14 +5327,14 @@ qemuParseCommandLineChr(const char *val)
if (host2) {
host2++;
- if (svc2)
+ if (svc2 && (svc2 != host2)) {
def->source.data.udp.bindHost = strndup(host2, svc2-host2);
- else
- def->source.data.udp.bindHost = strdup(host2);
- if (!def->source.data.udp.bindHost)
- goto no_memory;
+ if (!def->source.data.udp.bindHost)
+ goto no_memory;
+ }
}
+
if (svc2) {
svc2++;
def->source.data.udp.bindService = strdup(svc2);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args
index 7525110..8c6a6d5 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args
@@ -2,6 +2,8 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,\
id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,\
id=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev \
-udp,id=charserial0,host=127.0.0.1,port=9998,localaddr=127.0.0.1,localport=9999 \
--device isa-serial,chardev=charserial0,id=serial0 -usb -device \
+udp,id=charserial0,port=9998,host=127.0.0.1,localaddr=127.0.0.1,localport=9999 \
+-device isa-serial,chardev=charserial0,id=serial0 \
+-chardev udp,id=charserial1,port=9999 \
+-device isa-serial,chardev=charserial1,id=serial1 -usb -device \
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml
index 12622d4..9627c67 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml
@@ -25,6 +25,10 @@
<source mode='connect' host='127.0.0.1' service='9998'/>
<target port='0'/>
</serial>
+ <serial type='udp'>
+ <source mode='connect' service='9999'/>
+ <target port='1'/>
+ </serial>
<console type='udp'>
<source mode='bind' host='127.0.0.1' service='9999'/>
<source mode='connect' host='127.0.0.1' service='9998'/>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.args
index 53c69bc..cf25fe0 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.args
@@ -1,4 +1,4 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait \
-no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial \
-udp:127.0.0.1:9998@127.0.0.1:9999 -parallel none -usb
+udp:127.0.0.1:9998@127.0.0.1:9999 -serial udp::9999 -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml
index 8697f5a..f606ea4 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml
@@ -25,6 +25,10 @@
<source mode='connect' host='127.0.0.1' service='9998'/>
<target port='0'/>
</serial>
+ <serial type='udp'>
+ <source mode='connect' service='9999'/>
+ <target port='1'/>
+ </serial>
<console type='udp'>
<source mode='bind' host='127.0.0.1' service='9999'/>
<source mode='connect' host='127.0.0.1' service='9998'/>
--
1.7.4
13 years, 8 months
[libvirt] [BUG] Re: [2/6] loadvm: improve tests before bdrv_snapshot_goto()
by Philipp Hahn
Hello,
Am Dienstag 03 August 2010 06:44:26 schrieb Kevin Wolf:
> From: Miguel Di Ciurcio Filho <miguel.filho(a)gmail.com>
>
> This patch improves the resilience of the load_vmstate() function, doing
> further and better ordered tests.
This patch broke restoring not-running VMs using libvirt-0.8.7 with qemu-0.14:
When the domain is not running while taking a snpshot, the sn.vm_state_size
== 0:
2021 } else if (sn.vm_state_size == 0) {
(gdb) print sn
$6 = {id_str = "1", '\0' <repeats 126 times>, name = "pre-update-flash", '\0'
<repeats 239 times>, vm_state_size = 0, date_sec = 1302698007, date_nsec =
711909000,
vm_clock_nsec = 0}
> The [old] process:
...
> - run bdrv_snapshot_goto() on devices
> - if fails, give an warning and goes to the next (not good!)
> - if fails on the VM state device, return zero (not good!)
> - check if the requested snapshot exists on the device that saves the VM
> state and the state is not zero
> - if fails return -error
Previously the qcow2 image was still reverted to the old state, so on the next
start of the domain the qcow2 image would be in the state of the snapshot
> New behavior:
...
> - check if the requested snapshot exists on the device that saves the VM
> state and the state is not zero
> - if fails return -error
...
> - run snapshot_goto() on devices
Now the qcow2 image is not reverted and when the domain is started, it is NOT
in the state of the snapshot.
I can't decide if this regression is an Qemu bug or libvirt should be adapted
to this new behavior.
I found the Bug also reported with Ubuntu and created a Bug in our own German
bugtracker:
<https://bugs.launchpad.net/qemu/+bug/726619>
<https://forge.univention.org/bugzilla/show_bug.cgi?id=22221>
Sincerely
Philipp Hahn
--
Philipp Hahn Open Source Software Engineer hahn(a)univention.de
Univention GmbH Linux for Your Business fon: +49 421 22 232- 0
Mary-Somerville-Str.1 D-28359 Bremen fax: +49 421 22 232-99
http://www.univention.de/
13 years, 8 months
[libvirt] [PATCH] freebsd: Fix build problem due to picking up the wrong libvirt.h
by Matthias Bolte
AM_GNU_GETTEXT calls AM_ICONV_LINK. AM_ICONV_LINK saves and alters
CPPFLAGS, but doesn't restore it when it finds libiconv. This
results in /usr/local/include ending up in the gcc command line
before the include path for the local include directory. This makes
gcc pick a previous installed libvirt.h instead of the correct one
from the source tree.
Workaround this problem by saving and restoring CPPFLAGS around
the AM_GNU_GETTEXT call.
---
configure.ac | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/configure.ac b/configure.ac
index b2ba930..8f46dbd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2011,8 +2011,16 @@ dnl Enable building libvirtd?
AM_CONDITIONAL([WITH_LIBVIRTD],[test "x$with_libvirtd" = "xyes"])
dnl Check for gettext - don't go any newer than what RHEL 5 supports
+dnl
+dnl save and restore CPPFLAGS around gettext check as the internal iconv
+dnl check might leave -I/usr/local/include in CPPFLAGS on FreeBSD resulting
+dnl in the build picking up previously installed libvirt/libvirt.h instead
+dnl of the correct one from the soucre tree
+
+save_CPPFLAGS="$CPPFLAGS"
AM_GNU_GETTEXT_VERSION([0.17])
AM_GNU_GETTEXT([external])
+CPPFLAGS="$save_CPPFLAGS"
ALL_LINGUAS=`cd "$srcdir/po" > /dev/null && ls *.po | sed 's+\.po$++'`
--
1.7.0.4
13 years, 8 months
[libvirt] [PATCH] storage: fix volDelete return when volume still being allocated
by Matthew Booth
volDelete used to return VIR_ERR_INTERNAL_ERROR when attempting to delete a
volume which was still being allocated. It should return
VIR_ERR_OPERATION_INVALID.
* src/storage/storage_driver.c: Fix return of volDelete.
---
src/storage/storage_driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 2da2feb..d9c2137 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -1914,7 +1914,7 @@ storageVolumeDelete(virStorageVolPtr obj,
}
if (vol->building) {
- virStorageReportError(VIR_ERR_INTERNAL_ERROR,
+ virStorageReportError(VIR_ERR_OPERATION_INVALID,
_("volume '%s' is still being allocated."),
vol->name);
goto cleanup;
--
1.7.4.4
13 years, 9 months
[libvirt] [V2 Patch] virsh: Change log level order
by Supriya Kannery
Change log level order so that messages at all other levels get logged
for "DEBUG" level. Replace magic numbers with corresponding VSH_ERR_xx.
Signed-off-by: Supriya Kannery <supriyak(a)in.ibm.com>
---
tools/virsh.c | 119
++++++++++++++++++++++++++++++++--------------------------
1 file changed, 67 insertions(+), 52 deletions(-)
Index: libvirt/tools/virsh.c
===================================================================
--- libvirt.orig/tools/virsh.c
+++ libvirt/tools/virsh.c
@@ -91,11 +91,11 @@ static char *progname;
* Indicates the level of a log message
*/
typedef enum {
- VSH_ERR_DEBUG = 0,
- VSH_ERR_INFO,
- VSH_ERR_NOTICE,
+ VSH_ERR_ERROR = 0,
VSH_ERR_WARNING,
- VSH_ERR_ERROR
+ VSH_ERR_NOTICE,
+ VSH_ERR_INFO,
+ VSH_ERR_DEBUG
} vshErrorLevel;
/*
@@ -2146,7 +2146,8 @@ cmdDominfo(vshControl *ctl, const vshCmd
/* Check and display whether the domain is persistent or not */
persistent = virDomainIsPersistent(dom);
- vshDebug(ctl, 5, "Domain persistent flag value: %d\n", persistent);
+ vshDebug(ctl, VSH_ERR_DEBUG, "Domain persistent flag value: %d\n",
+ persistent);
if (persistent < 0)
vshPrint(ctl, "%-15s %s\n", _("Persistent:"), _("unknown"));
else
@@ -2928,7 +2929,7 @@ cmdSetvcpus(vshControl *ctl, const vshCm
/* If the --maximum flag was given, we need to ensure only the
--config flag is in effect as well */
if (maximum) {
- vshDebug(ctl, 5, "--maximum flag was given\n");
+ vshDebug(ctl, VSH_ERR_DEBUG, "--maximum flag was given\n");
/* If neither the --config nor --live flags were given, OR
if just the --live flag was given, we need to error out
@@ -4020,7 +4021,7 @@ repoll:
if ( timeout && ((int)(curr.tv_sec - start.tv_sec) * 1000 + \
(int)(curr.tv_usec - start.tv_usec) / 1000) >
timeout * 1000 ) {
/* suspend the domain when migration timeouts. */
- vshDebug(ctl, 5, "suspend the domain when migration
timeouts\n");
+ vshDebug(ctl, VSH_ERR_DEBUG, "suspend the domain when
migration timeouts\n");
virDomainSuspend(dom);
timeout = 0;
}
@@ -6125,7 +6126,8 @@ cmdPoolList(vshControl *ctl, const vshCm
/* Retrieve the persistence status of the pool */
if (details) {
persistent = virStoragePoolIsPersistent(pool);
- vshDebug(ctl, 5, "Persistent flag value: %d\n", persistent);
+ vshDebug(ctl, VSH_ERR_DEBUG, "Persistent flag value: %d\n",
+ persistent);
if (persistent < 0)
poolInfoTexts[i].persistent = vshStrdup(ctl,
_("unknown"));
else
@@ -6316,19 +6318,19 @@ cmdPoolList(vshControl *ctl, const vshCm
availStrLength = stringLength;
/* Display the string lengths for debugging. */
- vshDebug(ctl, 5, "Longest name string = %lu chars\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "Longest name string = %lu chars\n",
(unsigned long) nameStrLength);
- vshDebug(ctl, 5, "Longest state string = %lu chars\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "Longest state string = %lu chars\n",
(unsigned long) stateStrLength);
- vshDebug(ctl, 5, "Longest autostart string = %lu chars\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "Longest autostart string = %lu chars\n",
(unsigned long) autostartStrLength);
- vshDebug(ctl, 5, "Longest persistent string = %lu chars\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "Longest persistent string = %lu chars\n",
(unsigned long) persistStrLength);
- vshDebug(ctl, 5, "Longest capacity string = %lu chars\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "Longest capacity string = %lu chars\n",
(unsigned long) capStrLength);
- vshDebug(ctl, 5, "Longest allocation string = %lu chars\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "Longest allocation string = %lu chars\n",
(unsigned long) allocStrLength);
- vshDebug(ctl, 5, "Longest available string = %lu chars\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "Longest available string = %lu chars\n",
(unsigned long) availStrLength);
/* Create the output template. Each column is sized according to
@@ -6600,7 +6602,8 @@ cmdPoolInfo(vshControl *ctl, const vshCm
/* Check and display whether the pool is persistent or not */
persistent = virStoragePoolIsPersistent(pool);
- vshDebug(ctl, 5, "Pool persistent flag value: %d\n", persistent);
+ vshDebug(ctl, VSH_ERR_DEBUG, "Pool persistent flag value: %d\n",
+ persistent);
if (persistent < 0)
vshPrint(ctl, "%-15s %s\n", _("Persistent:"), _("unknown"));
else
@@ -6608,7 +6611,7 @@ cmdPoolInfo(vshControl *ctl, const vshCm
/* Check and display whether the pool is autostarted or not */
virStoragePoolGetAutostart(pool, &autostart);
- vshDebug(ctl, 5, "Pool autostart flag value: %d\n", autostart);
+ vshDebug(ctl, VSH_ERR_DEBUG, "Pool autostart flag value: %d\n",
autostart);
if (autostart < 0)
vshPrint(ctl, "%-15s %s\n", _("Autostart:"), _("no
autostart"));
else
@@ -6806,31 +6809,37 @@ cmdVolCreateAs(vshControl *ctl, const vs
if (snapshotStrVol) {
/* Lookup snapshot backing volume. Try the backing-vol
* parameter as a name */
- vshDebug(ctl, 5, "%s: Look up backing store volume '%s' as name\n",
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "%s: Look up backing store volume '%s' as name\n",
cmd->def->name, snapshotStrVol);
virStorageVolPtr snapVol = virStorageVolLookupByName(pool,
snapshotStrVol);
if (snapVol)
- vshDebug(ctl, 5, "%s: Backing store volume found using
'%s' as name\n",
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "%s: Backing store volume found using '%s' as
name\n",
cmd->def->name, snapshotStrVol);
if (snapVol == NULL) {
/* Snapshot backing volume not found by name. Try the
* backing-vol parameter as a key */
- vshDebug(ctl, 5, "%s: Look up backing store volume '%s' as
key\n",
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "%s: Look up backing store volume '%s' as key\n",
cmd->def->name, snapshotStrVol);
snapVol = virStorageVolLookupByKey(ctl->conn, snapshotStrVol);
if (snapVol)
- vshDebug(ctl, 5, "%s: Backing store volume found using
'%s' as key\n",
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "%s: Backing store volume found using '%s' as
key\n",
cmd->def->name, snapshotStrVol);
}
if (snapVol == NULL) {
/* Snapshot backing volume not found by key. Try the
* backing-vol parameter as a path */
- vshDebug(ctl, 5, "%s: Look up backing store volume '%s' as
path\n",
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "%s: Look up backing store volume '%s' as path\n",
cmd->def->name, snapshotStrVol);
snapVol = virStorageVolLookupByPath(ctl->conn,
snapshotStrVol);
if (snapVol)
- vshDebug(ctl, 5, "%s: Backing store volume found using
'%s' as path\n",
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "%s: Backing store volume found using '%s' as
path\n",
cmd->def->name, snapshotStrVol);
}
if (snapVol == NULL) {
@@ -7777,11 +7786,16 @@ cmdVolList(vshControl *ctl, const vshCmd
allocStrLength = stringLength;
/* Display the string lengths for debugging */
- vshDebug(ctl, 5, "Longest name string = %zu chars\n", nameStrLength);
- vshDebug(ctl, 5, "Longest path string = %zu chars\n", pathStrLength);
- vshDebug(ctl, 5, "Longest type string = %zu chars\n", typeStrLength);
- vshDebug(ctl, 5, "Longest capacity string = %zu chars\n",
capStrLength);
- vshDebug(ctl, 5, "Longest allocation string = %zu chars\n",
allocStrLength);
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "Longest name string = %zu chars\n", nameStrLength);
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "Longest path string = %zu chars\n", pathStrLength);
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "Longest type string = %zu chars\n", typeStrLength);
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "Longest capacity string = %zu chars\n", capStrLength);
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "Longest allocation string = %zu chars\n", allocStrLength);
/* Create the output template */
ret = virAsprintf(&outputStr,
@@ -11535,7 +11549,7 @@ vshCommandOptDomainBy(vshControl *ctl, c
if (vshCommandOptString(cmd, optname, &n) <= 0)
return NULL;
- vshDebug(ctl, 5, "%s: found option <%s>: %s\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: found option <%s>: %s\n",
cmd->def->name, optname, n);
if (name)
@@ -11544,20 +11558,20 @@ vshCommandOptDomainBy(vshControl *ctl, c
/* try it by ID */
if (flag & VSH_BYID) {
if (virStrToLong_i(n, NULL, 10, &id) == 0 && id >= 0) {
- vshDebug(ctl, 5, "%s: <%s> seems like domain ID\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> seems like domain ID\n",
cmd->def->name, optname);
dom = virDomainLookupByID(ctl->conn, id);
}
}
/* try it by UUID */
if (dom==NULL && (flag & VSH_BYUUID) &&
strlen(n)==VIR_UUID_STRING_BUFLEN-1) {
- vshDebug(ctl, 5, "%s: <%s> trying as domain UUID\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as domain UUID\n",
cmd->def->name, optname);
dom = virDomainLookupByUUIDString(ctl->conn, n);
}
/* try it by NAME */
if (dom==NULL && (flag & VSH_BYNAME)) {
- vshDebug(ctl, 5, "%s: <%s> trying as domain NAME\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as domain NAME\n",
cmd->def->name, optname);
dom = virDomainLookupByName(ctl->conn, n);
}
@@ -11581,7 +11595,7 @@ vshCommandOptNetworkBy(vshControl *ctl,
if (vshCommandOptString(cmd, optname, &n) <= 0)
return NULL;
- vshDebug(ctl, 5, "%s: found option <%s>: %s\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: found option <%s>: %s\n",
cmd->def->name, optname, n);
if (name)
@@ -11589,13 +11603,13 @@ vshCommandOptNetworkBy(vshControl *ctl,
/* try it by UUID */
if ((flag & VSH_BYUUID) && (strlen(n) == VIR_UUID_STRING_BUFLEN-1)) {
- vshDebug(ctl, 5, "%s: <%s> trying as network UUID\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as network UUID\n",
cmd->def->name, optname);
network = virNetworkLookupByUUIDString(ctl->conn, n);
}
/* try it by NAME */
if (network==NULL && (flag & VSH_BYNAME)) {
- vshDebug(ctl, 5, "%s: <%s> trying as network NAME\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as network NAME\n",
cmd->def->name, optname);
network = virNetworkLookupByName(ctl->conn, n);
}
@@ -11620,7 +11634,7 @@ vshCommandOptNWFilterBy(vshControl *ctl,
if (vshCommandOptString(cmd, optname, &n) <= 0)
return NULL;
- vshDebug(ctl, 5, "%s: found option <%s>: %s\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: found option <%s>: %s\n",
cmd->def->name, optname, n);
if (name)
@@ -11628,13 +11642,13 @@ vshCommandOptNWFilterBy(vshControl *ctl,
/* try it by UUID */
if ((flag & VSH_BYUUID) && (strlen(n) == VIR_UUID_STRING_BUFLEN-1)) {
- vshDebug(ctl, 5, "%s: <%s> trying as nwfilter UUID\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as nwfilter UUID\n",
cmd->def->name, optname);
nwfilter = virNWFilterLookupByUUIDString(ctl->conn, n);
}
/* try it by NAME */
if (nwfilter == NULL && (flag & VSH_BYNAME)) {
- vshDebug(ctl, 5, "%s: <%s> trying as nwfilter NAME\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as nwfilter NAME\n",
cmd->def->name, optname);
nwfilter = virNWFilterLookupByName(ctl->conn, n);
}
@@ -11658,7 +11672,7 @@ vshCommandOptInterfaceBy(vshControl *ctl
if (vshCommandOptString(cmd, optname, &n) <= 0)
return NULL;
- vshDebug(ctl, 5, "%s: found option <%s>: %s\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: found option <%s>: %s\n",
cmd->def->name, optname, n);
if (name)
@@ -11666,13 +11680,13 @@ vshCommandOptInterfaceBy(vshControl *ctl
/* try it by NAME */
if ((flag & VSH_BYNAME)) {
- vshDebug(ctl, 5, "%s: <%s> trying as interface NAME\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as interface NAME\n",
cmd->def->name, optname);
iface = virInterfaceLookupByName(ctl->conn, n);
}
/* try it by MAC */
if ((iface == NULL) && (flag & VSH_BYMAC)) {
- vshDebug(ctl, 5, "%s: <%s> trying as interface MAC\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as interface MAC\n",
cmd->def->name, optname);
iface = virInterfaceLookupByMACString(ctl->conn, n);
}
@@ -11693,7 +11707,7 @@ vshCommandOptPoolBy(vshControl *ctl, con
if (vshCommandOptString(cmd, optname, &n) <= 0)
return NULL;
- vshDebug(ctl, 5, "%s: found option <%s>: %s\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: found option <%s>: %s\n",
cmd->def->name, optname, n);
if (name)
@@ -11701,13 +11715,13 @@ vshCommandOptPoolBy(vshControl *ctl, con
/* try it by UUID */
if ((flag & VSH_BYUUID) && (strlen(n) == VIR_UUID_STRING_BUFLEN-1)) {
- vshDebug(ctl, 5, "%s: <%s> trying as pool UUID\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as pool UUID\n",
cmd->def->name, optname);
pool = virStoragePoolLookupByUUIDString(ctl->conn, n);
}
/* try it by NAME */
if (pool == NULL && (flag & VSH_BYNAME)) {
- vshDebug(ctl, 5, "%s: <%s> trying as pool NAME\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as pool NAME\n",
cmd->def->name, optname);
pool = virStoragePoolLookupByName(ctl->conn, n);
}
@@ -11739,7 +11753,7 @@ vshCommandOptVolBy(vshControl *ctl, cons
if (p)
pool = vshCommandOptPoolBy(ctl, cmd, pooloptname, name, flag);
- vshDebug(ctl, 5, "%s: found option <%s>: %s\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: found option <%s>: %s\n",
cmd->def->name, optname, n);
if (name)
@@ -11747,19 +11761,19 @@ vshCommandOptVolBy(vshControl *ctl, cons
/* try it by name */
if (pool && (flag & VSH_BYNAME)) {
- vshDebug(ctl, 5, "%s: <%s> trying as vol name\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol name\n",
cmd->def->name, optname);
vol = virStorageVolLookupByName(pool, n);
}
/* try it by key */
if (vol == NULL && (flag & VSH_BYUUID)) {
- vshDebug(ctl, 5, "%s: <%s> trying as vol key\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol key\n",
cmd->def->name, optname);
vol = virStorageVolLookupByKey(ctl->conn, n);
}
/* try it by path */
if (vol == NULL && (flag & VSH_BYUUID)) {
- vshDebug(ctl, 5, "%s: <%s> trying as vol path\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol path\n",
cmd->def->name, optname);
vol = virStorageVolLookupByPath(ctl->conn, n);
}
@@ -11786,7 +11800,8 @@ vshCommandOptSecret(vshControl *ctl, con
if (vshCommandOptString(cmd, optname, &n) <= 0)
return NULL;
- vshDebug(ctl, 5, "%s: found option <%s>: %s\n", cmd->def->name,
optname, n);
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: found option <%s>: %s\n",
+ cmd->def->name, optname, n);
if (name != NULL)
*name = n;
@@ -11991,7 +12006,7 @@ get_data:
last->next = arg;
last = arg;
- vshDebug(ctl, 4, "%s: %s(%s): %s\n",
+ vshDebug(ctl, VSH_ERR_DEBUG, "%s: %s(%s): %s\n",
cmd->name,
opt->name,
opt->type != VSH_OT_BOOL ? _("optdata") :
_("bool"),
@@ -12416,7 +12431,7 @@ vshInit(vshControl *ctl)
debugEnv = getenv("VIRSH_DEBUG");
if (debugEnv) {
if (virStrToLong_i(debugEnv, NULL, 10, &ctl->debug) < 0 ||
- ctl->debug < VSH_ERR_DEBUG || ctl->debug > VSH_ERR_ERROR) {
+ ctl->debug > VSH_ERR_DEBUG || ctl->debug < VSH_ERR_ERROR) {
vshError(ctl, "%s",
_("VIRSH_DEBUG not set with a valid numeric
value"));
ctl->debug = VSH_ERR_DEBUG;
@@ -13088,7 +13103,7 @@ vshParseArgv(vshControl *ctl, int argc,
/* parse command */
ctl->imode = false;
if (argc - optind == 1) {
- vshDebug(ctl, 2, "commands: \"%s\"\n", argv[optind]);
+ vshDebug(ctl, VSH_ERR_NOTICE, "commands: \"%s\"\n",
argv[optind]);
return vshCommandStringParse(ctl, argv[optind]);
} else {
return vshCommandArgvParse(ctl, argc - optind, argv + optind);
13 years, 9 months
[libvirt] Appending REJECT rules.
by Stephen O'Dor
Greetings folks,
I've patched the libvirt iptables interface to append it's REJECT
rules rather than insert at the head. Idea being that I'm not the only
person who usually puts the REJECTs at the end of a chain.
In my particular case any custom ACCEPT rules involving the bridge
interfaces would get pushed below the rules that libvirt puts in to
REJECT everything on the bridge interface.
I'm using the routed network mode, I have no idea if this hurts any
other network mode.
Thanks,
-Steve
--- iptables.c 2011-02-28 23:03:32.000000000 -0800
+++ iptables.c_new 2011-05-18 14:00:59.110855881 -0700
@@ -51,7 +51,8 @@
enum {
ADD = 0,
- REMOVE
+ REMOVE,
+ APPEND
};
typedef struct
@@ -111,7 +112,7 @@
? IP6TABLES_PATH : IPTABLES_PATH);
virCommandAddArgList(cmd, "--table", rules->table,
- action == ADD ? "--insert" : "--delete",
+ action == ADD ? "--insert" : action ==
REMOVE ? "--delete" : "--append",
rules->chain, arg, NULL);
va_start(args, arg);
@@ -666,7 +667,7 @@
int family,
const char *iface)
{
- return iptablesForwardRejectOut(ctx, family, iface, ADD);
+ return iptablesForwardRejectOut(ctx, family, iface, APPEND);
}
/**
@@ -722,7 +723,7 @@
int family,
const char *iface)
{
- return iptablesForwardRejectIn(ctx, family, iface, ADD);
+ return iptablesForwardRejectIn(ctx, family, iface, APPEND);
}
/**
13 years, 9 months
[libvirt] [PATCH 0/2] Replace all remaining setgid calls with virSetUIDGID
by Jiri Denemark
Should we also ban setgid/setuid usage since we probably want to call
initgroups after them anyway?
Jiri Denemark (2):
util: Keep errno set to the root error after when returning from
virSetUIDGID
Replace all remaining setgid/setuid calls with virSetUIDGID
src/storage/storage_backend.c | 15 +----------
src/util/util.c | 53 +++++++++++++++++------------------------
2 files changed, 24 insertions(+), 44 deletions(-)
--
1.7.5.rc3
13 years, 9 months