Signed-off-by: Dmitry Guryanov <dguryanov@xxxxxxxxxxxxx> --- src/pvs/pvs_driver.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/pvs/pvs_driver.h | 1 + src/pvs/pvs_utils.c | 18 ++++++ 3 files changed, 167 insertions(+), 0 deletions(-) diff --git a/src/pvs/pvs_driver.c b/src/pvs/pvs_driver.c index c854664..b0c9a20 100644 --- a/src/pvs/pvs_driver.c +++ b/src/pvs/pvs_driver.c @@ -60,6 +60,11 @@ void pvsFreeDomObj(void *p); static virCapsPtr pvsBuildCapabilities(void); static int pvsClose(virConnectPtr conn); +int pvsPause(virDomainObjPtr privdom); +int pvsResume(virDomainObjPtr privdom); +int pvsStart(virDomainObjPtr privdom); +int pvsKill(virDomainObjPtr privdom); +int pvsStop(virDomainObjPtr privdom); static void pvsDriverLock(pvsConnPtr driver) @@ -87,6 +92,12 @@ pvsFreeDomObj(void *p) VIR_FREE(pdom); }; +static void +pvsDomainEventQueue(pvsConnPtr driver, virDomainEventPtr event) +{ + virDomainEventStateQueue(driver->domainEventState, event); +} + static virCapsPtr pvsBuildCapabilities(void) { @@ -726,6 +737,138 @@ pvsDomainGetAutostart(virDomainPtr domain, int *autostart) return ret; } +typedef int (*pvsChangeState) (virDomainObjPtr privdom); +#define PVS_UUID(x) (((pvsDomObjPtr)(x->privateData))->uuid) + +static int +pvsDomainChangeState(virDomainPtr domain, + virDomainState req_state, const char * req_state_name, + pvsChangeState chstate, + virDomainState new_state, int reason, + int event_type, int event_detail) +{ + pvsConnPtr privconn = domain->conn->privateData; + virDomainObjPtr privdom; + virDomainEventPtr event = NULL; + int state; + int ret = -1; + + pvsDriverLock(privconn); + privdom = virDomainFindByName(&privconn->domains, domain->name); + pvsDriverUnlock(privconn); + + if (privdom == NULL) { + pvsError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto cleanup; + } + + state = virDomainObjGetState(privdom, NULL); + if (state != req_state) { + pvsError(VIR_ERR_INTERNAL_ERROR, _("domain '%s' not %s"), + privdom->def->name, req_state_name); + goto cleanup; + } + + if (chstate(privdom)) + goto cleanup; + + virDomainObjSetState(privdom, new_state, reason); + + event = virDomainEventNewFromObj(privdom, event_type, event_detail); + ret = 0; + + cleanup: + if (privdom) + virDomainObjUnlock(privdom); + + if (event) { + pvsDriverLock(privconn); + pvsDomainEventQueue(privconn, event); + pvsDriverUnlock(privconn); + } + return ret; +} + +int pvsPause(virDomainObjPtr privdom) +{ + return pvsCmdRun(PRLCTL, "pause", PVS_UUID(privdom), NULL); +} + +static int +pvsPauseDomain(virDomainPtr domain) +{ + return pvsDomainChangeState(domain, + VIR_DOMAIN_RUNNING, "running", + pvsPause, + VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER, + VIR_DOMAIN_EVENT_SUSPENDED, + VIR_DOMAIN_EVENT_SUSPENDED_PAUSED); +} + +int pvsResume(virDomainObjPtr privdom) +{ + return pvsCmdRun(PRLCTL, "resume", PVS_UUID(privdom), NULL); +} + +static int +pvsResumeDomain(virDomainPtr domain) +{ + return pvsDomainChangeState(domain, + VIR_DOMAIN_PAUSED, "paused", + pvsResume, + VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_UNPAUSED, + VIR_DOMAIN_EVENT_RESUMED, + VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); +} + +int pvsStart(virDomainObjPtr privdom) +{ + return pvsCmdRun(PRLCTL, "start", PVS_UUID(privdom), NULL); +} + +static int +pvsDomainCreate(virDomainPtr domain) +{ + return pvsDomainChangeState(domain, + VIR_DOMAIN_SHUTOFF, "stopped", + pvsStart, + VIR_DOMAIN_RUNNING, VIR_DOMAIN_EVENT_STARTED_BOOTED, + VIR_DOMAIN_EVENT_STARTED, + VIR_DOMAIN_EVENT_STARTED_BOOTED); +} + +int pvsKill(virDomainObjPtr privdom) +{ + return pvsCmdRun(PRLCTL, "stop", PVS_UUID(privdom), "--kill", NULL); +} + +static int +pvsDestroyDomain(virDomainPtr domain) +{ + return pvsDomainChangeState(domain, + VIR_DOMAIN_RUNNING, "running", + pvsKill, + VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_DESTROYED, + VIR_DOMAIN_EVENT_STOPPED, + VIR_DOMAIN_EVENT_STOPPED_DESTROYED); +} + +int pvsStop(virDomainObjPtr privdom) +{ + return pvsCmdRun(PRLCTL, "stop", PVS_UUID(privdom), NULL); +} + +static int +pvsShutdownDomain(virDomainPtr domain) +{ + return pvsDomainChangeState(domain, + VIR_DOMAIN_RUNNING, "running", + pvsStop, + VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_SHUTDOWN, + VIR_DOMAIN_EVENT_STOPPED, + VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN); +} + static virDriver pvsDriver = { .no = VIR_DRV_PVS, .name = "PVS", @@ -748,6 +891,11 @@ static virDriver pvsDriver = { .domainGetXMLDesc = pvsDomainGetXMLDesc, /* 0.9.11 */ .domainIsPersistent = pvsDomainIsPersistent, /* 0.9.11 */ .domainGetAutostart = pvsDomainGetAutostart, /* 0.9.11 */ + .domainSuspend = pvsPauseDomain, /* 0.9.11 */ + .domainResume = pvsResumeDomain, /* 0.9.11 */ + .domainDestroy = pvsDestroyDomain, /* 0.9.11 */ + .domainShutdown = pvsShutdownDomain, /* 0.9.11 */ + .domainCreate = pvsDomainCreate, /* 0.9.11 */ }; /** diff --git a/src/pvs/pvs_driver.h b/src/pvs/pvs_driver.h index 3f84d66..d3cbca2 100644 --- a/src/pvs/pvs_driver.h +++ b/src/pvs/pvs_driver.h @@ -62,5 +62,6 @@ typedef struct _pvsConn *pvsConnPtr; int pvsRegister(void); virJSONValuePtr pvsParseOutput(const char *binary, ...); +int pvsCmdRun(const char *binary, ...); #endif diff --git a/src/pvs/pvs_utils.c b/src/pvs/pvs_utils.c index 3842010..3a548bd 100644 --- a/src/pvs/pvs_utils.c +++ b/src/pvs/pvs_utils.c @@ -99,3 +99,21 @@ pvsParseOutput(const char *binary, ...) return jobj; } + +/* + * Run prlctl command and check for errors + * + * Return value is 0 in case of success, else - -1 + */ +int +pvsCmdRun(const char *binary, ...) +{ + int ret; + va_list list; + + va_start(list, binary); + ret = pvsDoCmdRun(NULL, binary, list); + va_end(list); + + return ret; +} -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list