[libvirt] [PATCH 0/2] don't masquerade local broadcast/multicast packets
by Laszlo Ersek
Masquerading local broadcast breaks DHCP replies for some clients.
There has been a report about broken local multicast too.
(See references in the patches.)
Testing: since I have no idea how to test upstream libvirt on a
RHEL-6.4.z virt host and guarantee nothing will be tangled up, I ported
the series to libvirt-0.10.2-18.el6_4.5 and tested that. (The upstream
series does build and passes the checks in HACKING, except I didn't try
valgrind.)
Laszlo Ersek (2):
util/viriptables: add/remove rules that short-circuit masquerading
bridge driver: don't masquerade local subnet broadcast/multicast
packets
src/util/viriptables.h | 10 +++++
src/network/bridge_driver.c | 76 +++++++++++++++++++++++++++++++++--
src/util/viriptables.c | 93 +++++++++++++++++++++++++++++++++++++++++++
src/libvirt_private.syms | 2 +
4 files changed, 177 insertions(+), 4 deletions(-)
11 years, 6 months
[libvirt] [PATCH v3 0/3] libvirt supports Guest panicked
by Chen Fan
This patchs implement the 'on_crash' behavior in the XML
example XML:
<on_crash>destroy</on_crash>
Changes:
v2-v3: 1. split into 3 patches
v1-v2: 1. fix the incorrect domain state: paused -> crashed, when crash
the guest while libvirt isn't running, then restart libvirtd.
Chen Fan (3):
libvirt: Define domain crash event types
qemu: Supports guest panicked
virsh: supports guest panicked
examples/domain-events/events-c/event-test.c | 10 +++
include/libvirt/libvirt.h.in | 16 +++++
src/conf/domain_conf.c | 12 ++--
src/qemu/qemu_monitor.c | 14 +++-
src/qemu/qemu_monitor.h | 5 ++
src/qemu/qemu_monitor_json.c | 7 ++
src/qemu/qemu_process.c | 103 ++++++++++++++++++++++++++-
tools/virsh-domain-monitor.c | 8 +++
8 files changed, 169 insertions(+), 6 deletions(-)
--
1.8.1.4
11 years, 6 months
[libvirt] [PATCH v2] libvirt supports Guest Panicked
by Chen Fan
From: ChenFan <chen.fan.fnst(a)cn.fujitsu.com>
This patch implements qemu_driver supporting guest panicked.
we crashed the guest while libvirt isn't running, then restart libvirtd, we change the domain state to 'crashed'.
---
examples/domain-events/events-c/event-test.c | 10 +++
include/libvirt/libvirt.h.in | 16 +++++
src/conf/domain_conf.c | 12 ++--
src/qemu/qemu_monitor.c | 14 +++-
src/qemu/qemu_monitor.h | 5 ++
src/qemu/qemu_monitor_json.c | 7 ++
src/qemu/qemu_process.c | 103 ++++++++++++++++++++++++++-
tools/virsh-domain-monitor.c | 8 +++
8 files changed, 169 insertions(+), 6 deletions(-)
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c
index eeff50f..1b425fb 100644
--- a/examples/domain-events/events-c/event-test.c
+++ b/examples/domain-events/events-c/event-test.c
@@ -93,6 +93,9 @@ const char *eventToString(int event) {
case VIR_DOMAIN_EVENT_PMSUSPENDED:
ret = "PMSuspended";
break;
+ case VIR_DOMAIN_EVENT_CRASHED:
+ ret = "Crashed";
+ break;
}
return ret;
}
@@ -209,6 +212,13 @@ static const char *eventDetailToString(int event, int detail) {
break;
}
break;
+ case VIR_DOMAIN_EVENT_CRASHED:
+ switch ((virDomainEventCrashedDetailType) detail) {
+ case VIR_DOMAIN_EVENT_CRASHED_PANICKED:
+ ret = "Panicked";
+ break;
+ }
+ break;
}
return ret;
}
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 1804c93..56c6c5c 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -155,6 +155,7 @@ typedef enum {
VIR_DOMAIN_RUNNING_SAVE_CANCELED = 7, /* returned from failed save process */
VIR_DOMAIN_RUNNING_WAKEUP = 8, /* returned from pmsuspended due to
wakeup event */
+ VIR_DOMAIN_RUNNING_CRASHED = 9, /* resumed from crashed */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_RUNNING_LAST
@@ -180,6 +181,7 @@ typedef enum {
VIR_DOMAIN_PAUSED_FROM_SNAPSHOT = 7, /* paused after restoring from snapshot */
VIR_DOMAIN_PAUSED_SHUTTING_DOWN = 8, /* paused during shutdown process */
VIR_DOMAIN_PAUSED_SNAPSHOT = 9, /* paused while creating a snapshot */
+ VIR_DOMAIN_PAUSED_GUEST_PANICKED = 10, /* paused due to a guest panicked event */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_PAUSED_LAST
@@ -189,6 +191,7 @@ typedef enum {
typedef enum {
VIR_DOMAIN_SHUTDOWN_UNKNOWN = 0, /* the reason is unknown */
VIR_DOMAIN_SHUTDOWN_USER = 1, /* shutting down on user request */
+ VIR_DOMAIN_SHUTDOWN_CRASHED = 2, /* domain crashed */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_SHUTDOWN_LAST
@@ -212,6 +215,7 @@ typedef enum {
typedef enum {
VIR_DOMAIN_CRASHED_UNKNOWN = 0, /* crashed for unknown reason */
+ VIR_DOMAIN_CRASHED_PANICKED = 1, /* domain panicked */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_CRASHED_LAST
@@ -3319,6 +3323,7 @@ typedef enum {
VIR_DOMAIN_EVENT_STOPPED = 5,
VIR_DOMAIN_EVENT_SHUTDOWN = 6,
VIR_DOMAIN_EVENT_PMSUSPENDED = 7,
+ VIR_DOMAIN_EVENT_CRASHED = 8,
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_LAST
@@ -3450,6 +3455,17 @@ typedef enum {
#endif
} virDomainEventPMSuspendedDetailType;
+/*
+ * Details about the 'crashed' lifecycle event
+ */
+typedef enum {
+ VIR_DOMAIN_EVENT_CRASHED_PANICKED = 0, /* Guest was panicked */
+
+#ifdef VIR_ENUM_SENTINELS
+ VIR_DOMAIN_EVENT_CRASHED_LAST
+#endif
+} virDomainEventCrashedDetailType;
+
/**
* virConnectDomainEventCallback:
* @conn: virConnect connection
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a9656af..f577fd4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -642,7 +642,8 @@ VIR_ENUM_IMPL(virDomainRunningReason, VIR_DOMAIN_RUNNING_LAST,
"unpaused",
"migration canceled",
"save canceled",
- "wakeup")
+ "wakeup",
+ "from crashed")
VIR_ENUM_IMPL(virDomainBlockedReason, VIR_DOMAIN_BLOCKED_LAST,
"unknown")
@@ -657,11 +658,13 @@ VIR_ENUM_IMPL(virDomainPausedReason, VIR_DOMAIN_PAUSED_LAST,
"watchdog",
"from snapshot",
"shutdown",
- "snapshot")
+ "snapshot",
+ "guest panicked")
VIR_ENUM_IMPL(virDomainShutdownReason, VIR_DOMAIN_SHUTDOWN_LAST,
"unknown",
- "user")
+ "user",
+ "crashed")
VIR_ENUM_IMPL(virDomainShutoffReason, VIR_DOMAIN_SHUTOFF_LAST,
"unknown",
@@ -674,7 +677,8 @@ VIR_ENUM_IMPL(virDomainShutoffReason, VIR_DOMAIN_SHUTOFF_LAST,
"from snapshot")
VIR_ENUM_IMPL(virDomainCrashedReason, VIR_DOMAIN_CRASHED_LAST,
- "unknown")
+ "unknown",
+ "panicked")
VIR_ENUM_IMPL(virDomainPMSuspendedReason, VIR_DOMAIN_PMSUSPENDED_LAST,
"unknown")
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 4e35f79..e0cd62c 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -113,7 +113,7 @@ VIR_ENUM_IMPL(qemuMonitorVMStatus,
QEMU_MONITOR_VM_STATUS_LAST,
"debug", "inmigrate", "internal-error", "io-error", "paused",
"postmigrate", "prelaunch", "finish-migrate", "restore-vm",
- "running", "save-vm", "shutdown", "watchdog")
+ "running", "save-vm", "shutdown", "watchdog", "guest-panicked")
typedef enum {
QEMU_MONITOR_BLOCK_IO_STATUS_OK,
@@ -1032,6 +1032,15 @@ int qemuMonitorEmitResume(qemuMonitorPtr mon)
}
+int qemuMonitorEmitGUESTPanicked(qemuMonitorPtr mon)
+{
+ int ret = -1;
+ VIR_DEBUG("mon=%p", mon);
+ QEMU_MONITOR_CALLBACK(mon, ret, domainGUESTPanicked, mon->vm);
+ return ret;
+}
+
+
int qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset)
{
int ret = -1;
@@ -3185,6 +3194,9 @@ int qemuMonitorVMStatusToPausedReason(const char *status)
case QEMU_MONITOR_VM_STATUS_WATCHDOG:
return VIR_DOMAIN_PAUSED_WATCHDOG;
+ case QEMU_MONITOR_VM_STATUS_GUEST_PANICKED:
+ return VIR_DOMAIN_PAUSED_GUEST_PANICKED;
+
/* unreachable from this point on */
case QEMU_MONITOR_VM_STATUS_LAST:
;
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index a607712..543050c 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -140,6 +140,8 @@ struct _qemuMonitorCallbacks {
unsigned long long actual);
int (*domainPMSuspendDisk)(qemuMonitorPtr mon,
virDomainObjPtr vm);
+ int (*domainGUESTPanicked)(qemuMonitorPtr mon,
+ virDomainObjPtr vm);
};
char *qemuMonitorEscapeArg(const char *in);
@@ -220,6 +222,8 @@ int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
unsigned long long actual);
int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon);
+int qemuMonitorEmitGUESTPanicked(qemuMonitorPtr mon);
+
int qemuMonitorStartCPUs(qemuMonitorPtr mon,
virConnectPtr conn);
@@ -239,6 +243,7 @@ typedef enum {
QEMU_MONITOR_VM_STATUS_SAVE_VM,
QEMU_MONITOR_VM_STATUS_SHUTDOWN,
QEMU_MONITOR_VM_STATUS_WATCHDOG,
+ QEMU_MONITOR_VM_STATUS_GUEST_PANICKED,
QEMU_MONITOR_VM_STATUS_LAST
} qemuMonitorVMStatus;
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 2b73884..b6efa52 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -74,6 +74,7 @@ static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJSONVal
static void qemuMonitorJSONHandleBlockJobReady(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, virJSONValuePtr data);
+static void qemuMonitorJSONHandleGUESTPanicked(qemuMonitorPtr mon, virJSONValuePtr data);
typedef struct {
const char *type;
@@ -87,6 +88,7 @@ static qemuEventHandler eventHandlers[] = {
{ "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJobCompleted, },
{ "BLOCK_JOB_READY", qemuMonitorJSONHandleBlockJobReady, },
{ "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
+ { "GUEST_PANICKED", qemuMonitorJSONHandleGUESTPanicked, },
{ "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
{ "RESET", qemuMonitorJSONHandleReset, },
{ "RESUME", qemuMonitorJSONHandleResume, },
@@ -593,6 +595,11 @@ static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, virJSONValuePtr data
qemuMonitorEmitResume(mon);
}
+static void qemuMonitorJSONHandleGUESTPanicked(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
+{
+ qemuMonitorEmitGUESTPanicked(mon);
+}
+
static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data)
{
long long offset = 0;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d4fd4fb..29c8c4b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -548,6 +548,7 @@ qemuProcessFakeReboot(void *opaque)
qemuDomainObjPrivatePtr priv = vm->privateData;
virDomainEventPtr event = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainRunningReason reason = VIR_DOMAIN_RUNNING_BOOTED;
int ret = -1;
VIR_DEBUG("vm=%p", vm);
virObjectLock(vm);
@@ -573,8 +574,11 @@ qemuProcessFakeReboot(void *opaque)
goto endjob;
}
+ if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_CRASHED)
+ reason = VIR_DOMAIN_RUNNING_CRASHED;
+
if (qemuProcessStartCPUs(driver, vm, NULL,
- VIR_DOMAIN_RUNNING_BOOTED,
+ reason,
QEMU_ASYNC_JOB_NONE) < 0) {
if (virGetLastError() == NULL)
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -1269,6 +1273,98 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
return 0;
}
+static int
+qemuProcessHandleGUESTPanicked(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm)
+{
+ virQEMUDriverPtr driver = qemu_driver;
+ qemuDomainObjPrivatePtr priv;
+ virDomainEventPtr event = NULL;
+ bool isReboot = true;
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+
+ VIR_DEBUG("vm=%p", vm);
+
+ virObjectLock(vm);
+
+ if (!virDomainObjIsActive(vm)) {
+ VIR_DEBUG("Ignoring GUEST_PANICKED event from inactive domain %s",
+ vm->def->name);
+ goto cleanup;
+ }
+
+ priv = vm->privateData;
+
+ virDomainObjSetState(vm,
+ VIR_DOMAIN_CRASHED,
+ VIR_DOMAIN_CRASHED_PANICKED);
+
+ event = virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_CRASHED,
+ VIR_DOMAIN_EVENT_CRASHED_PANICKED);
+
+ if (vm->def->onCrash == VIR_DOMAIN_LIFECYCLE_CRASH_PRESERVE) {
+ VIR_FREE(priv->lockState);
+
+ if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
+ VIR_WARN("Unable to release lease on %s", vm->def->name);
+ VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
+
+ if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) {
+ VIR_WARN("Unable to save status on vm %s after state change",
+ vm->def->name);
+ }
+
+ goto cleanup;
+ }
+
+ if (vm->def->onCrash == VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY) {
+ isReboot = false;
+ VIR_INFO("Domain on_crash setting overridden, shutting down");
+ }
+
+ qemuDomainSetFakeReboot(driver, vm, isReboot);
+
+ if (isReboot) {
+ qemuProcessShutdownOrReboot(driver, vm);
+ } else {
+ priv->beingDestroyed = true;
+
+ if (qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE) < 0) {
+ priv->beingDestroyed = false;
+ goto cleanup;
+ }
+
+ priv->beingDestroyed = false;
+
+ if (! virDomainObjIsActive(vm)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_CRASHED, 0);
+ event = virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_CRASHED);
+
+ virDomainAuditStop(vm, "destroyed");
+
+ if (! vm->persistent) {
+ qemuDomainRemoveInactive(driver, vm);
+ vm = NULL;
+ }
+ }
+
+cleanup:
+ if (vm)
+ virObjectUnlock(vm);
+ if (event)
+ qemuDomainEventQueue(driver, event);
+ virObjectUnref(cfg);
+
+ return 0;
+}
static qemuMonitorCallbacks monitorCallbacks = {
.destroy = qemuProcessHandleMonitorDestroy,
@@ -1289,6 +1385,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
.domainPMSuspend = qemuProcessHandlePMSuspend,
.domainBalloonChange = qemuProcessHandleBalloonChange,
.domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk,
+ .domainGUESTPanicked = qemuProcessHandleGUESTPanicked,
};
static int
@@ -2673,6 +2770,10 @@ qemuProcessUpdateState(virQEMUDriverPtr driver, virDomainObjPtr vm)
newState = VIR_DOMAIN_SHUTDOWN;
newReason = VIR_DOMAIN_SHUTDOWN_UNKNOWN;
ignore_value(VIR_STRDUP_QUIET(msg, "shutdown"));
+ } else if (reason == VIR_DOMAIN_PAUSED_GUEST_PANICKED) {
+ newState = VIR_DOMAIN_CRASHED;
+ newReason = VIR_DOMAIN_CRASHED_PANICKED;
+ ignore_value(VIR_STRDUP_QUIET(msg, "was crashed"));
} else {
newState = VIR_DOMAIN_PAUSED;
newReason = reason;
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 5ed89d1..4bddefe 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -192,6 +192,8 @@ vshDomainStateReasonToString(int state, int reason)
return N_("save canceled");
case VIR_DOMAIN_RUNNING_WAKEUP:
return N_("event wakeup");
+ case VIR_DOMAIN_RUNNING_CRASHED:
+ return N_("from crashed");
case VIR_DOMAIN_RUNNING_UNKNOWN:
case VIR_DOMAIN_RUNNING_LAST:
;
@@ -226,6 +228,8 @@ vshDomainStateReasonToString(int state, int reason)
return N_("shutting down");
case VIR_DOMAIN_PAUSED_SNAPSHOT:
return N_("creating snapshot");
+ case VIR_DOMAIN_PAUSED_GUEST_PANICKED:
+ return N_("guest panicked");
case VIR_DOMAIN_PAUSED_UNKNOWN:
case VIR_DOMAIN_PAUSED_LAST:
;
@@ -236,6 +240,8 @@ vshDomainStateReasonToString(int state, int reason)
switch ((virDomainShutdownReason) reason) {
case VIR_DOMAIN_SHUTDOWN_USER:
return N_("user");
+ case VIR_DOMAIN_SHUTDOWN_CRASHED:
+ return N_("crashed");
case VIR_DOMAIN_SHUTDOWN_UNKNOWN:
case VIR_DOMAIN_SHUTDOWN_LAST:
;
@@ -266,6 +272,8 @@ vshDomainStateReasonToString(int state, int reason)
case VIR_DOMAIN_CRASHED:
switch ((virDomainCrashedReason) reason) {
+ case VIR_DOMAIN_CRASHED_PANICKED:
+ return N_("panicked");
case VIR_DOMAIN_CRASHED_UNKNOWN:
case VIR_DOMAIN_CRASHED_LAST:
;
--
1.8.1.4
11 years, 6 months
[libvirt] [PATCH] libvirt supports Guest Panicked
by Chen Fan
From: chenfan <chen.fan.fnst(a)cn.fujitsu.com>
This patch implements qemu_driver supporting guest panicked, modified the 'on_crash' default value to 'preserve'.
---
examples/domain-events/events-c/event-test.c | 10 +++
include/libvirt/libvirt.h.in | 16 +++++
src/conf/domain_conf.c | 14 ++--
src/qemu/qemu_monitor.c | 14 +++-
src/qemu/qemu_monitor.h | 5 ++
src/qemu/qemu_monitor_json.c | 7 ++
src/qemu/qemu_process.c | 99 +++++++++++++++++++++++++++-
tools/virsh-domain-monitor.c | 8 +++
8 files changed, 166 insertions(+), 7 deletions(-)
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c
index eeff50f..1b425fb 100644
--- a/examples/domain-events/events-c/event-test.c
+++ b/examples/domain-events/events-c/event-test.c
@@ -93,6 +93,9 @@ const char *eventToString(int event) {
case VIR_DOMAIN_EVENT_PMSUSPENDED:
ret = "PMSuspended";
break;
+ case VIR_DOMAIN_EVENT_CRASHED:
+ ret = "Crashed";
+ break;
}
return ret;
}
@@ -209,6 +212,13 @@ static const char *eventDetailToString(int event, int detail) {
break;
}
break;
+ case VIR_DOMAIN_EVENT_CRASHED:
+ switch ((virDomainEventCrashedDetailType) detail) {
+ case VIR_DOMAIN_EVENT_CRASHED_PANICKED:
+ ret = "Panicked";
+ break;
+ }
+ break;
}
return ret;
}
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 1804c93..56c6c5c 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -155,6 +155,7 @@ typedef enum {
VIR_DOMAIN_RUNNING_SAVE_CANCELED = 7, /* returned from failed save process */
VIR_DOMAIN_RUNNING_WAKEUP = 8, /* returned from pmsuspended due to
wakeup event */
+ VIR_DOMAIN_RUNNING_CRASHED = 9, /* resumed from crashed */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_RUNNING_LAST
@@ -180,6 +181,7 @@ typedef enum {
VIR_DOMAIN_PAUSED_FROM_SNAPSHOT = 7, /* paused after restoring from snapshot */
VIR_DOMAIN_PAUSED_SHUTTING_DOWN = 8, /* paused during shutdown process */
VIR_DOMAIN_PAUSED_SNAPSHOT = 9, /* paused while creating a snapshot */
+ VIR_DOMAIN_PAUSED_GUEST_PANICKED = 10, /* paused due to a guest panicked event */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_PAUSED_LAST
@@ -189,6 +191,7 @@ typedef enum {
typedef enum {
VIR_DOMAIN_SHUTDOWN_UNKNOWN = 0, /* the reason is unknown */
VIR_DOMAIN_SHUTDOWN_USER = 1, /* shutting down on user request */
+ VIR_DOMAIN_SHUTDOWN_CRASHED = 2, /* domain crashed */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_SHUTDOWN_LAST
@@ -212,6 +215,7 @@ typedef enum {
typedef enum {
VIR_DOMAIN_CRASHED_UNKNOWN = 0, /* crashed for unknown reason */
+ VIR_DOMAIN_CRASHED_PANICKED = 1, /* domain panicked */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_CRASHED_LAST
@@ -3319,6 +3323,7 @@ typedef enum {
VIR_DOMAIN_EVENT_STOPPED = 5,
VIR_DOMAIN_EVENT_SHUTDOWN = 6,
VIR_DOMAIN_EVENT_PMSUSPENDED = 7,
+ VIR_DOMAIN_EVENT_CRASHED = 8,
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_LAST
@@ -3450,6 +3455,17 @@ typedef enum {
#endif
} virDomainEventPMSuspendedDetailType;
+/*
+ * Details about the 'crashed' lifecycle event
+ */
+typedef enum {
+ VIR_DOMAIN_EVENT_CRASHED_PANICKED = 0, /* Guest was panicked */
+
+#ifdef VIR_ENUM_SENTINELS
+ VIR_DOMAIN_EVENT_CRASHED_LAST
+#endif
+} virDomainEventCrashedDetailType;
+
/**
* virConnectDomainEventCallback:
* @conn: virConnect connection
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a9656af..3f0786e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -642,7 +642,8 @@ VIR_ENUM_IMPL(virDomainRunningReason, VIR_DOMAIN_RUNNING_LAST,
"unpaused",
"migration canceled",
"save canceled",
- "wakeup")
+ "wakeup",
+ "from crashed")
VIR_ENUM_IMPL(virDomainBlockedReason, VIR_DOMAIN_BLOCKED_LAST,
"unknown")
@@ -657,11 +658,13 @@ VIR_ENUM_IMPL(virDomainPausedReason, VIR_DOMAIN_PAUSED_LAST,
"watchdog",
"from snapshot",
"shutdown",
- "snapshot")
+ "snapshot",
+ "guest panicked")
VIR_ENUM_IMPL(virDomainShutdownReason, VIR_DOMAIN_SHUTDOWN_LAST,
"unknown",
- "user")
+ "user",
+ "crashed")
VIR_ENUM_IMPL(virDomainShutoffReason, VIR_DOMAIN_SHUTOFF_LAST,
"unknown",
@@ -674,7 +677,8 @@ VIR_ENUM_IMPL(virDomainShutoffReason, VIR_DOMAIN_SHUTOFF_LAST,
"from snapshot")
VIR_ENUM_IMPL(virDomainCrashedReason, VIR_DOMAIN_CRASHED_LAST,
- "unknown")
+ "unknown",
+ "panicked")
VIR_ENUM_IMPL(virDomainPMSuspendedReason, VIR_DOMAIN_PMSUSPENDED_LAST,
"unknown")
@@ -10943,7 +10947,7 @@ virDomainDefParseXML(xmlDocPtr xml,
if (virDomainEventActionParseXML(ctxt, "on_crash",
"string(./on_crash[1])",
&def->onCrash,
- VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY,
+ VIR_DOMAIN_LIFECYCLE_CRASH_PRESERVE,
virDomainLifecycleCrashTypeFromString) < 0)
goto error;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 4e35f79..e0cd62c 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -113,7 +113,7 @@ VIR_ENUM_IMPL(qemuMonitorVMStatus,
QEMU_MONITOR_VM_STATUS_LAST,
"debug", "inmigrate", "internal-error", "io-error", "paused",
"postmigrate", "prelaunch", "finish-migrate", "restore-vm",
- "running", "save-vm", "shutdown", "watchdog")
+ "running", "save-vm", "shutdown", "watchdog", "guest-panicked")
typedef enum {
QEMU_MONITOR_BLOCK_IO_STATUS_OK,
@@ -1032,6 +1032,15 @@ int qemuMonitorEmitResume(qemuMonitorPtr mon)
}
+int qemuMonitorEmitGUESTPanicked(qemuMonitorPtr mon)
+{
+ int ret = -1;
+ VIR_DEBUG("mon=%p", mon);
+ QEMU_MONITOR_CALLBACK(mon, ret, domainGUESTPanicked, mon->vm);
+ return ret;
+}
+
+
int qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset)
{
int ret = -1;
@@ -3185,6 +3194,9 @@ int qemuMonitorVMStatusToPausedReason(const char *status)
case QEMU_MONITOR_VM_STATUS_WATCHDOG:
return VIR_DOMAIN_PAUSED_WATCHDOG;
+ case QEMU_MONITOR_VM_STATUS_GUEST_PANICKED:
+ return VIR_DOMAIN_PAUSED_GUEST_PANICKED;
+
/* unreachable from this point on */
case QEMU_MONITOR_VM_STATUS_LAST:
;
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index a607712..543050c 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -140,6 +140,8 @@ struct _qemuMonitorCallbacks {
unsigned long long actual);
int (*domainPMSuspendDisk)(qemuMonitorPtr mon,
virDomainObjPtr vm);
+ int (*domainGUESTPanicked)(qemuMonitorPtr mon,
+ virDomainObjPtr vm);
};
char *qemuMonitorEscapeArg(const char *in);
@@ -220,6 +222,8 @@ int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
unsigned long long actual);
int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon);
+int qemuMonitorEmitGUESTPanicked(qemuMonitorPtr mon);
+
int qemuMonitorStartCPUs(qemuMonitorPtr mon,
virConnectPtr conn);
@@ -239,6 +243,7 @@ typedef enum {
QEMU_MONITOR_VM_STATUS_SAVE_VM,
QEMU_MONITOR_VM_STATUS_SHUTDOWN,
QEMU_MONITOR_VM_STATUS_WATCHDOG,
+ QEMU_MONITOR_VM_STATUS_GUEST_PANICKED,
QEMU_MONITOR_VM_STATUS_LAST
} qemuMonitorVMStatus;
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 2b73884..b6efa52 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -74,6 +74,7 @@ static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJSONVal
static void qemuMonitorJSONHandleBlockJobReady(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, virJSONValuePtr data);
+static void qemuMonitorJSONHandleGUESTPanicked(qemuMonitorPtr mon, virJSONValuePtr data);
typedef struct {
const char *type;
@@ -87,6 +88,7 @@ static qemuEventHandler eventHandlers[] = {
{ "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJobCompleted, },
{ "BLOCK_JOB_READY", qemuMonitorJSONHandleBlockJobReady, },
{ "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
+ { "GUEST_PANICKED", qemuMonitorJSONHandleGUESTPanicked, },
{ "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
{ "RESET", qemuMonitorJSONHandleReset, },
{ "RESUME", qemuMonitorJSONHandleResume, },
@@ -593,6 +595,11 @@ static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, virJSONValuePtr data
qemuMonitorEmitResume(mon);
}
+static void qemuMonitorJSONHandleGUESTPanicked(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
+{
+ qemuMonitorEmitGUESTPanicked(mon);
+}
+
static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data)
{
long long offset = 0;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d4fd4fb..1dc1f3a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -548,6 +548,7 @@ qemuProcessFakeReboot(void *opaque)
qemuDomainObjPrivatePtr priv = vm->privateData;
virDomainEventPtr event = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainRunningReason reason = VIR_DOMAIN_RUNNING_BOOTED;
int ret = -1;
VIR_DEBUG("vm=%p", vm);
virObjectLock(vm);
@@ -573,8 +574,11 @@ qemuProcessFakeReboot(void *opaque)
goto endjob;
}
+ if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_CRASHED)
+ reason = VIR_DOMAIN_RUNNING_CRASHED;
+
if (qemuProcessStartCPUs(driver, vm, NULL,
- VIR_DOMAIN_RUNNING_BOOTED,
+ reason,
QEMU_ASYNC_JOB_NONE) < 0) {
if (virGetLastError() == NULL)
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -1269,6 +1273,98 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
return 0;
}
+static int
+qemuProcessHandleGUESTPanicked(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm)
+{
+ virQEMUDriverPtr driver = qemu_driver;
+ qemuDomainObjPrivatePtr priv;
+ virDomainEventPtr event = NULL;
+ bool isReboot = true;
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+
+ VIR_DEBUG("vm=%p", vm);
+
+ virObjectLock(vm);
+
+ if (!virDomainObjIsActive(vm)) {
+ VIR_DEBUG("Ignoring GUEST_PANICKED event from inactive domain %s",
+ vm->def->name);
+ goto cleanup;
+ }
+
+ priv = vm->privateData;
+
+ virDomainObjSetState(vm,
+ VIR_DOMAIN_CRASHED,
+ VIR_DOMAIN_CRASHED_PANICKED);
+
+ event = virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_CRASHED,
+ VIR_DOMAIN_EVENT_CRASHED_PANICKED);
+
+ if (vm->def->onCrash == VIR_DOMAIN_LIFECYCLE_CRASH_PRESERVE) {
+ VIR_FREE(priv->lockState);
+
+ if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
+ VIR_WARN("Unable to release lease on %s", vm->def->name);
+ VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
+
+ if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) {
+ VIR_WARN("Unable to save status on vm %s after state change",
+ vm->def->name);
+ }
+
+ goto cleanup;
+ }
+
+ if (vm->def->onCrash == VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY) {
+ isReboot = false;
+ VIR_INFO("Domain on_crash setting overridden, shutting down");
+ }
+
+ qemuDomainSetFakeReboot(driver, vm, isReboot);
+
+ if (isReboot) {
+ qemuProcessShutdownOrReboot(driver, vm);
+ } else {
+ priv->beingDestroyed = true;
+
+ if (qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE) < 0) {
+ priv->beingDestroyed = false;
+ goto cleanup;
+ }
+
+ priv->beingDestroyed = false;
+
+ if (! virDomainObjIsActive(vm)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_CRASHED, 0);
+ event = virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_CRASHED);
+
+ virDomainAuditStop(vm, "destroyed");
+
+ if (! vm->persistent) {
+ qemuDomainRemoveInactive(driver, vm);
+ vm = NULL;
+ }
+ }
+
+cleanup:
+ if (vm)
+ virObjectUnlock(vm);
+ if (event)
+ qemuDomainEventQueue(driver, event);
+ virObjectUnref(cfg);
+
+ return 0;
+}
static qemuMonitorCallbacks monitorCallbacks = {
.destroy = qemuProcessHandleMonitorDestroy,
@@ -1289,6 +1385,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
.domainPMSuspend = qemuProcessHandlePMSuspend,
.domainBalloonChange = qemuProcessHandleBalloonChange,
.domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk,
+ .domainGUESTPanicked = qemuProcessHandleGUESTPanicked,
};
static int
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 5ed89d1..4bddefe 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -192,6 +192,8 @@ vshDomainStateReasonToString(int state, int reason)
return N_("save canceled");
case VIR_DOMAIN_RUNNING_WAKEUP:
return N_("event wakeup");
+ case VIR_DOMAIN_RUNNING_CRASHED:
+ return N_("from crashed");
case VIR_DOMAIN_RUNNING_UNKNOWN:
case VIR_DOMAIN_RUNNING_LAST:
;
@@ -226,6 +228,8 @@ vshDomainStateReasonToString(int state, int reason)
return N_("shutting down");
case VIR_DOMAIN_PAUSED_SNAPSHOT:
return N_("creating snapshot");
+ case VIR_DOMAIN_PAUSED_GUEST_PANICKED:
+ return N_("guest panicked");
case VIR_DOMAIN_PAUSED_UNKNOWN:
case VIR_DOMAIN_PAUSED_LAST:
;
@@ -236,6 +240,8 @@ vshDomainStateReasonToString(int state, int reason)
switch ((virDomainShutdownReason) reason) {
case VIR_DOMAIN_SHUTDOWN_USER:
return N_("user");
+ case VIR_DOMAIN_SHUTDOWN_CRASHED:
+ return N_("crashed");
case VIR_DOMAIN_SHUTDOWN_UNKNOWN:
case VIR_DOMAIN_SHUTDOWN_LAST:
;
@@ -266,6 +272,8 @@ vshDomainStateReasonToString(int state, int reason)
case VIR_DOMAIN_CRASHED:
switch ((virDomainCrashedReason) reason) {
+ case VIR_DOMAIN_CRASHED_PANICKED:
+ return N_("panicked");
case VIR_DOMAIN_CRASHED_UNKNOWN:
case VIR_DOMAIN_CRASHED_LAST:
;
--
1.8.1.4
11 years, 6 months
[libvirt] [PATCH] Expose all CPU features in host definition
by Don Dugger
I've opened BZ 697141 on this as I would consider it more
a bug than a feature request. Anyway, to re-iterate my
rationale from the BZ:
The virConnectGetCapabilities API describes the host capabilities
by returning an XML description that includes the CPU model name
and a set of CPU features. The problem is that any features that
are part of the CPU model are not explicitly listed, they are
assumed to be part of the definition of that CPU model. This
makes it extremely difficult for the caller of this API to check
for the presence of a specific CPU feature, the caller would have
to know what features are part of which CPU models, a very
daunting task.
This patch solves this problem by having the API return a model
name, as it currently does, but it will also explicitly list all
of the CPU features that are present. This would make it much
easier for a caller of this API to check for specific features.
Signed-off-by: Don Dugger <donald.d.dugger(a)intel.com>
---
src/cpu/cpu_x86.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 5d479c2..b2e16df 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -1296,6 +1296,35 @@ x86GuestData(virCPUDefPtr host,
return x86Compute(host, guest, data, message);
}
+static void
+x86AddFeatures(virCPUDefPtr cpu,
+ struct x86_map *map)
+{
+ const struct x86_model *candidate;
+ const struct x86_feature *feature = map->features;
+
+ candidate = map->models;
+ while (candidate != NULL) {
+ if (STREQ(cpu->model, candidate->name))
+ break;
+ candidate = candidate->next;
+ }
+ if (!candidate) {
+ VIR_WARN("Odd, %s not a known CPU model\n", cpu->model);
+ return;
+ }
+ while (feature != NULL) {
+ if (x86DataIsSubset(candidate->data, feature->data)) {
+ if (virCPUDefAddFeature(cpu, feature->name, VIR_CPU_FEATURE_DISABLE) < 0) {
+ VIR_WARN("CPU model %s, no room for feature %s", cpu->model, feature->name);
+ return;
+ }
+ }
+ feature = feature->next;
+ }
+ return;
+}
+
static int
x86Decode(virCPUDefPtr cpu,
@@ -1383,6 +1412,7 @@ x86Decode(virCPUDefPtr cpu,
goto out;
}
+ x86AddFeatures(cpuModel, map);
cpu->model = cpuModel->model;
cpu->vendor = cpuModel->vendor;
cpu->nfeatures = cpuModel->nfeatures;
--
1.7.10.4
11 years, 6 months
[libvirt] Issues with qemu-nbd over AF_UNIX and virDomainAttachDevice
by Deepak C Shetty
Hi List,
Facing issues trying to use virDomainAttachDevice API of libvirt
from python.
Here is what I am trying to do
1) Setup qemu-nbd to export a qcow2 disk image over unix socket on my
localhost
qemu-nbd -t -k /tmp/mysock2 /home/dpkshetty/work/img/iscsi_disk
The above blocks. and i am able to use
qemu-system-x86_64 -drive file=nbd:unix:/tmp/mysock2
Just to test it...and it works. Since currently the disk is a blank
disk.. I see "No bootable device" and QEMU stops.. whcih is expected
So qemu-nbd is setup and working properly
2)
>>> print nbdxml
<disk type='network' device='disk'>
<driver name="qemu" type="qcow2"/>
<source protocol="nbd">
<host name="deepakcs-lx" port="10809" transport="unix"
socket="/tmp/mysock2" />
</source>
<target dev="vdc" bus="virtio" />
</disk>
>>> dom.attachDevice(nbdxml)
libvir: QEMU error : operation failed: open disk image file failed
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/site-packages/libvirt.py", line 400, in
attachDevice
if ret == -1: raise libvirtError ('virDomainAttachDevice() failed',
dom=self)
libvirt.libvirtError: operation failed: open disk image file failed
and I see... in the VM's log....
inet_connect_opts:
connect(ipv4,deepakcs-lx.local.lan,192.168.1.7,10809): Connection refused
3) I tried usign virsh attach-device.. and the same problem happens
4) firewall/iptables are not running. SELinux is permissive
5) I tried appending -p 1111 to the qemu-nbd cmdline and using
port="1111" in the XML.. but that doesn't help, see the same error
Questions/Observations :
1) What am i doing wrong here ? In the <host> tag, port attr is
mandatory.. but looking at `netstat -nptl` I don't see any process
listeing on 10809 or 1111 (when i gave -p 1111 ).
So does this mean there is no way for libvirt to just directly open the
socket and use it.. Its trying to connect to the port i give in the XML
and since no one is listening there.. it fails.. hence the error seen in
the VM logs.... Has anybody tryign usign qemu-nbd and attaching that
disk as I am doign above ? Is it legal, if not, why ?
2) The VM/Domain is active during all of the above steps.
3) IIUC... for the above usecase... port attr of <host> should be
optional... such that libvirt can directly do the equivalent of ` -drive
file=nbd:unix:/tmp/mysock2` and add this as a NBD device to the runnign
guest/Domain... but currently port and hostname are mandatory. For unix
sockets... hostname will always be local...so i feel both hostname &
port should be optional for the above usecase ?
4) I haven't yet tried doing the above when guest/Domain is Inactive.
5) I haven't yet tried doing the above usign nbd-server or qemu-nbd
usign -c option (which i believe starts qemu-nbd in server mode, but
need nbd.ko kernel module to be loaded).
I am hoping using either of these might get it working... since we have
a process listening on a port on the host... but I wanted to get this
working using plain unix sockets.. lightweight and doesn't need nbd.ko
Comments/Suggestions appreciated.
thanx,
deepak
11 years, 6 months
[libvirt] fix change-media bug on disk block type and support volume type
by Guannan Ren
Resolves:https://bugzilla.redhat.com/show_bug.cgi?id=923053
When cdrom is block type, the virsh change-media failed to insert
source info because virsh uses "<source block='/dev/sdb'/>" while
the correct name of the attribute for block disks is "dev".
Correct XML:
<disk type='block' device='cdrom'>
<driver name='qemu' type='raw'/>
<source dev='/dev/sdb'/>
<target dev='vdb' bus='virtio'/>
<readonly/>
</disk>
And, this patch supports cdrom with volume type for change-media command
For example:
'/var/lib/libvirt/images/boot.iso' is a volume path of 'boot.iso' volume
on 'default' pool and the cdrom device has no source.
Virsh command:
virsh change-media rhel6qcow2 vdb /var/lib/libvirt/images/boot.iso --insert
The updated disk XML:
<disk type='volume' device='cdrom'>
<driver name='qemu' type='raw'/>
<source pool='default' volume='boot.iso'/>
<target dev='vdb' bus='virtio'/>
<readonly/>
</disk>
Guannan Ren(3)
[PATCH 1/3] qemu: throw original error when failing to lookup pool or volume
[PATCH 2/3] qemu: support updating pool and volume info when disk is volume type
[PATCH 3/3] virsh: fix change-media bug on disk block type and support volume type
src/conf/domain_conf.c | 2 +-
src/conf/domain_conf.h | 1 +
src/libvirt_private.syms | 1 +
src/qemu/qemu_conf.c | 11 ++++++++++-
src/qemu/qemu_driver.c | 5 +++++
tools/virsh-domain.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++------
6 files changed, 69 insertions(+), 8 deletions(-)
11 years, 6 months
Re: [libvirt] [Qemu-devel] [PATCH v3 2/2] net: introduce command to query rx-filter information
by Michael S. Tsirkin
On Fri, May 24, 2013 at 05:20:13PM +0200, Markus Armbruster wrote:
> Eric Blake <eblake(a)redhat.com> writes:
>
> > On 05/24/2013 06:23 AM, Luiz Capitulino wrote:
> >>>> I don't think we need this argument. This command is quite simple in its
> >>>> response, let's do this filtering in HMP only.
> >>>
> >>> Event message contains the net client name, management might only want
> >>> to query the single net client.
> >>
> >> The client can do the filtering itself.
> >
> > If we're arguing that we want this to be as responsive as possible, then
> > the less data we send over the wire, the faster management can react to
> > the guest's request for a particular NIC. That is, if libvirt is
> > listening to events that says NIC2 wants to change rx-filter, libvirt
> > would rather do a filtered query where it knows the JSON array of 1
> > element matches NIC2 data, rather than do a global query and search
> > through the returned array until it finds NIC2.
> >
> > Filtering is relatively easy to add, whether you do it in QMP or make
> > every client add it. Libvirt will survive if you don't have filtering,
> > but I don't see why we can't have it in QMP. Also, if you DO decide to
> > rip filtering out of QMP, you STILL need to keep a per-NIC flag. Since
> > the events say which NIC is requesting a change, even if the query reads
> > all nics, libvirt will only change the macvtap settings of the nic(s)
> > for which it has received an event (it doesn't make sense to waste time
> > requesting a (no-op) change to macvtap settings on a nic that hasn't
> > requested a change). But if you argue that having no filtering in the
> > QMP command means that you can get away with a single flag instead of a
> > per-nic flag, then you will fail to emit an event for NIC2 if it changes
> > in between the time that NIC1 fired an event and libvirt finally does
> > the query, and libvirt wouldn't realize that NIC2 also needs a macvtap
> > change.
>
> No disagreement on the need for a per-NIC flag.
>
> I'm not sure I buy the responsiveness argument. Sure, the fastest I/O
> is no I/O, but whether you read and parse 100 bytes or 1000 from a Unix
> domain socket once in a great while shouldn't make a difference.
>
> My main concern is to keep the external interface simple. I'm rather
> reluctant to have query commands grow options.
>
> In a case where we need the "give me everything" query anyway, the "give
> me this particular part" option is additional complexity. Needs
> justification, say arguments involving throughput, latency or client
> complexity.
>
> Perhaps cases exist where we never want to ask for everything. Then the
> "give me everything" query is useless, and the option should be
> mandatory.
We need the query for macvtap devices. We don't need it
for tap devices. In that case you don't want tap device info.
Maybe some libvirt guys can tell us whether they prefer
a per device query or a global one with info for all NICs?
I think for HMP it's best to have nic optional.
Is it a good idea to make QMP match HMP closely?
--
MST
11 years, 6 months
[libvirt] [PATCH] qemu: Fix build without gnutls
by Jiri Denemark
"error" label in qemuMigrationCookieGraphicsAlloc is now used
unconditionally thanks to VIR_STRDUP.
---
Pushed as a build-breaker.
src/qemu/qemu_migration.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 73ced73..19b1236 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -324,9 +324,7 @@ qemuMigrationCookieGraphicsAlloc(virQEMUDriverPtr driver,
no_memory:
virReportOOMError();
-#ifdef WITH_GNUTLS
error:
-#endif
qemuMigrationCookieGraphicsFree(mig);
virObjectUnref(cfg);
return NULL;
--
1.8.2.1
11 years, 6 months
[libvirt] two hostdev devices problem
by Dominik Mostowiec
hi,
I try to add 2 VF by "hostdev".
Networks (vnet0, vnet1) with:
<forward mode='hostdev' managed='yes'>
<pf dev='eth1'/>
.....
Domain:
<interface type="network">
<source network="vnet0"/>
....
<interface type="network">
<source network="vnet1"/>
....
virsh create error:
"error: internal error process exited while connecting to monitor: kvm:
-device pci-assign,configfd=25,host=01:10.1,id=hostdev0,bus=pci.0,addr=0x4:
Duplicate ID 'hostdev0' for device"
I am doing somthing wrong?
My configs:
domain:
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
<name>one-466</name>
<vcpu>1</vcpu>
<memory>1781760</memory>
<os>
<type arch="x86_64">hvm</type>
<boot dev="hd"/>
</os>
<devices>
<emulator>/usr/bin/kvm</emulator>
<disk type="file" device="disk">
<source
file="/nebula/nebula/var//datastores/0/466/disk.0"/>
<target dev="hda" bus="virtio"/>
<driver name="qemu" type="raw" cache="default"/>
</disk>
<disk type="file" device="disk">
<source
file="/nebula/nebula/var//datastores/0/466/disk.1"/>
<target dev="vdb" bus="virtio"/>
<driver name="qemu" type="raw" cache="default"/>
</disk>
<graphics type="vnc" listen="0.0.0.0" port="-1"/>
<interface type="network">
<source network="vnet0"/>
<mac address="52:54:0a:b1:48:91"/>
</interface>
<interface type="network">
<source network="vnet1"/>
<mac address="52:54:0a:b1:48:92"/>
</interface>
</devices>
<features>
<acpi/>
</features>
<devices><serial type="pty"><source path="/dev/pts/477"/><target
port="0"/></serial><console type="pty" tty="/dev/pts/477"><source
path="/dev/pts/477"/><target port="0"/></console></devices>
</domain>
Networks:
cat /etc/libvirt/qemu/networks/vnet0.xml
<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made
using:
virsh net-edit vnet0
or other application using the libvirt API.
-->
<network>
<name>vnet0</name>
<uuid>1b6a3506-d9e0-4e1e-bbff-6f700b8dc80b</uuid>
<forward mode='hostdev' managed='yes'>
<pf dev='eth0'/>
</forward>
</network>
cat /etc/libvirt/qemu/networks/vnet1.xml
<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made
using:
virsh net-edit vnet1
or other application using the libvirt API.
-->
<network>
<name>vnet1</name>
<uuid>11feb088-d609-4177-86d7-ac3b9467a3e8</uuid>
<forward mode='hostdev' managed='yes'>
<pf dev='eth1'/>
</forward>
</network>
I wrote libvirt-users mailing list too.
--
Pozdrawiam
Dominik
11 years, 6 months