From 1cc9f9b3d87a63a30e0c95a16f42b6a596686745 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 5 Sep 2008 14:10:58 +0000 Subject: [PATCH] Convert openvz driver to generic domain XML APIs --- ChangeLog | 5 + src/openvz_conf.c | 580 ++++++++++---------------------------------- src/openvz_conf.h | 95 ++------ src/openvz_driver.c | 408 +++++++++++++++++-------------- src/openvz_driver.h | 18 -- 5 files changed, 368 insertions(+), 738 deletions(-) diff --git a/ChangeLog b/ChangeLog index f82548c2b1..5f23513c19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Fri Sep 5 15:09:26 BST 2008 Daniel P. Berrange + + * src/openvz_conf.c, src/openvz_conf.h, src/openvz_driver.c, + src/openvz_driver.h: Convert to generic domain XML apis + Fri Sep 5 13:02:26 BST 2008 Daniel P. Berrange Fully support mingw builds diff --git a/src/openvz_conf.c b/src/openvz_conf.c index 7d75719aee..1ccf9239ee 100644 --- a/src/openvz_conf.c +++ b/src/openvz_conf.c @@ -40,39 +40,29 @@ #include #include #include +#include -#include -#include -#include -#include - -#include "internal.h" - -#include "openvz_driver.h" #include "openvz_conf.h" #include "uuid.h" #include "buf.h" #include "memory.h" #include "util.h" -#include "xml.h" -#include "domain_conf.h" static char *openvzLocateConfDir(void); -static struct openvz_vm_def *openvzParseXML(virConnectPtr conn, xmlDocPtr xml); static int openvzGetVPSUUID(int vpsid, char *uuidstr); -static int openvzSetUUID(int vpsid); static int openvzLocateConfFile(int vpsid, char *conffile, int maxlen); +static int openvzAssignUUIDs(void); void openvzError (virConnectPtr conn, virErrorNumber code, const char *fmt, ...) { va_list args; - char errorMessage[OPENVZ_MAX_ERROR_LEN]; + char errorMessage[1024]; const char *errmsg; if (fmt) { va_start(args, fmt); - vsnprintf(errorMessage, OPENVZ_MAX_ERROR_LEN-1, fmt, args); + vsnprintf(errorMessage, sizeof(errorMessage)-1, fmt, args); va_end(args); } else { errorMessage[0] = '\0'; @@ -84,46 +74,6 @@ openvzError (virConnectPtr conn, virErrorNumber code, const char *fmt, ...) errmsg, errorMessage); } -struct openvz_vm -*openvzFindVMByID(const struct openvz_driver *driver, int id) { - struct openvz_vm *vm = driver->vms; - - while (vm) { - if (vm->vpsid == id) - return vm; - vm = vm->next; - } - - return NULL; -} - -struct openvz_vm -*openvzFindVMByUUID(const struct openvz_driver *driver, - const unsigned char *uuid) { - struct openvz_vm *vm = driver->vms; - - while (vm) { - if (!memcmp(vm->vmdef->uuid, uuid, VIR_UUID_BUFLEN)) - return vm; - vm = vm->next; - } - - return NULL; -} - -struct openvz_vm -*openvzFindVMByName(const struct openvz_driver *driver, - const char *name) { - struct openvz_vm *vm = driver->vms; - - while (vm) { - if (STREQ(vm->vmdef->name, name)) - return vm; - vm = vm->next; - } - - return NULL; -} int strtoI(const char *str) @@ -136,6 +86,43 @@ strtoI(const char *str) return val; } +virCapsPtr openvzCapsInit(void) +{ + struct utsname utsname; + virCapsPtr caps; + virCapsGuestPtr guest; + + uname(&utsname); + + if ((caps = virCapabilitiesNew(utsname.machine, + 0, 0)) == NULL) + goto no_memory; + + if ((guest = virCapabilitiesAddGuest(caps, + "exe", + utsname.machine, + sizeof(int) == 4 ? 32 : 8, + NULL, + NULL, + 0, + NULL)) == NULL) + goto no_memory; + + if (virCapabilitiesAddGuestDomain(guest, + "openvz", + NULL, + NULL, + 0, + NULL) == NULL) + goto no_memory; + return caps; + +no_memory: + virCapabilitiesFree(caps); + return NULL; +} + + /* function checks MAC address is empty return 0 - empty 1 - not @@ -164,438 +151,117 @@ char *openvzMacToString(const unsigned char *mac) return strdup(str); } -void -openvzRemoveInactiveVM(struct openvz_driver *driver, struct openvz_vm *vm) -{ - driver->num_inactive--; - openvzFreeVM(driver, vm, 1); -} - -/* Free all memory associated with a openvz_vm_def structure */ -void -openvzFreeVMDef(struct openvz_vm_def *def) -{ - if (def) { - virDomainNetDefFree(def->net); - } -} - -/* Free all memory associated with a openvz_vm structure - * @checkCallee == 0 then openvzFreeDriver() is callee else some other function - */ -void -openvzFreeVM(struct openvz_driver *driver, struct openvz_vm *vm, - int checkCallee) -{ - struct openvz_vm *vms; - - if (!vm && !driver) - return; - vms = driver->vms; - if (checkCallee) { - if (vms == vm) - driver->vms = vm->next; - else { - while (vms) { - struct openvz_vm *prev = vms; - - vms = vms->next; - if (vms == vm) { - prev->next = vms->next; - break; - } - } - } - } - if (vms) { - openvzFreeVMDef(vm->vmdef); - VIR_FREE(vm); - } -} - /* Free all memory associated with a openvz_driver structure */ void openvzFreeDriver(struct openvz_driver *driver) { - struct openvz_vm *next; - + virDomainObjPtr dom; + if (!driver) return; - if (driver->vms) - for(next = driver->vms->next; driver->vms; driver->vms = next) - openvzFreeVM(driver, driver->vms, 0); - VIR_FREE(driver); -} - -struct openvz_vm * -openvzAssignVMDef(virConnectPtr conn, - struct openvz_driver *driver, struct openvz_vm_def *def) -{ - struct openvz_vm *vm = NULL; - - if (!driver || !def) - return NULL; - - if ((vm = openvzFindVMByName(driver, def->name))) { - if (!openvzIsActiveVM(vm)) { - openvzFreeVMDef(vm->vmdef); - vm->vmdef = def; - } - else - { - openvzLog(OPENVZ_ERR, - _("Error already an active OPENVZ VM having id '%s'"), - def->name); - openvzFreeVMDef(def); - return NULL; /* can't redefine an active domain */ - } - - return vm; - } - - if (VIR_ALLOC(vm) < 0) { - openvzFreeVMDef(def); - openvzError(conn, VIR_ERR_NO_MEMORY, _("vm")); - return NULL; - } - - vm->vpsid = -1; /* -1 needed for to represent inactiveness of domain before 'start' */ - vm->status = VIR_DOMAIN_SHUTOFF; - vm->vmdef = def; - vm->next = driver->vms; - - driver->vms = vm; - driver->num_inactive++; - - return vm; -} - -struct openvz_vm_def -*openvzParseVMDef(virConnectPtr conn, - const char *xmlStr, const char *displayName) -{ - xmlDocPtr xml; - struct openvz_vm_def *def = NULL; - - xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName : "domain.xml", NULL, - XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_NOERROR | XML_PARSE_NOWARNING); - if (!xml) { - openvzError(conn, VIR_ERR_XML_ERROR, NULL); - return NULL; - } - - def = openvzParseXML(conn, xml); - xmlFreeDoc(xml); - - return def; -} - -/* Parse filesystem section -Sample: - - - - - -*/ -static int openvzParseDomainFS(virConnectPtr conn, - struct openvz_fs_def *fs, - xmlXPathContextPtr ctxt) -{ - xmlNodePtr cur, obj; - char *type = NULL; - int n; - xmlNodePtr *nodes = NULL; - - - if ((n = virXPathNodeSet(conn, "/domain/devices/filesystem", - ctxt, &nodes)) < 0) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("missing filesystem tag")); - goto error; - } - - if (n > 1) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("There should be only one filesystem tag")); - goto error; + + dom = driver->domains; + while (dom) { + virDomainObjPtr tmp = dom->next; + virDomainObjFree(dom); + dom = tmp; } + + virCapabilitiesFree(driver->caps); +} - obj = nodes[0]; - /*check template type*/ - type = virXMLPropString(obj, "type"); - if (type == NULL) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("missing type attribute")); - goto error; - } - if (STRNEQ(type, "template")) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("Unknown type attribute %s"), type); - goto error; - } - VIR_FREE(type); - - cur = obj->children; - while(cur != NULL) - { - if (cur->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(cur->name, BAD_CAST "source")) { - char * name = virXMLPropString(cur, "name"); - - if (name != NULL) { - strncpy(fs->tmpl, name,sizeof(fs->tmpl)); - fs->tmpl[sizeof(fs->tmpl) - 1] = '\0'; - } - VIR_FREE(name); - } else if (xmlStrEqual(cur->name, BAD_CAST "quota")) { - char * qtype = virXMLPropString(cur, "type"); - char * max = virXMLPropString(cur, "max"); - - if (qtype != NULL && STREQ(qtype, "size") && max != NULL) - fs->disksize = strtoI(max); - else if (qtype != NULL && STREQ(qtype, "inodes") && max != NULL) - fs->diskinodes = strtoI(max); - VIR_FREE(qtype); - VIR_FREE(max); - } - } - cur = cur->next; - } - VIR_FREE(nodes); - - return 0; - - error: - VIR_FREE(nodes); - VIR_FREE(type); - - return -1; -} - - -/* - * Parses a libvirt XML definition of a guest, and populates the - * the openvz_vm struct with matching data about the guests config - */ -static struct openvz_vm_def -*openvzParseXML(virConnectPtr conn, - xmlDocPtr xml) { - xmlNodePtr root = NULL; - char *prop = NULL; - xmlXPathContextPtr ctxt = NULL; - xmlXPathObjectPtr obj = NULL; - struct openvz_vm_def *def = NULL; - xmlNodePtr *nodes = NULL; - int i, n; - - if (VIR_ALLOC(def) < 0) { - openvzError(conn, VIR_ERR_NO_MEMORY, _("xmlXPathContext")); - return NULL; - } - - /* Prepare parser / xpath context */ - root = xmlDocGetRootElement(xml); - if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "domain"))) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("incorrect root element")); - goto bail_out; - } - - ctxt = xmlXPathNewContext(xml); - if (ctxt == NULL) { - openvzError(conn, VIR_ERR_NO_MEMORY, _("xmlXPathContext")); - goto bail_out; - } - ctxt->node = root; - - /* Find out what type of OPENVZ virtualization to use */ - if (!(prop = virXMLPropString(root, "type"))) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("missing domain type attribute")); - goto bail_out; - } - - if (STRNEQ(prop, "openvz")){ - openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("invalid domain type attribute")); - goto bail_out; - } - VIR_FREE(prop); - - /* Extract domain name */ - obj = xmlXPathEval(BAD_CAST "string(/domain/name[1])", ctxt); - if ((obj == NULL) || (obj->type != XPATH_STRING) || - (obj->stringval == NULL) || (obj->stringval[0] == 0)) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("invalid domain name")); - goto bail_out; - } - - /* rejecting VPS ID <= OPENVZ_RSRV_VM_LIMIT for they are reserved */ - if (strtoI((const char *) obj->stringval) <= OPENVZ_RSRV_VM_LIMIT) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("VPS ID Error (must be an integer greater than 100")); - goto bail_out; - } - strncpy(def->name, (const char *) obj->stringval, OPENVZ_NAME_MAX); - xmlXPathFreeObject(obj); - obj = NULL; - - /* Extract domain uuid */ - prop = virXPathString(conn, "string(./uuid[1])", ctxt); - if (!prop) { - int err; - if ((err = virUUIDGenerate(def->uuid))) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("Failed to generate UUID: %s"), - strerror(err)); - goto bail_out; - } - } else { - if (virUUIDParse(prop, def->uuid) < 0) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("malformed uuid element")); - goto bail_out; - } - VIR_FREE(prop); - } - - /* extract virtual CPUs */ - if (virXPathULong(conn, "string(./vcpu[1])", ctxt, &def->vcpus) < 0) - def->vcpus = 0; //use default CPUs count - - /* Extract filesystem info */ - if (openvzParseDomainFS(conn, &(def->fs), ctxt)) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("malformed filesystem tag")); - goto bail_out; - } - - /* analysis of the network devices */ - if ((n = virXPathNodeSet(conn, "/domain/devices/interface", - ctxt, &nodes)) < 0) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, - "%s", _("cannot extract network devices")); - goto bail_out; - } - - for (i = n - 1 ; i >= 0 ; i--) { - virDomainNetDefPtr net = virDomainNetDefParseXML(conn, - nodes[i]); - if (!net) - goto bail_out; - - net->next = def->net; - def->net = net; - } - VIR_FREE(nodes); - - xmlXPathFreeContext(ctxt); - return def; - - bail_out: - VIR_FREE(prop); - xmlXPathFreeObject(obj); - xmlXPathFreeContext(ctxt); - openvzFreeVMDef(def); - - return NULL; -} - -struct openvz_vm * -openvzGetVPSInfo(virConnectPtr conn) { +int openvzLoadDomains(struct openvz_driver *driver) { FILE *fp; int veid, ret; char status[16]; char uuidstr[VIR_UUID_STRING_BUFLEN]; - struct openvz_vm *vm; - struct openvz_vm **pnext; - struct openvz_driver *driver; - struct openvz_vm_def *vmdef; - char temp[124]; - - vm = NULL; - driver = conn->privateData; - driver->num_active = 0; - driver->num_inactive = 0; - - if((fp = popen(VZLIST " -a -ovpsid,status -H 2>/dev/null", "r")) == NULL) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("popen failed")); - return NULL; - } - pnext = &vm; - while(!feof(fp)) { - if (VIR_ALLOC(*pnext) < 0) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("calloc failed")); - goto error; - } + virDomainObjPtr dom = NULL, prev = NULL; + char temp[50]; - if(!vm) - vm = *pnext; + if (openvzAssignUUIDs() < 0) + return -1; + if ((fp = popen(VZLIST " -a -ovpsid,status -H 2>/dev/null", "r")) == NULL) { + openvzError(NULL, VIR_ERR_INTERNAL_ERROR, _("popen failed")); + return -1; + } + + while(!feof(fp)) { if (fscanf(fp, "%d %s\n", &veid, status) != 2) { if (feof(fp)) break; - - openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("Failed to parse vzlist output")); - goto error; - } - if(STRNEQ(status, "stopped")) { - (*pnext)->status = VIR_DOMAIN_RUNNING; - driver->num_active ++; - (*pnext)->vpsid = veid; + + openvzError(NULL, VIR_ERR_INTERNAL_ERROR, + _("Failed to parse vzlist output")); + goto cleanup; } - else { - (*pnext)->status = VIR_DOMAIN_SHUTOFF; - driver->num_inactive ++; - /* - * inactive domains don't have their ID set in libvirt, - * thought this doesn't make sense for OpenVZ - */ - (*pnext)->vpsid = -1; - } - - if (VIR_ALLOC(vmdef) < 0) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("calloc failed")); - goto error; + + if (VIR_ALLOC(dom) < 0 || + VIR_ALLOC(dom->def) < 0) + goto no_memory; + + if (STREQ(status, "stopped")) + dom->state = VIR_DOMAIN_SHUTOFF; + else + dom->state = VIR_DOMAIN_RUNNING; + + dom->pid = veid; + dom->def->id = dom->state == VIR_DOMAIN_SHUTOFF ? -1 : veid; + + if (asprintf(&dom->def->name, "%i", veid) < 0) { + dom->def->name = NULL; + goto no_memory; } - - snprintf(vmdef->name, OPENVZ_NAME_MAX, "%i", veid); + openvzGetVPSUUID(veid, uuidstr); - ret = virUUIDParse(uuidstr, vmdef->uuid); - - if(ret == -1) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("UUID in config file malformed")); - VIR_FREE(vmdef); - goto error; + ret = virUUIDParse(uuidstr, dom->def->uuid); + + if (ret == -1) { + openvzError(NULL, VIR_ERR_INTERNAL_ERROR, + _("UUID in config file malformed")); + goto cleanup; } + + if (!(dom->def->os.type = strdup("exe"))) + goto no_memory; + if (!(dom->def->os.init = strdup("/sbin/init"))) + goto no_memory; - /*get VCPU*/ ret = openvzReadConfigParam(veid, "CPUS", temp, sizeof(temp)); if (ret < 0) { - openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("Cound not read config for container %d"), veid); - goto error; + openvzError(NULL, VIR_ERR_INTERNAL_ERROR, + _("Cound not read config for container %d"), + veid); + goto cleanup; } else if (ret > 0) { - vmdef->vcpus = strtoI(temp); + dom->def->vcpus = strtoI(temp); + } else { + dom->def->vcpus = 1; } - - (*pnext)->vmdef = vmdef; - pnext = &(*pnext)->next; - } - return vm; -error: - while (vm != NULL) { - struct openvz_vm *next; - - next = vm->next; - VIR_FREE(vm->vmdef); - VIR_FREE(vm); - vm = next; + /* XXX load rest of VM config data .... */ + + if (prev) { + prev->next = dom; + } else { + driver->domains = dom; + } + prev = dom; } - return NULL; + + fclose(fp); + + return 0; + + no_memory: + openvzError(NULL, VIR_ERR_NO_MEMORY, NULL); + + cleanup: + fclose(fp); + virDomainObjFree(dom); + return -1; } /* @@ -797,7 +463,7 @@ openvzSetUUID(int vpsid){ * */ -int openvzAssignUUIDs(void) +static int openvzAssignUUIDs(void) { DIR *dp; struct dirent *dent; diff --git a/src/openvz_conf.h b/src/openvz_conf.h index da18407985..68c00ea5b0 100644 --- a/src/openvz_conf.h +++ b/src/openvz_conf.h @@ -28,94 +28,35 @@ #ifndef OPENVZ_CONF_H #define OPENVZ_CONF_H -#include "openvz_driver.h" +#include "internal.h" #include "domain_conf.h" enum { OPENVZ_WARN, OPENVZ_ERR }; -#define OPENVZ_NAME_MAX 8 -#define OPENVZ_TMPL_MAX 256 -#define OPENVZ_UNAME_MAX 32 -#define OPENVZ_IP_MAX 16 -#define OPENVZ_HOSTNAME_MAX 256 -#define OPENVZ_PROFILE_MAX 256 -#define OPENVZ_MAX_ERROR_LEN 1024 -#define OPENVZ_MAX_XML_LEN 4096 -#define OPENVZ_MAX_QUOTA 8 -#define OPENVZ_MAX_XPathEval_LEN 256 -#define OPENVZ_RSRV_VM_LIMIT 100 - -enum openvz_quota{ - VM_LEVEL = 0, - USER_LEVEL = 1, -}; - -/* TODO Add more properties here */ -struct vps_props { - int kmemsize; /* currently held */ - int kmemsize_m; /* max held */ - int kmemsize_b; /* barrier */ - int kmemsize_l; /* limit */ - int kmemsize_f; /* fail count */ - -}; - -struct openvz_fs_def { - char tmpl[OPENVZ_TMPL_MAX]; - long int disksize, diskinodes; -}; - -struct openvz_vm_def { - char name[OPENVZ_NAME_MAX]; - unsigned char uuid[VIR_UUID_BUFLEN]; - char profile[OPENVZ_PROFILE_MAX]; - unsigned long vcpus; - struct openvz_fs_def fs; - virDomainNetDefPtr net; +#define openvzLog(level, msg...) { if(level == OPENVZ_WARN) \ + fprintf(stderr, "\nWARNING: ");\ + else \ + fprintf(stderr, "\nERROR: ");\ + fprintf(stderr, "\n\t");\ + fprintf(stderr, msg);\ + fprintf(stderr, "\n"); } + +/* OpenVZ commands - Replace with wrapper scripts later? */ +#define VZLIST "vzlist" +#define VZCTL "vzctl" + +struct openvz_driver { + virCapsPtr caps; + virDomainObjPtr domains; }; -struct ovz_quota { - enum openvz_quota type; - unsigned int size; - char uname[OPENVZ_UNAME_MAX]; - struct ovz_quota *next; -}; - -struct openvz_vm { - int vpsid; - int status; - struct openvz_vm_def *vmdef; - struct openvz_vm *next; -}; - -static inline int -openvzIsActiveVM(struct openvz_vm *vm) -{ - return vm->vpsid != -1; -} - void openvzError (virConnectPtr conn, virErrorNumber code, const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 3, 4); int openvz_readline(int fd, char *ptr, int maxlen); int openvzReadConfigParam(int vpsid ,const char * param, char *value, int maxlen); -struct openvz_vm *openvzFindVMByID(const struct openvz_driver *driver, int id); -struct openvz_vm *openvzFindVMByUUID(const struct openvz_driver *driver, - const unsigned char *uuid); - -struct openvz_vm *openvzFindVMByName(const struct openvz_driver *driver, const char *name); -struct openvz_vm_def *openvzParseVMDef(virConnectPtr conn, const char *xmlStr, - const char *displayName); - -struct openvz_vm *openvzAssignVMDef(virConnectPtr conn, struct openvz_driver *driver, - struct openvz_vm_def *def); - -struct openvz_vm *openvzGetVPSInfo(virConnectPtr conn); -void openvzGenerateUUID(unsigned char *uuid); -int openvzAssignUUIDs(void); -void openvzRemoveInactiveVM(struct openvz_driver *driver, struct openvz_vm *vm); +virCapsPtr openvzCapsInit(void); +int openvzLoadDomains(struct openvz_driver *driver); void openvzFreeDriver(struct openvz_driver *driver); -void openvzFreeVM(struct openvz_driver *driver, struct openvz_vm *vm, int checkCallee); -void openvzFreeVMDef(struct openvz_vm_def *def); int strtoI(const char *str); int openvzCheckEmptyMac(const unsigned char *mac); char *openvzMacToString(const unsigned char *mac); diff --git a/src/openvz_driver.c b/src/openvz_driver.c index ef0d0e053e..dd28303fe0 100644 --- a/src/openvz_driver.c +++ b/src/openvz_driver.c @@ -60,33 +60,6 @@ #define CMDBUF_LEN 1488 #define CMDOP_LEN 288 -static virDomainPtr openvzDomainLookupByID(virConnectPtr conn, int id); -static char *openvzGetOSType(virDomainPtr dom); -static int openvzGetNodeInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo); -static virDomainPtr openvzDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid); -static virDomainPtr openvzDomainLookupByName(virConnectPtr conn, const char *name); -static int openvzDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info); -static int openvzDomainShutdown(virDomainPtr dom); -static int openvzDomainReboot(virDomainPtr dom, unsigned int flags); -static int openvzDomainCreate(virDomainPtr dom); -static virDrvOpenStatus openvzOpen(virConnectPtr conn, - xmlURIPtr uri, - virConnectAuthPtr auth ATTRIBUTE_UNUSED, - int flags ATTRIBUTE_UNUSED); -static int openvzClose(virConnectPtr conn); -static const char *openvzGetType(virConnectPtr conn ATTRIBUTE_UNUSED); -static int openvzListDomains(virConnectPtr conn, int *ids, int nids); -static int openvzNumDomains(virConnectPtr conn); -static int openvzListDefinedDomains(virConnectPtr conn, char **const names, int nnames); -static int openvzNumDefinedDomains(virConnectPtr conn); - -static virDomainPtr openvzDomainDefineXML(virConnectPtr conn, const char *xml); -static virDomainPtr openvzDomainCreateLinux(virConnectPtr conn, const char *xml, - unsigned int flags ATTRIBUTE_UNUSED); - -static int openvzDomainUndefine(virDomainPtr dom); -static void cmdExecFree(const char *cmdExec[]); - static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid); static int openvzGetMaxVCPUs(virConnectPtr conn, const char *type); static int openvzDomainGetMaxVcpus(virDomainPtr dom); @@ -110,7 +83,7 @@ static void cmdExecFree(const char *cmdExec[]) static int openvzDomainDefineCmd(virConnectPtr conn, const char *args[], int maxarg, - struct openvz_vm_def *vmdef) + virDomainDefPtr vmdef) { int narg; @@ -143,15 +116,29 @@ static int openvzDomainDefineCmd(virConnectPtr conn, ADD_ARG_LIT("--quiet"); ADD_ARG_LIT("create"); ADD_ARG_LIT(vmdef->name); + + if (vmdef->fss) { + if (vmdef->fss->type != VIR_DOMAIN_FS_TYPE_TEMPLATE) { + openvzError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("only filesystem templates are supported")); + return -1; + } + + if (vmdef->fss->next) { + openvzError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("only one filesystem supported")); + return -1; + } - if ((vmdef->fs.tmpl && *(vmdef->fs.tmpl))) { ADD_ARG_LIT("--ostemplate"); - ADD_ARG_LIT(vmdef->fs.tmpl); + ADD_ARG_LIT(vmdef->fss->src); } +#if 0 if ((vmdef->profile && *(vmdef->profile))) { ADD_ARG_LIT("--config"); ADD_ARG_LIT(vmdef->profile); } +#endif ADD_ARG(NULL); return 0; @@ -165,39 +152,48 @@ static int openvzDomainDefineCmd(virConnectPtr conn, static virDomainPtr openvzDomainLookupByID(virConnectPtr conn, - int id) { + int id) { struct openvz_driver *driver = (struct openvz_driver *)conn->privateData; - struct openvz_vm *vm; + virDomainObjPtr vm; virDomainPtr dom; - vm = openvzFindVMByID(driver, id); + vm = virDomainFindByID(driver->domains, id); if (!vm) { openvzError(conn, VIR_ERR_NO_DOMAIN, NULL); return NULL; } - dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid); - if (!dom) { - openvzError(conn, VIR_ERR_NO_MEMORY, _("virDomainPtr")); + dom = virGetDomain(conn, vm->def->name, vm->def->uuid); + if (!dom) return NULL; - } - dom->id = vm->vpsid; + dom->id = vm->def->id; return dom; } -static char *openvzGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) +static char *openvzGetOSType(virDomainPtr dom) { - /* OpenVZ runs on Linux and runs only Linux */ - return strdup("linux"); + struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData; + virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid); + char *ret; + + if (!vm) { + openvzError(dom->conn, VIR_ERR_NO_DOMAIN, NULL); + return NULL; + } + + if (!(ret = strdup(vm->def->os.type))) + openvzError(dom->conn, VIR_ERR_NO_MEMORY, NULL); + + return ret; } static virDomainPtr openvzDomainLookupByUUID(virConnectPtr conn, - const unsigned char *uuid) { + const unsigned char *uuid) { struct openvz_driver *driver = (struct openvz_driver *)conn->privateData; - struct openvz_vm *vm = openvzFindVMByUUID(driver, uuid); + virDomainObjPtr vm = virDomainFindByUUID(driver->domains, uuid); virDomainPtr dom; if (!vm) { @@ -205,20 +201,18 @@ static virDomainPtr openvzDomainLookupByUUID(virConnectPtr conn, return NULL; } - dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid); - if (!dom) { - openvzError(conn, VIR_ERR_NO_MEMORY, _("virDomainPtr")); + dom = virGetDomain(conn, vm->def->name, vm->def->uuid); + if (!dom) return NULL; - } - dom->id = vm->vpsid; + dom->id = vm->def->id; return dom; } static virDomainPtr openvzDomainLookupByName(virConnectPtr conn, const char *name) { struct openvz_driver *driver = (struct openvz_driver *)conn->privateData; - struct openvz_vm *vm = openvzFindVMByName(driver, name); + virDomainObjPtr vm = virDomainFindByName(driver->domains, name); virDomainPtr dom; if (!vm) { @@ -226,74 +220,81 @@ static virDomainPtr openvzDomainLookupByName(virConnectPtr conn, return NULL; } - dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid); - if (!dom) { - openvzError(conn, VIR_ERR_NO_MEMORY, _("virDomainPtr")); + dom = virGetDomain(conn, vm->def->name, vm->def->uuid); + if (!dom) return NULL; - } - - dom->id = vm->vpsid; + + dom->id = vm->def->id; return dom; } static int openvzDomainGetInfo(virDomainPtr dom, - virDomainInfoPtr info) { + virDomainInfoPtr info) { struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData; - struct openvz_vm *vm = openvzFindVMByUUID(driver, dom->uuid); + virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid); if (!vm) { openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN, - _("no domain with matching uuid")); + _("no domain with matching uuid")); return -1; } - info->state = vm->status; - - if (!openvzIsActiveVM(vm)) { + info->state = vm->state; + + if (!virDomainIsActive(vm)) { info->cpuTime = 0; } else { if (openvzGetProcessInfo(&(info->cpuTime), dom->id) < 0) { openvzError(dom->conn, VIR_ERR_OPERATION_FAILED, - _("cannot read cputime for domain %d"), dom->id); + _("cannot read cputime for domain %d"), dom->id); return -1; } } - /* TODO These need to be calculated differently for OpenVZ */ - //info->cpuTime = - //info->maxMem = vm->def->maxmem; - //info->memory = vm->def->memory; - info->nrVirtCpu = vm->vmdef->vcpus; + info->maxMem = vm->def->maxmem; + info->memory = vm->def->memory; + info->nrVirtCpu = vm->def->vcpus; return 0; } -static int openvzDomainShutdown(virDomainPtr dom) { - struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData; - struct openvz_vm *vm = openvzFindVMByUUID(driver, dom->uuid); - const char *prog[] = {VZCTL, "--quiet", "stop", vm->vmdef->name, NULL}; +static char *openvzDomainDumpXML(virDomainPtr dom, int flags) { + struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData; + virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid); + if (!vm) { openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN, - _("no domain with matching id")); - return -1; + _("no domain with matching uuid")); + return NULL; } + + return virDomainDefFormat(dom->conn, vm->def, flags); +} - if (vm->status != VIR_DOMAIN_RUNNING) { - openvzError(dom->conn, VIR_ERR_OPERATION_DENIED, - _("domain is not in running state")); + + +static int openvzDomainShutdown(virDomainPtr dom) { + struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData; + virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid); + const char *prog[] = {VZCTL, "--quiet", "stop", vm->def->name, NULL}; + + if (!vm) { + openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN, + _("no domain with matching uuid")); return -1; } - - if (virRun(dom->conn, prog, NULL) < 0) { + + if (vm->state != VIR_DOMAIN_RUNNING) { openvzError(dom->conn, VIR_ERR_INTERNAL_ERROR, - _("Could not exec %s"), VZCTL); + _("domain is not in running state")); return -1; } - - vm->vpsid = -1; - vm->status = VIR_DOMAIN_SHUTOFF; - ovz_driver.num_inactive ++; - ovz_driver.num_active --; + + if (virRun(dom->conn, prog, NULL) < 0) + return -1; + + vm->def->id = -1; + vm->state = VIR_DOMAIN_SHUTOFF; return 0; } @@ -301,26 +302,23 @@ static int openvzDomainShutdown(virDomainPtr dom) { static int openvzDomainReboot(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED) { struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData; - struct openvz_vm *vm = openvzFindVMByUUID(driver, dom->uuid); - const char *prog[] = {VZCTL, "--quiet", "restart", vm->vmdef->name, NULL}; + virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid); + const char *prog[] = {VZCTL, "--quiet", "restart", vm->def->name, NULL}; if (!vm) { openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN, - _("no domain with matching id")); + _("no domain with matching uuid")); return -1; } - if (vm->status != VIR_DOMAIN_RUNNING) { - openvzError(dom->conn, VIR_ERR_OPERATION_DENIED, - _("domain is not in running state")); + if (vm->state != VIR_DOMAIN_RUNNING) { + openvzError(dom->conn, VIR_ERR_INTERNAL_ERROR, + _("domain is not in running state")); return -1; } - if (virRun(dom->conn, prog, NULL) < 0) { - openvzError(dom->conn, VIR_ERR_INTERNAL_ERROR, - _("Could not exec %s"), VZCTL); + if (virRun(dom->conn, prog, NULL) < 0) return -1; - } return 0; } @@ -421,24 +419,31 @@ static virDomainPtr openvzDomainDefineXML(virConnectPtr conn, const char *xml) { struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; - struct openvz_vm_def *vmdef = NULL; - struct openvz_vm *vm = NULL; + virDomainDefPtr vmdef = NULL; + virDomainObjPtr vm = NULL; virDomainPtr dom = NULL; const char *prog[OPENVZ_MAX_ARG]; prog[0] = NULL; - if ((vmdef = openvzParseVMDef(conn, xml, NULL)) == NULL) + if ((vmdef = virDomainDefParseString(conn, driver->caps, xml)) == NULL) return NULL; - vm = openvzFindVMByName(driver, vmdef->name); + if (vmdef->os.init == NULL && + !(vmdef->os.init = strdup("/sbin/init"))) { + virDomainDefFree(vmdef); + return NULL; + } + + vm = virDomainFindByName(driver->domains, vmdef->name); if (vm) { + virDomainDefFree(vmdef); openvzLog(OPENVZ_ERR, _("Already an OPENVZ VM active with the id '%s'"), vmdef->name); return NULL; } - if (!(vm = openvzAssignVMDef(conn, driver, vmdef))) { - openvzFreeVMDef(vmdef); - openvzLog(OPENVZ_ERR, "%s", _("Error creating OPENVZ VM")); + if (!(vm = virDomainAssignDef(conn, &driver->domains, vmdef))) { + virDomainDefFree(vmdef); + return NULL; } if (openvzDomainDefineCmd(conn, prog, OPENVZ_MAX_ARG, vmdef) < 0) { @@ -461,11 +466,11 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml) goto exit; } - dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid); + dom = virGetDomain(conn, vm->def->name, vm->def->uuid); if (dom) - dom->id = vm->vpsid; + dom->id = -1; - if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->net) < 0) { + if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets) < 0) { openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("Could not configure network")); goto exit; @@ -488,27 +493,33 @@ static virDomainPtr openvzDomainCreateLinux(virConnectPtr conn, const char *xml, unsigned int flags ATTRIBUTE_UNUSED) { - struct openvz_vm_def *vmdef = NULL; - struct openvz_vm *vm = NULL; + virDomainDefPtr vmdef = NULL; + virDomainObjPtr vm = NULL; virDomainPtr dom = NULL; struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; const char *progstart[] = {VZCTL, "--quiet", "start", NULL, NULL}; const char *progcreate[OPENVZ_MAX_ARG]; progcreate[0] = NULL; - if (!(vmdef = openvzParseVMDef(conn, xml, NULL))) + if ((vmdef = virDomainDefParseString(conn, driver->caps, xml)) == NULL) + return NULL; + + if (vmdef->os.init == NULL && + !(vmdef->os.init = strdup("/sbin/init"))) { + virDomainDefFree(vmdef); return NULL; + } - vm = openvzFindVMByName(driver, vmdef->name); + vm = virDomainFindByName(driver->domains, vmdef->name); if (vm) { - openvzFreeVMDef(vmdef); + virDomainDefFree(vmdef); openvzLog(OPENVZ_ERR, _("Already an OPENVZ VM defined with the id '%d'"), strtoI(vmdef->name)); return NULL; } - if (!(vm = openvzAssignVMDef(conn, driver, vmdef))) { - openvzLog(OPENVZ_ERR, "%s", _("Error creating OPENVZ VM")); + if (!(vm = virDomainAssignDef(conn, &driver->domains, vmdef))) { + virDomainDefFree(vmdef); return NULL; } @@ -530,7 +541,7 @@ openvzDomainCreateLinux(virConnectPtr conn, const char *xml, goto exit; } - if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->net) < 0) { + if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets) < 0) { openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("Could not configure network")); goto exit; @@ -544,20 +555,19 @@ openvzDomainCreateLinux(virConnectPtr conn, const char *xml, goto exit; } - vm->vpsid = strtoI(vmdef->name); - vm->status = VIR_DOMAIN_RUNNING; - ovz_driver.num_inactive--; - ovz_driver.num_active++; - - dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid); + vm->pid = strtoI(vmdef->name); + vm->def->id = vm->pid; + vm->state = VIR_DOMAIN_RUNNING; + + dom = virGetDomain(conn, vm->def->name, vm->def->uuid); if (dom) - dom->id = vm->vpsid; + dom->id = vm->def->id; if (vmdef->vcpus > 0) { if (openvzDomainSetVcpus(dom, vmdef->vcpus) < 0) { openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("Could not set number of virtual cpu")); - goto exit; + _("Could not set number of virtual cpu")); + goto exit; } } @@ -570,8 +580,8 @@ static int openvzDomainCreate(virDomainPtr dom) { struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData; - struct openvz_vm *vm = openvzFindVMByName(driver, dom->name); - const char *prog[] = {VZCTL, "--quiet", "start", vm->vmdef->name, NULL }; + virDomainObjPtr vm = virDomainFindByName(driver->domains, dom->name); + const char *prog[] = {VZCTL, "--quiet", "start", vm->def->name, NULL }; if (!vm) { openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN, @@ -579,7 +589,7 @@ openvzDomainCreate(virDomainPtr dom) return -1; } - if (vm->status != VIR_DOMAIN_SHUTOFF) { + if (vm->state != VIR_DOMAIN_SHUTOFF) { openvzError(dom->conn, VIR_ERR_OPERATION_DENIED, _("domain is not in shutoff state")); return -1; @@ -591,10 +601,9 @@ openvzDomainCreate(virDomainPtr dom) return -1; } - vm->vpsid = strtoI(vm->vmdef->name); - vm->status = VIR_DOMAIN_RUNNING; - ovz_driver.num_inactive --; - ovz_driver.num_active ++; + vm->pid = strtoI(vm->def->name); + vm->def->id = vm->pid; + vm->state = VIR_DOMAIN_RUNNING; return 0; } @@ -604,15 +613,15 @@ openvzDomainUndefine(virDomainPtr dom) { virConnectPtr conn= dom->conn; struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; - struct openvz_vm *vm = openvzFindVMByUUID(driver, dom->uuid); - const char *prog[] = { VZCTL, "--quiet", "destroy", vm->vmdef->name, NULL }; + virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid); + const char *prog[] = { VZCTL, "--quiet", "destroy", vm->def->name, NULL }; if (!vm) { openvzError(conn, VIR_ERR_INVALID_DOMAIN, _("no domain with matching uuid")); return -1; } - if (openvzIsActiveVM(vm)) { + if (virDomainIsActive(vm)) { openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("cannot delete active domain")); return -1; } @@ -623,7 +632,8 @@ openvzDomainUndefine(virDomainPtr dom) return -1; } - openvzRemoveInactiveVM(driver, vm); + virDomainRemoveInactive(&driver->domains, vm); + return 0; } @@ -632,8 +642,8 @@ openvzDomainSetAutostart(virDomainPtr dom, int autostart) { virConnectPtr conn= dom->conn; struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; - struct openvz_vm *vm = openvzFindVMByUUID(driver, dom->uuid); - const char *prog[] = { VZCTL, "--quiet", "set", vm->vmdef->name, + virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid); + const char *prog[] = { VZCTL, "--quiet", "set", vm->def->name, "--onboot", autostart ? "yes" : "no", "--save", NULL }; @@ -655,7 +665,7 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart) { virConnectPtr conn= dom->conn; struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; - struct openvz_vm *vm = openvzFindVMByUUID(driver, dom->uuid); + virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid); char value[1024]; if (!vm) { @@ -663,7 +673,7 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart) return -1; } - if (openvzReadConfigParam(strtoI(vm->vmdef->name), "ONBOOT", value, sizeof(value)) < 0) { + if (openvzReadConfigParam(strtoI(vm->def->name), "ONBOOT", value, sizeof(value)) < 0) { openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("Could not read container config")); return -1; } @@ -692,39 +702,39 @@ static int openvzDomainGetMaxVcpus(virDomainPtr dom) { static int openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) { virConnectPtr conn= dom->conn; struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; - struct openvz_vm *vm = openvzFindVMByUUID(driver, dom->uuid); + virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid); char str_vcpus[32]; - const char *prog[] = { VZCTL, "--quiet", "set", vm->vmdef->name, + const char *prog[] = { VZCTL, "--quiet", "set", vm->def->name, "--cpus", str_vcpus, "--save", NULL }; snprintf(str_vcpus, 31, "%d", nvcpus); str_vcpus[31] = '\0'; if (nvcpus <= 0) { openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("VCPUs should be >= 1")); + _("VCPUs should be >= 1")); return -1; } if (!vm) { openvzError(conn, VIR_ERR_INVALID_DOMAIN, - _("no domain with matching uuid")); + _("no domain with matching uuid")); return -1; } if (virRun(conn, prog, NULL) < 0) { openvzError(conn, VIR_ERR_INTERNAL_ERROR, - _("Could not exec %s"), VZCTL); + _("Could not exec %s"), VZCTL); return -1; } - vm->vmdef->vcpus = nvcpus; + vm->def->vcpus = nvcpus; return 0; } static const char *openvzProbe(void) { #ifdef __linux__ - if ((getuid() == 0) && (virFileExists("/proc/vz"))) + if ((geteuid() == 0) && (virFileExists("/proc/vz"))) return("openvz:///system"); #endif return(NULL); @@ -735,51 +745,48 @@ static virDrvOpenStatus openvzOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED) { - struct openvz_vm *vms; - + struct openvz_driver *driver; /*Just check if the user is root. Nothing really to open for OpenVZ */ - if (getuid()) { // OpenVZ tools can only be used by r00t - return VIR_DRV_OPEN_DECLINED; - } else { - if (uri == NULL || uri->scheme == NULL || uri->path == NULL) - return VIR_DRV_OPEN_DECLINED; - if (STRNEQ (uri->scheme, "openvz")) - return VIR_DRV_OPEN_DECLINED; - if (STRNEQ (uri->path, "/system")) - return VIR_DRV_OPEN_DECLINED; - } + if (geteuid()) { // OpenVZ tools can only be used by r00t + return VIR_DRV_OPEN_DECLINED; + } else { + if (uri == NULL || + uri->scheme == NULL || + uri->path == NULL || + STRNEQ (uri->scheme, "openvz") || + STRNEQ (uri->path, "/system")) + return VIR_DRV_OPEN_DECLINED; + } /* See if we are running an OpenVZ enabled kernel */ - if(access("/proc/vz/veinfo", F_OK) == -1 || - access("/proc/user_beancounters", F_OK) == -1) { - return VIR_DRV_OPEN_DECLINED; - } + if(access("/proc/vz/veinfo", F_OK) == -1 || + access("/proc/user_beancounters", F_OK) == -1) { + return VIR_DRV_OPEN_DECLINED; + } + + if (VIR_ALLOC(driver) < 0) { + openvzError(conn, VIR_ERR_NO_MEMORY, NULL); + return VIR_DRV_OPEN_ERROR; + } + + if (!(driver->caps = openvzCapsInit())) + goto cleanup; - conn->privateData = &ovz_driver; + if (openvzLoadDomains(driver) < 0) + goto cleanup; - openvzAssignUUIDs(); + conn->privateData = driver; - vms = openvzGetVPSInfo(conn); - ovz_driver.vms = vms; + return VIR_DRV_OPEN_SUCCESS; - return VIR_DRV_OPEN_SUCCESS; +cleanup: + openvzFreeDriver(driver); + return VIR_DRV_OPEN_ERROR; }; static int openvzClose(virConnectPtr conn) { - struct openvz_driver *driver = (struct openvz_driver *)conn->privateData; - struct openvz_vm *vm = driver->vms; - - while(vm) { - openvzFreeVMDef(vm->vmdef); - vm = vm->next; - } - vm = driver->vms; - while (vm) { - struct openvz_vm *prev = vm; - vm = vm->next; - free(prev); - } + openvzFreeDriver(driver); conn->privateData = NULL; return 0; @@ -794,6 +801,12 @@ static int openvzGetNodeInfo(virConnectPtr conn, return virNodeInfoPopulate(conn, nodeinfo); } +static char *openvzGetCapabilities(virConnectPtr conn) { + struct openvz_driver *driver = (struct openvz_driver *)conn->privateData; + + return virCapabilitiesFormatXML(driver->caps); +} + static int openvzListDomains(virConnectPtr conn, int *ids, int nids) { int got = 0; int veid, pid; @@ -829,14 +842,22 @@ static int openvzListDomains(virConnectPtr conn, int *ids, int nids) { } static int openvzNumDomains(virConnectPtr conn ATTRIBUTE_UNUSED) { - return ovz_driver.num_active; + struct openvz_driver *driver = conn->privateData; + int nactive = 0; + virDomainObjPtr vm = driver->domains; + while (vm) { + if (virDomainIsActive(vm)) + nactive++; + vm = vm->next; + } + return nactive; } static int openvzListDefinedDomains(virConnectPtr conn, - char **const names, int nnames) { + char **const names, int nnames) { int got = 0; int veid, pid, outfd = -1, errfd = -1, ret; - char vpsname[OPENVZ_NAME_MAX]; + char vpsname[32]; char buf[32]; char *endptr; const char *cmd[] = {VZLIST, "-ovpsid", "-H", "-S", NULL}; @@ -858,12 +879,19 @@ static int openvzListDefinedDomains(virConnectPtr conn, _("Could not parse VPS ID %s"), buf); continue; } - sprintf(vpsname, "%d", veid); - names[got] = strdup(vpsname); + snprintf(vpsname, sizeof(vpsname), "%d", veid); + if (!(names[got] = strdup(vpsname))) + goto no_memory; got ++; } waitpid(pid, NULL, 0); return got; + +no_memory: + openvzError(conn, VIR_ERR_NO_MEMORY, NULL); + for ( ; got >= 0 ; got--) + VIR_FREE(names[got]); + return -1; } static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid) { @@ -911,8 +939,16 @@ Version: 2.2 return 0; } -static int openvzNumDefinedDomains(virConnectPtr conn ATTRIBUTE_UNUSED) { - return ovz_driver.num_inactive; +static int openvzNumDefinedDomains(virConnectPtr conn) { + struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; + int ninactive = 0; + virDomainObjPtr vm = driver->domains; + while (vm) { + if (!virDomainIsActive(vm)) + ninactive++; + vm = vm->next; + } + return ninactive; } static virDriver openvzDriver = { @@ -929,7 +965,7 @@ static virDriver openvzDriver = { NULL, /* uri */ openvzGetMaxVCPUs, /* getMaxVcpus */ openvzGetNodeInfo, /* nodeGetInfo */ - NULL, /* getCapabilities */ + openvzGetCapabilities, /* getCapabilities */ openvzListDomains, /* listDomains */ openvzNumDomains, /* numOfDomains */ openvzDomainCreateLinux, /* domainCreateLinux */ @@ -953,7 +989,7 @@ static virDriver openvzDriver = { NULL, /* domainPinVcpu */ NULL, /* domainGetVcpus */ openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */ - NULL, /* domainDumpXML */ + openvzDomainDumpXML, /* domainDumpXML */ openvzListDefinedDomains, /* listDomains */ openvzNumDefinedDomains, /* numOfDomains */ openvzDomainCreate, /* domainCreate */ diff --git a/src/openvz_driver.h b/src/openvz_driver.h index 8b0a49fa5d..d6e77feb4e 100644 --- a/src/openvz_driver.h +++ b/src/openvz_driver.h @@ -31,24 +31,6 @@ #include "internal.h" -/* OpenVZ commands - Replace with wrapper scripts later? */ -#define VZLIST "vzlist" -#define VZCTL "vzctl" - -struct openvz_driver { - struct openvz_vm *vms; - int num_active; - int num_inactive; -}; - int openvzRegister(void); -#define openvzLog(level, msg...) { if(level == OPENVZ_WARN) \ - fprintf(stderr, "\nWARNING: ");\ - else \ - fprintf(stderr, "\nERROR: ");\ - fprintf(stderr, "\n\t");\ - fprintf(stderr, msg);\ - fprintf(stderr, "\n"); } - #endif -- GitLab