On Thu, Jul 26, 2012 at 10:32:02PM +0400, Dmitry Guryanov wrote:
Add functions for create/shutdown/destroy and suspend/resume domain.
Signed-off-by: Dmitry Guryanov <dguryanov(a)parallels.com>
---
src/parallels/parallels_driver.c | 143 ++++++++++++++++++++++++++++++++++++++
src/parallels/parallels_utils.c | 18 +++++
src/parallels/parallels_utils.h | 2 +
3 files changed, 163 insertions(+), 0 deletions(-)
diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c
index c716b25..8c20d27 100644
--- a/src/parallels/parallels_driver.c
+++ b/src/parallels/parallels_driver.c
@@ -128,6 +128,12 @@ parallelsDomObjFreePrivate(void *p)
VIR_FREE(p);
};
+static void
+parallelsDomainEventQueue(parallelsConnPtr driver, virDomainEventPtr event)
+{
+ virDomainEventStateQueue(driver->domainEventState, event);
+}
I don't see any code which ever deals with dispatching of the domain
event state. Is this something you're just preparing now, so that you
can wire up events in a future patch ?
+
static virCapsPtr
parallelsBuildCapabilities(void)
{
@@ -805,6 +811,138 @@ parallelsDomainGetAutostart(virDomainPtr domain, int *autostart)
return ret;
}
+typedef int (*parallelsChangeStateFunc) (virDomainObjPtr privdom);
+#define PARALLELS_UUID(x) (((parallelsDomObjPtr)(x->privateData))->uuid)
+
+static int
+parallelsDomainChangeState(virDomainPtr domain,
+ virDomainState req_state, const char *req_state_name,
+ parallelsChangeStateFunc chstate,
+ virDomainState new_state, int reason,
+ int event_type, int event_detail)
+{
+ parallelsConnPtr privconn = domain->conn->privateData;
+ virDomainObjPtr privdom;
+ virDomainEventPtr event = NULL;
+ int state;
+ int ret = -1;
+
+ parallelsDriverLock(privconn);
+ privdom = virDomainFindByUUID(&privconn->domains, domain->uuid);
+ parallelsDriverUnlock(privconn);
+
+ if (privdom == NULL) {
+ parallelsDomNotFoundError(domain);
+ goto cleanup;
+ }
+
+ state = virDomainObjGetState(privdom, NULL);
+ if (state != req_state) {
+ virReportError(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) {
+ parallelsDriverLock(privconn);
+ parallelsDomainEventQueue(privconn, event);
+ parallelsDriverUnlock(privconn);
+ }
+ return ret;
+}
One comment I'd have here is that the event dispatch only works
within the context of this single virConnectPtr instance. If you
have 2 active connections to libvirt and one starts a guest,
the other connection won't see any event. Likewise if someone
starts/stops something using the parallels tools directly no
events will get queued.
Is there any way we can obtain some kind of notification from
the core parallels software stack ? Even if it is indirect eg
with UserModeLinux we detect stop/start events only, using an
inotify watch on the directory containing the UML monitor
socket :-)
+
+static int parallelsPause(virDomainObjPtr privdom)
+{
+ return parallelsCmdRun(PRLCTL, "pause", PARALLELS_UUID(privdom), NULL);
+}
+
+static int
+parallelsPauseDomain(virDomainPtr domain)
+{
+ return parallelsDomainChangeState(domain,
+ VIR_DOMAIN_RUNNING, "running",
+ parallelsPause,
+ VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER,
+ VIR_DOMAIN_EVENT_SUSPENDED,
+ VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
+}
+
+static int parallelsResume(virDomainObjPtr privdom)
+{
+ return parallelsCmdRun(PRLCTL, "resume", PARALLELS_UUID(privdom), NULL);
+}
+
+static int
+parallelsResumeDomain(virDomainPtr domain)
+{
+ return parallelsDomainChangeState(domain,
+ VIR_DOMAIN_PAUSED, "paused",
+ parallelsResume,
+ VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_UNPAUSED,
+ VIR_DOMAIN_EVENT_RESUMED,
+ VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
+}
+
+static int parallelsStart(virDomainObjPtr privdom)
+{
+ return parallelsCmdRun(PRLCTL, "start", PARALLELS_UUID(privdom), NULL);
+}
+
+static int
+parallelsDomainCreate(virDomainPtr domain)
+{
+ return parallelsDomainChangeState(domain,
+ VIR_DOMAIN_SHUTOFF, "stopped",
+ parallelsStart,
+ VIR_DOMAIN_RUNNING,
VIR_DOMAIN_EVENT_STARTED_BOOTED,
+ VIR_DOMAIN_EVENT_STARTED,
+ VIR_DOMAIN_EVENT_STARTED_BOOTED);
+}
+
+static int parallelsKill(virDomainObjPtr privdom)
+{
+ return parallelsCmdRun(PRLCTL, "stop", PARALLELS_UUID(privdom),
"--kill", NULL);
+}
+
+static int
+parallelsDestroyDomain(virDomainPtr domain)
+{
+ return parallelsDomainChangeState(domain,
+ VIR_DOMAIN_RUNNING, "running",
+ parallelsKill,
+ VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_DESTROYED,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
+}
+
+static int parallelsStop(virDomainObjPtr privdom)
+{
+ return parallelsCmdRun(PRLCTL, "stop", PARALLELS_UUID(privdom), NULL);
+}
+
+static int
+parallelsShutdownDomain(virDomainPtr domain)
+{
+ return parallelsDomainChangeState(domain,
+ VIR_DOMAIN_RUNNING, "running",
+ parallelsStop,
+ VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_SHUTDOWN,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
+}
+
static virDriver parallelsDriver = {
.no = VIR_DRV_PARALLELS,
.name = "Parallels",
@@ -828,6 +966,11 @@ static virDriver parallelsDriver = {
.domainGetXMLDesc = parallelsDomainGetXMLDesc, /* 0.10.0 */
.domainIsPersistent = parallelsDomainIsPersistent, /* 0.10.0 */
.domainGetAutostart = parallelsDomainGetAutostart, /* 0.10.0 */
+ .domainSuspend = parallelsPauseDomain, /* 0.10.0 */
+ .domainResume = parallelsResumeDomain, /* 0.10.0 */
+ .domainDestroy = parallelsDestroyDomain, /* 0.10.0 */
+ .domainShutdown = parallelsShutdownDomain, /* 0.10.0 */
+ .domainCreate = parallelsDomainCreate, /* 0.10.0 */
};
I think I'd be happier if the creation /queueing of the virDomainEventPtr
parts where commented out, at least until we have dispatch of them
wired up, so the queue doesn't build up unbounded
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|