From 4ab2646127fbea861d270731bc2b81caabdbf2a9 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 14 Jun 2006 23:58:34 +0000 Subject: [PATCH] Added implementation of shutdown & reboot driver methods --- ChangeLog | 5 ++++ src/test.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/test.h | 2 ++ 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 388abc092c..7a9f228330 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Jun 14 18:59:30 EDT 2006 Daniel P. Berrange + + * src/test.h, src/test.c: Added implementation of the reboot + and shutdown methods for domains. + Wed Jun 14 11:20:23 EDT 2006 Daniel P. Berrange * src/libvirt.c: connect virDomainDestroy, virDomainSuspend, diff --git a/src/test.c b/src/test.c index ae46108a7b..09161f3132 100644 --- a/src/test.c +++ b/src/test.c @@ -33,8 +33,8 @@ static virDriver testDriver = { testLookupDomainByName, /* domainLookupByName */ testPauseDomain, /* domainSuspend */ testResumeDomain, /* domainResume */ - NULL, /* domainShutdown */ - NULL, /* domainReboot */ + testShutdownDomain, /* domainShutdown */ + testRebootDomain, /* domainReboot */ testDestroyDomain, /* domainDestroy */ NULL, /* domainFree */ NULL, /* domainGetName */ @@ -49,6 +49,9 @@ static virDriver testDriver = { NULL /* domainRestore */ }; +/* Amount of time it takes to shutdown */ +#define SHUTDOWN_DURATION 15 + typedef struct _testDev { char name[20]; virDeviceMode mode; @@ -62,6 +65,7 @@ typedef struct _testDom { unsigned char uuid[16]; virDomainKernel kernel; virDomainInfo info; + time_t shutdownStartedAt; virDomainRestart onRestart; int numDevices; testDev devices[MAX_DEVICES]; @@ -327,6 +331,44 @@ int testPauseDomain (virDomainPtr domain) return 0; } +/* We don't do an immediate shutdown. We basically pretend that + out shutdown sequence takes 'n' seconds to complete. SO, here + we just set state to shutdown, and subsquent calls to getDomainInfo + will check to see if shutdown ought to be marked complete. */ +int testShutdownDomain (virDomainPtr domain) +{ + testCon *con = &node->connections[domain->conn->handle]; + struct timeval tv; + if (gettimeofday(&tv, NULL) < 0) { + testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot get timeofday"); + return -1; + } + + con->domains[domain->handle].info.state = VIR_DOMAIN_SHUTDOWN; + con->domains[domain->handle].onRestart = VIR_DOMAIN_DESTROY; + con->domains[domain->handle].shutdownStartedAt = tv.tv_sec; + return 0; +} + +/* Similar behaviour as shutdown */ +int testRebootDomain (virDomainPtr domain, virDomainRestart action) +{ + testCon *con = &node->connections[domain->conn->handle]; + struct timeval tv; + if (gettimeofday(&tv, NULL) < 0) { + testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot get timeofday"); + return -1; + } + + if (!action) + action = VIR_DOMAIN_RESTART; + + con->domains[domain->handle].info.state = VIR_DOMAIN_SHUTDOWN; + con->domains[domain->handle].onRestart = action; + con->domains[domain->handle].shutdownStartedAt = tv.tv_sec; + return 0; +} + int testGetDomainInfo (virDomainPtr domain, virDomainInfoPtr info) { @@ -337,7 +379,40 @@ int testGetDomainInfo (virDomainPtr domain, return -1; } - con->domains[domain->handle].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll)); + /* Check to see if there is an in-progresss shutdown/reboot that + needs to be marked completed now */ + if (con->domains[domain->handle].info.state == VIR_DOMAIN_SHUTDOWN && + (tv.tv_sec - con->domains[domain->handle].shutdownStartedAt) > SHUTDOWN_DURATION) { + + switch (con->domains[domain->handle].onRestart) { + case VIR_DOMAIN_DESTROY: + con->domains[domain->handle].info.state = VIR_DOMAIN_SHUTOFF; + break; + + case VIR_DOMAIN_RESTART: + con->domains[domain->handle].info.state = VIR_DOMAIN_RUNNING; + break; + + case VIR_DOMAIN_PRESERVE: + con->domains[domain->handle].info.state = VIR_DOMAIN_SHUTOFF; + break; + + case VIR_DOMAIN_RENAME_RESTART: + con->domains[domain->handle].info.state = VIR_DOMAIN_RUNNING; + break; + + default: + con->domains[domain->handle].info.state = VIR_DOMAIN_SHUTOFF; + break; + } + } + + if (con->domains[domain->handle].info.state == VIR_DOMAIN_SHUTOFF) { + con->domains[domain->handle].info.cpuTime = 0; + con->domains[domain->handle].info.memory = 0; + } else { + con->domains[domain->handle].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll)); + } memcpy(info, &con->domains[domain->handle].info, sizeof(virDomainInfo)); return 0; } diff --git a/src/test.h b/src/test.h index 9281e27a25..757b1e4ea4 100644 --- a/src/test.h +++ b/src/test.h @@ -39,6 +39,8 @@ extern "C" { int testDestroyDomain(virDomainPtr domain); int testResumeDomain(virDomainPtr domain); int testPauseDomain(virDomainPtr domain); + int testShutdownDomain (virDomainPtr domain); + int testRebootDomain (virDomainPtr domain, virDomainRestart action); int testGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info); int testGetDomainID(virDomainPtr domain);