#include <limits.h>
#include <errno.h>
#include <string.h>
+#include <sys/utsname.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/xpath.h>
-#include <libxml/uri.h>
-
-#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';
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)
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
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:
-<filesystem type="template">
- <source name="fedora-core-5-i386"/>
- <quota type="size" max="10000"/>
- <quota type="inodes" max="100"/>
-</filesystem>
-*/
-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;
}
/*
*
*/
-int openvzAssignUUIDs(void)
+static int openvzAssignUUIDs(void)
{
DIR *dp;
struct dirent *dent;
#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);
static int openvzDomainDefineCmd(virConnectPtr conn,
const char *args[],
int maxarg,
- struct openvz_vm_def *vmdef)
+ virDomainDefPtr vmdef)
{
int narg;
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;
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) {
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) {
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;
}
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;
}
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) {
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;
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;
}
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;
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;
}
}
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,
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;
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;
}
{
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;
}
return -1;
}
- openvzRemoveInactiveVM(driver, vm);
+ virDomainRemoveInactive(&driver->domains, vm);
+
return 0;
}
{
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 };
{
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) {
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;
}
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);
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;
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;
}
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};
_("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) {
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 = {
NULL, /* uri */
openvzGetMaxVCPUs, /* getMaxVcpus */
openvzGetNodeInfo, /* nodeGetInfo */
- NULL, /* getCapabilities */
+ openvzGetCapabilities, /* getCapabilities */
openvzListDomains, /* listDomains */
openvzNumDomains, /* numOfDomains */
openvzDomainCreateLinux, /* domainCreateLinux */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */
- NULL, /* domainDumpXML */
+ openvzDomainDumpXML, /* domainDumpXML */
openvzListDefinedDomains, /* listDomains */
openvzNumDefinedDomains, /* numOfDomains */
openvzDomainCreate, /* domainCreate */