qemu: Wire up PR_MANAGER_STATUS_CHANGED event

This event is emitted on the monitor if one of pr-managers lost
connection to its pr-helper process. What libvirt needs to do is
restart the pr-helper process iff it corresponds to managed
pr-manager.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Michal Privoznik 2018-06-27 12:17:59 +02:00
parent 0da435118c
commit 6fbda83330
7 changed files with 123 additions and 0 deletions

View File

@ -13003,6 +13003,7 @@ qemuProcessEventFree(struct qemuProcessEvent *event)
case QEMU_PROCESS_EVENT_MONITOR_EOF:
VIR_FREE(event->data);
break;
case QEMU_PROCESS_EVENT_PR_DISCONNECT:
case QEMU_PROCESS_EVENT_LAST:
break;
}

View File

@ -477,6 +477,7 @@ typedef enum {
QEMU_PROCESS_EVENT_SERIAL_CHANGED,
QEMU_PROCESS_EVENT_BLOCK_JOB,
QEMU_PROCESS_EVENT_MONITOR_EOF,
QEMU_PROCESS_EVENT_PR_DISCONNECT,
QEMU_PROCESS_EVENT_LAST
} qemuProcessEventType;

View File

@ -4778,6 +4778,20 @@ processMonitorEOFEvent(virQEMUDriverPtr driver,
}
static void
processPRDisconnectEvent(virDomainObjPtr vm)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
if (!virDomainObjIsActive(vm))
return;
if (!priv->prDaemonRunning &&
virDomainDefHasManagedPR(vm->def))
qemuProcessStartManagedPRDaemon(vm);
}
static void qemuProcessEventHandler(void *data, void *opaque)
{
struct qemuProcessEvent *processEvent = data;
@ -4815,6 +4829,9 @@ static void qemuProcessEventHandler(void *data, void *opaque)
case QEMU_PROCESS_EVENT_MONITOR_EOF:
processMonitorEOFEvent(driver, vm);
break;
case QEMU_PROCESS_EVENT_PR_DISCONNECT:
processPRDisconnectEvent(vm);
break;
case QEMU_PROCESS_EVENT_LAST:
break;
}

View File

