static PromiseResult RunningVirt(EvalContext *ctx, virConnectPtr vc, Attributes a, const Promise *pp) { virDomainPtr dom; virDomainInfo info; dom = virDomainLookupByName(vc, pp->promiser); PromiseResult result = PROMISE_RESULT_NOOP; if (dom) { if (virDomainGetInfo(dom, &info) == -1) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Unable to probe virtual domain '%s'", pp->promiser); virDomainFree(dom); return PROMISE_RESULT_FAIL; } switch (info.state) { case VIR_DOMAIN_RUNNING: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Virtual domain '%s' running - promise kept", pp->promiser); break; case VIR_DOMAIN_BLOCKED: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Virtual domain '%s' running but waiting for a resource - promise kept as far as possible", pp->promiser); break; case VIR_DOMAIN_SHUTDOWN: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' is shutting down", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); Log(LOG_LEVEL_VERBOSE, "It is currently impossible to know whether it will reboot or not - deferring promise check until it has completed its shutdown"); break; case VIR_DOMAIN_PAUSED: if (virDomainResume(dom) == -1) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' failed to resume after suspension", pp->promiser); virDomainFree(dom); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Virtual domain '%s' was suspended, resuming", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); break; case VIR_DOMAIN_SHUTOFF: if (virDomainCreate(dom) == -1) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' failed to resume after halting", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); virDomainFree(dom); return result; } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Virtual domain '%s' was inactive, booting...", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); break; case VIR_DOMAIN_CRASHED: if (virDomainReboot(dom, 0) == -1) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' has crashed and rebooting failed", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); virDomainFree(dom); return result; } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Virtual domain '%s' has crashed, rebooting...", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); break; default: Log(LOG_LEVEL_VERBOSE, "Virtual domain '%s' is reported as having no state, whatever that means", pp->promiser); break; } if (a.env.cpus > 0) { if (virDomainSetVcpus(dom, a.env.cpus) == -1) { Log(LOG_LEVEL_INFO, " Unable to set the number of cpus to %d", a.env.cpus); } else { Log(LOG_LEVEL_INFO, "Setting the number of virtual cpus to %d", a.env.cpus); } } if (a.env.memory != CF_NOINT) { if (virDomainSetMaxMemory(dom, (unsigned long) a.env.memory) == -1) { Log(LOG_LEVEL_INFO, " Unable to set the memory limit to %d", a.env.memory); } else { Log(LOG_LEVEL_INFO, "Setting the memory limit to %d", a.env.memory); } if (virDomainSetMemory(dom, (unsigned long) a.env.memory) == -1) { Log(LOG_LEVEL_INFO, " Unable to set the current memory to %d", a.env.memory); } } if (a.env.disk != CF_NOINT) { Log(LOG_LEVEL_VERBOSE, "Info: env_disk parameter is not currently supported on this platform"); } virDomainFree(dom); } else { Log(LOG_LEVEL_VERBOSE, "Virtual domain '%s' cannot be located, attempting to recreate", pp->promiser); result = PromiseResultUpdate(result, CreateVirtDom(ctx, vc, a, pp)); } return result; }
static int RunningVirt(virConnectPtr vc, char *uri, Attributes a, Promise *pp) { virDomainPtr dom; virDomainInfo info; dom = virDomainLookupByName(vc, pp->promiser); if (dom) { if (virDomainGetInfo(dom, &info) == -1) { cfPS(cf_inform, CF_FAIL, "", pp, a, " !! Unable to probe virtual domain \"%s\"", pp->promiser); virDomainFree(dom); return false; } switch (info.state) { case VIR_DOMAIN_RUNNING: cfPS(cf_verbose, CF_NOP, "", pp, a, " -> Virtual domain \"%s\" running - promise kept\n", pp->promiser); break; case VIR_DOMAIN_BLOCKED: cfPS(cf_verbose, CF_NOP, "", pp, a, " -> Virtual domain \"%s\" running but waiting for a resource - promise kept as far as possible\n", pp->promiser); break; case VIR_DOMAIN_SHUTDOWN: cfPS(cf_verbose, CF_INTERPT, "", pp, a, " -> Virtual domain \"%s\" is shutting down\n", pp->promiser); CfOut(cf_verbose, "", " -> It is currently impossible to know whether it will reboot or not - deferring promise check until it has completed its shutdown"); break; case VIR_DOMAIN_PAUSED: if (virDomainResume(dom) == -1) { cfPS(cf_verbose, CF_INTERPT, "", pp, a, " -> Virtual domain \"%s\" failed to resume after suspension\n", pp->promiser); virDomainFree(dom); return false; } cfPS(cf_verbose, CF_CHG, "", pp, a, " -> Virtual domain \"%s\" was suspended, resuming\n", pp->promiser); break; case VIR_DOMAIN_SHUTOFF: if (virDomainCreate(dom) == -1) { cfPS(cf_verbose, CF_INTERPT, "", pp, a, " -> Virtual domain \"%s\" failed to resume after halting\n", pp->promiser); virDomainFree(dom); return false; } cfPS(cf_verbose, CF_CHG, "", pp, a, " -> Virtual domain \"%s\" was inactive, booting...\n", pp->promiser); break; case VIR_DOMAIN_CRASHED: if (virDomainReboot(dom, 0) == -1) { cfPS(cf_verbose, CF_INTERPT, "", pp, a, " -> Virtual domain \"%s\" has crashed and rebooting failed\n", pp->promiser); virDomainFree(dom); return false; } cfPS(cf_verbose, CF_CHG, "", pp, a, " -> Virtual domain \"%s\" has crashed, rebooting...\n", pp->promiser); break; default: CfOut(cf_verbose, "", " !! Virtual domain \"%s\" is reported as having no state, whatever that means", pp->promiser); break; } if (a.env.cpus > 0) { if (virDomainSetVcpus(dom, a.env.cpus) == -1) { CfOut(cf_inform, "", " !!! Unable to set the number of cpus to %d", a.env.cpus); } else { CfOut(cf_inform, "", " -> Setting the number of virtual cpus to %d", a.env.cpus); } } if (a.env.memory != CF_NOINT) { if (virDomainSetMaxMemory(dom, (unsigned long) a.env.memory) == -1) { CfOut(cf_inform, "", " !!! Unable to set the memory limit to %d", a.env.memory); } else { CfOut(cf_inform, "", " -> Setting the memory limit to %d", a.env.memory); } if (virDomainSetMemory(dom, (unsigned long) a.env.memory) == -1) { CfOut(cf_inform, "", " !!! Unable to set the current memory to %d", a.env.memory); } } if (a.env.disk != CF_NOINT) { CfOut(cf_verbose, "", " -> Info: env_disk parameter is not currently supported on this platform"); } virDomainFree(dom); } else { CfOut(cf_verbose, "", " -> Virtual domain \"%s\" cannot be located, attempting to recreate", pp->promiser); CreateVirtDom(vc, uri, a, pp); } return true; }
static PromiseResult CreateVirtDom(EvalContext *ctx, virConnectPtr vc, Attributes a, const Promise *pp) { int alloc_file = false; char *xml_file; const char *name; char defaultxml[CF_MAXVARSIZE]; virDomainPtr dom; int i; snprintf(defaultxml, CF_MAXVARSIZE - 1, "<domain type='test'>" " <name>%s</name>" " <memory>8388608</memory>" " <currentMemory>2097152</currentMemory>" " <vcpu>2</vcpu>" " <os>" " <type>hvm</type>" " </os>" "</domain>", pp->promiser); for (i = 0; i < CF_MAX_CONCURRENT_ENVIRONMENTS; i++) { if (CF_RUNNING[i] > 0) { dom = virDomainLookupByID(vc, CF_RUNNING[i]); name = virDomainGetName(dom); if (name && strcmp(name, pp->promiser) == 0) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Found a running environment called '%s' - promise kept", name); return PROMISE_RESULT_NOOP; } virDomainFree(dom); } } for (i = 0; CF_SUSPENDED[i] != NULL; i++) { if (strcmp(CF_SUSPENDED[i], pp->promiser) == 0) { Log(LOG_LEVEL_INFO, "Found an existing, but suspended, environment id = %s, called '%s'", CF_SUSPENDED[i], CF_SUSPENDED[i]); } } if(a.env.spec) { xml_file = xstrdup(a.env.spec); alloc_file = true; } else { Log(LOG_LEVEL_VERBOSE, "No spec file is promised, so reverting to default settings"); xml_file = defaultxml; } PromiseResult result = PROMISE_RESULT_NOOP; if ((dom = virDomainCreateXML(vc, xml_file, 0))) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Created a virtual domain '%s'", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); if (a.env.cpus != CF_NOINT) { int maxcpus; if ((maxcpus = virConnectGetMaxVcpus(vc, virConnectGetType(vc))) == -1) { Log(LOG_LEVEL_VERBOSE, "Can't determine the available CPU resources"); } else { if (a.env.cpus > maxcpus) { Log(LOG_LEVEL_INFO, "The promise to allocate %d CPUs in domain '%s' cannot be kept - only %d exist on the host", a.env.cpus, pp->promiser, maxcpus); } else if (virDomainSetVcpus(dom, (unsigned int) a.env.cpus) == -1) { Log(LOG_LEVEL_INFO, "Unable to adjust CPU count to %d", a.env.cpus); } else { Log(LOG_LEVEL_INFO, "Verified that environment CPU count is now %d", a.env.cpus); } } } if (a.env.memory != CF_NOINT) { unsigned long maxmem; if ((maxmem = virDomainGetMaxMemory(dom)) == -1) { Log(LOG_LEVEL_VERBOSE, "Can't determine the available CPU resources"); } else { if (virDomainSetMaxMemory(dom, (unsigned long) a.env.memory) == -1) { Log(LOG_LEVEL_INFO, " Unable to set the memory limit to %d", a.env.memory); } else { Log(LOG_LEVEL_INFO, "Setting the memory limit to %d", a.env.memory); } if (virDomainSetMemory(dom, (unsigned long) a.env.memory) == -1) { Log(LOG_LEVEL_INFO, " Unable to set the current memory to %d", a.env.memory); } } } if (a.env.disk != CF_NOINT) { Log(LOG_LEVEL_VERBOSE, "Info: env_disk parameter is not currently supported on this platform"); } virDomainFree(dom); } else { virErrorPtr vp; vp = virGetLastError(); cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Failed to create a virtual domain '%s' - check spec for errors: '%s'", pp->promiser, vp->message); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); Log(LOG_LEVEL_VERBOSE, "Quoted spec file: %s", xml_file); } if (alloc_file) { free(xml_file); } return result; }
static int CreateVirtDom(virConnectPtr vc, char *uri, Attributes a, Promise *pp) { int alloc_file = false; char *xml_file; const char *name; char defaultxml[CF_MAXVARSIZE]; virDomainPtr dom; int i; snprintf(defaultxml, CF_MAXVARSIZE - 1, "<domain type='test'>" " <name>%s</name>" " <memory>8388608</memory>" " <currentMemory>2097152</currentMemory>" " <vcpu>2</vcpu>" " <os>" " <type>hvm</type>" " </os>" "</domain>", pp->promiser); for (i = 0; i < CF_MAX_CONCURRENT_ENVIRONMENTS; i++) { if (CF_RUNNING[i] > 0) { dom = virDomainLookupByID(vc, CF_RUNNING[i]); name = virDomainGetName(dom); if (name && strcmp(name, pp->promiser) == 0) { cfPS(cf_verbose, CF_NOP, "", pp, a, " -> Found a running environment called \"%s\" - promise kept\n", name); return true; } virDomainFree(dom); } } for (i = 0; CF_SUSPENDED[i] != NULL; i++) { if (strcmp(CF_SUSPENDED[i], pp->promiser) == 0) { CfOut(cf_inform, "", " -> Found an existing, but suspended, environment id = %s, called \"%s\"\n", CF_SUSPENDED[i], CF_SUSPENDED[i]); } } if(a.env.spec) { xml_file = xstrdup(a.env.spec); alloc_file = true; } else { CfOut(cf_verbose, "", "No spec file is promised, so reverting to default settings"); xml_file = defaultxml; } if ((dom = virDomainCreateXML(vc, xml_file, 0))) { cfPS(cf_verbose, CF_CHG, "", pp, a, " -> Created a virtual domain \"%s\"\n", pp->promiser); if (a.env.cpus != CF_NOINT) { int maxcpus; if ((maxcpus = virConnectGetMaxVcpus(vc, virConnectGetType(vc))) == -1) { CfOut(cf_verbose, "", " !! Can't determine the available CPU resources"); } else { if (a.env.cpus > maxcpus) { CfOut(cf_inform, "", " !! The promise to allocate %d CPUs in domain \"%s\" cannot be kept - only %d exist on the host", a.env.cpus, pp->promiser, maxcpus); } else if (virDomainSetVcpus(dom, (unsigned int) a.env.cpus) == -1) { CfOut(cf_inform, "", " -> Unable to adjust CPU count to %d", a.env.cpus); } else { CfOut(cf_inform, "", " -> Verified that environment CPU count is now %d", a.env.cpus); } } } if (a.env.memory != CF_NOINT) { unsigned long maxmem; if ((maxmem = virDomainGetMaxMemory(dom)) == -1) { CfOut(cf_verbose, "", " !! Can't determine the available CPU resources"); } else { if (virDomainSetMaxMemory(dom, (unsigned long) a.env.memory) == -1) { CfOut(cf_inform, "", " !!! Unable to set the memory limit to %d", a.env.memory); } else { CfOut(cf_inform, "", " -> Setting the memory limit to %d", a.env.memory); } if (virDomainSetMemory(dom, (unsigned long) a.env.memory) == -1) { CfOut(cf_inform, "", " !!! Unable to set the current memory to %d", a.env.memory); } } } if (a.env.disk != CF_NOINT) { CfOut(cf_verbose, "", " -> Info: env_disk parameter is not currently supported on this platform"); } virDomainFree(dom); } else { virErrorPtr vp; vp = virGetLastError(); cfPS(cf_verbose, CF_FAIL, "", pp, a, " !! Failed to create a virtual domain \"%s\" - check spec for errors: %s", pp->promiser, vp->message); CfOut(cf_verbose, "", "Quoted spec file: %s", xml_file); } if (alloc_file) { free(xml_file); } return true; }