@ -1669,6 +1669,21 @@ qemuMonitorEmitDumpCompleted(qemuMonitorPtr mon,
}
int
qemuMonitorEmitPRManagerStatusChanged(qemuMonitorPtr mon,
const char *prManager,
bool connected)
{
int ret = -1;
VIR_DEBUG("mon=%p, prManager='%s', connected=%d", mon, prManager, connected);
QEMU_MONITOR_CALLBACK(mon, ret, domainPRManagerStatusChanged,
mon->vm, prManager, connected);
return ret;
}
int
qemuMonitorSetCapabilities(qemuMonitorPtr mon)
{

View File

@ -273,6 +273,12 @@ typedef int (*qemuMonitorDomainDumpCompletedCallback)(qemuMonitorPtr mon,
const char *error,
void *opaque);
typedef int (*qemuMonitorDomainPRManagerStatusChangedCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
const char *prManager,
bool connected,
void *opaque);
typedef struct _qemuMonitorCallbacks qemuMonitorCallbacks;
typedef qemuMonitorCallbacks *qemuMonitorCallbacksPtr;
struct _qemuMonitorCallbacks {
@ -305,6 +311,7 @@ struct _qemuMonitorCallbacks {
qemuMonitorDomainAcpiOstInfoCallback domainAcpiOstInfo;
qemuMonitorDomainBlockThresholdCallback domainBlockThreshold;
qemuMonitorDomainDumpCompletedCallback domainDumpCompleted;
qemuMonitorDomainPRManagerStatusChangedCallback domainPRManagerStatusChanged;
};
char *qemuMonitorEscapeArg(const char *in);
@ -433,6 +440,10 @@ int qemuMonitorEmitDumpCompleted(qemuMonitorPtr mon,
qemuMonitorDumpStatsPtr stats,
const char *error);
int qemuMonitorEmitPRManagerStatusChanged(qemuMonitorPtr mon,
const char *prManager,
bool connected);
int qemuMonitorStartCPUs(qemuMonitorPtr mon);
int qemuMonitorStopCPUs(qemuMonitorPtr mon);

View File

@ -91,6 +91,7 @@ static void qemuMonitorJSONHandleMigrationPass(qemuMonitorPtr mon, virJSONValueP
static void qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleDumpCompleted(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandlePRManagerStatusChanged(qemuMonitorPtr mon, virJSONValuePtr data);
typedef struct {
const char *type;
@ -113,6 +114,7 @@ static qemuEventHandler eventHandlers[] = {
{ "MIGRATION_PASS", qemuMonitorJSONHandleMigrationPass, },
{ "NIC_RX_FILTER_CHANGED", qemuMonitorJSONHandleNicRxFilterChanged, },
{ "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
{ "PR_MANAGER_STATUS_CHANGED", qemuMonitorJSONHandlePRManagerStatusChanged, },
{ "RESET", qemuMonitorJSONHandleReset, },
{ "RESUME", qemuMonitorJSONHandleResume, },
{ "RTC_CHANGE", qemuMonitorJSONHandleRTCChange, },
@ -1297,6 +1299,27 @@ qemuMonitorJSONHandleDumpCompleted(qemuMonitorPtr mon,
}
static void qemuMonitorJSONHandlePRManagerStatusChanged(qemuMonitorPtr mon,
virJSONValuePtr data)
{
const char *name;
bool connected;
if (!(name = virJSONValueObjectGetString(data, "id"))) {
VIR_WARN("missing pr-manager alias in PR_MANAGER_STATUS_CHANGED event");
return;
}
if (virJSONValueObjectGetBoolean(data, "connected", &connected) < 0) {
VIR_WARN("missing connected state for %s "
"in PR_MANAGER_STATUS_CHANGED event", name);
return;
}
qemuMonitorEmitPRManagerStatusChanged(mon, name, connected);
}
int
qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon,
const char *cmd_str,

View File

@ -1615,6 +1615,60 @@ qemuProcessHandleDumpCompleted(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
static int
qemuProcessHandlePRManagerStatusChanged(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
const char *prManager,
bool connected,
void *opaque)
{
virQEMUDriverPtr driver = opaque;
qemuDomainObjPrivatePtr priv;
struct qemuProcessEvent *processEvent = NULL;
const char *managedAlias = qemuDomainGetManagedPRAlias();
int ret = -1;
virObjectLock(vm);
VIR_DEBUG("pr-manager %s status changed for domain %p %s connected=%d",
prManager, vm, vm->def->name, connected);
if (connected) {
/* Connect events are boring. */
ret = 0;
goto cleanup;
}
/* Disconnect events are more interesting. */
if (STRNEQ(prManager, managedAlias)) {
VIR_DEBUG("pr-manager %s not managed, ignoring event",
prManager);
ret = 0;
goto cleanup;
}
priv = vm->privateData;
priv->prDaemonRunning = false;
if (VIR_ALLOC(processEvent) < 0)
goto cleanup;
processEvent->eventType = QEMU_PROCESS_EVENT_PR_DISCONNECT;
processEvent->vm = virObjectRef(vm);
if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
qemuProcessEventFree(processEvent);
virObjectUnref(vm);
goto cleanup;
}
ret = 0;
cleanup:
virObjectUnlock(vm);
return ret;
}
static qemuMonitorCallbacks monitorCallbacks = {
.eofNotify = qemuProcessHandleMonitorEOF,
.errorNotify = qemuProcessHandleMonitorError,
@ -1643,6 +1697,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
.domainAcpiOstInfo = qemuProcessHandleAcpiOstInfo,
.domainBlockThreshold = qemuProcessHandleBlockThreshold,
.domainDumpCompleted = qemuProcessHandleDumpCompleted,
.domainPRManagerStatusChanged = qemuProcessHandlePRManagerStatusChanged,
};
static void