Convert openvz driver to generic domain XML APIs

This commit is contained in:
Daniel P. Berrange 2008-09-05 14:10:58 +00:00
parent 542039fab0
commit 1cc9f9b3d8
5 changed files with 366 additions and 736 deletions

View File

@ -1,3 +1,8 @@
Fri Sep 5 15:09:26 BST 2008 Daniel P. Berrange <berrange@redhat.com>
* 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 <berrange@redhat.com> Fri Sep 5 13:02:26 BST 2008 Daniel P. Berrange <berrange@redhat.com>
Fully support mingw builds Fully support mingw builds

View File

@ -40,39 +40,29 @@
#include <limits.h> #include <limits.h>
#include <errno.h> #include <errno.h>
#include <string.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 "openvz_conf.h"
#include "uuid.h" #include "uuid.h"
#include "buf.h" #include "buf.h"
#include "memory.h" #include "memory.h"
#include "util.h" #include "util.h"
#include "xml.h"
#include "domain_conf.h"
static char *openvzLocateConfDir(void); static char *openvzLocateConfDir(void);
static struct openvz_vm_def *openvzParseXML(virConnectPtr conn, xmlDocPtr xml);
static int openvzGetVPSUUID(int vpsid, char *uuidstr); static int openvzGetVPSUUID(int vpsid, char *uuidstr);
static int openvzSetUUID(int vpsid);
static int openvzLocateConfFile(int vpsid, char *conffile, int maxlen); static int openvzLocateConfFile(int vpsid, char *conffile, int maxlen);
static int openvzAssignUUIDs(void);
void void
openvzError (virConnectPtr conn, virErrorNumber code, const char *fmt, ...) openvzError (virConnectPtr conn, virErrorNumber code, const char *fmt, ...)
{ {
va_list args; va_list args;
char errorMessage[OPENVZ_MAX_ERROR_LEN]; char errorMessage[1024];
const char *errmsg; const char *errmsg;
if (fmt) { if (fmt) {
va_start(args, fmt); va_start(args, fmt);
vsnprintf(errorMessage, OPENVZ_MAX_ERROR_LEN-1, fmt, args); vsnprintf(errorMessage, sizeof(errorMessage)-1, fmt, args);
va_end(args); va_end(args);
} else { } else {
errorMessage[0] = '\0'; errorMessage[0] = '\0';
@ -84,46 +74,6 @@ openvzError (virConnectPtr conn, virErrorNumber code, const char *fmt, ...)
errmsg, errorMessage); 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 int
strtoI(const char *str) strtoI(const char *str)
@ -136,6 +86,43 @@ strtoI(const char *str)
return val; 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 /* function checks MAC address is empty
return 0 - empty return 0 - empty
1 - not 1 - not
@ -164,438 +151,117 @@ char *openvzMacToString(const unsigned char *mac)
return strdup(str); 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 */ /* Free all memory associated with a openvz_driver structure */
void void
openvzFreeDriver(struct openvz_driver *driver) openvzFreeDriver(struct openvz_driver *driver)
{ {
struct openvz_vm *next; virDomainObjPtr dom;
if (!driver) if (!driver)
return; return;
if (driver->vms)
for(next = driver->vms->next; driver->vms; driver->vms = next) dom = driver->domains;
openvzFreeVM(driver, driver->vms, 0); while (dom) {
VIR_FREE(driver); virDomainObjPtr tmp = dom->next;
} virDomainObjFree(dom);
dom = tmp;
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) { virCapabilitiesFree(driver->caps);
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) { int openvzLoadDomains(struct openvz_driver *driver) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("There should be only one filesystem tag"));
goto error;
}
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) {
FILE *fp; FILE *fp;
int veid, ret; int veid, ret;
char status[16]; char status[16];
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
struct openvz_vm *vm; virDomainObjPtr dom = NULL, prev = NULL;
struct openvz_vm **pnext; char temp[50];
struct openvz_driver *driver;
struct openvz_vm_def *vmdef;
char temp[124];
vm = NULL; if (openvzAssignUUIDs() < 0)
driver = conn->privateData; return -1;
driver->num_active = 0;
driver->num_inactive = 0;
if((fp = popen(VZLIST " -a -ovpsid,status -H 2>/dev/null", "r")) == NULL) { if ((fp = popen(VZLIST " -a -ovpsid,status -H 2>/dev/null", "r")) == NULL) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("popen failed")); openvzError(NULL, VIR_ERR_INTERNAL_ERROR, _("popen failed"));
return NULL; return -1;
} }
pnext = &vm;
while(!feof(fp)) { while(!feof(fp)) {
if (VIR_ALLOC(*pnext) < 0) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("calloc failed"));
goto error;
}
if(!vm)
vm = *pnext;
if (fscanf(fp, "%d %s\n", &veid, status) != 2) { if (fscanf(fp, "%d %s\n", &veid, status) != 2) {
if (feof(fp)) if (feof(fp))
break; break;
openvzError(conn, VIR_ERR_INTERNAL_ERROR, openvzError(NULL, VIR_ERR_INTERNAL_ERROR,
_("Failed to parse vzlist output")); _("Failed to parse vzlist output"));
goto error; goto cleanup;
} }
if(STRNEQ(status, "stopped")) {
(*pnext)->status = VIR_DOMAIN_RUNNING; if (VIR_ALLOC(dom) < 0 ||
driver->num_active ++; VIR_ALLOC(dom->def) < 0)
(*pnext)->vpsid = veid; 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;
} }
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;
}
snprintf(vmdef->name, OPENVZ_NAME_MAX, "%i", veid);
openvzGetVPSUUID(veid, uuidstr); openvzGetVPSUUID(veid, uuidstr);
ret = virUUIDParse(uuidstr, vmdef->uuid); ret = virUUIDParse(uuidstr, dom->def->uuid);
if(ret == -1) { if (ret == -1) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, openvzError(NULL, VIR_ERR_INTERNAL_ERROR,
_("UUID in config file malformed")); _("UUID in config file malformed"));
VIR_FREE(vmdef); goto cleanup;
goto error;
} }
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)); ret = openvzReadConfigParam(veid, "CPUS", temp, sizeof(temp));
if (ret < 0) { if (ret < 0) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, openvzError(NULL, VIR_ERR_INTERNAL_ERROR,
_("Cound not read config for container %d"), veid); _("Cound not read config for container %d"),
goto error; veid);
goto cleanup;
} else if (ret > 0) { } else if (ret > 0) {
vmdef->vcpus = strtoI(temp); dom->def->vcpus = strtoI(temp);
} else {
dom->def->vcpus = 1;
} }
/* XXX load rest of VM config data .... */
(*pnext)->vmdef = vmdef;
pnext = &(*pnext)->next; if (prev) {
prev->next = dom;
} else {
driver->domains = dom;
}
prev = dom;
} }
return vm;
error: fclose(fp);
while (vm != NULL) {
struct openvz_vm *next; return 0;
next = vm->next; no_memory:
VIR_FREE(vm->vmdef); openvzError(NULL, VIR_ERR_NO_MEMORY, NULL);
VIR_FREE(vm);
vm = next; cleanup:
} fclose(fp);
return NULL; virDomainObjFree(dom);
return -1;
} }
/* /*
@ -797,7 +463,7 @@ openvzSetUUID(int vpsid){
* *
*/ */
int openvzAssignUUIDs(void) static int openvzAssignUUIDs(void)
{ {
DIR *dp; DIR *dp;
struct dirent *dent; struct dirent *dent;

View File

@ -28,94 +28,35 @@
#ifndef OPENVZ_CONF_H #ifndef OPENVZ_CONF_H
#define OPENVZ_CONF_H #define OPENVZ_CONF_H
#include "openvz_driver.h" #include "internal.h"
#include "domain_conf.h" #include "domain_conf.h"
enum { OPENVZ_WARN, OPENVZ_ERR }; enum { OPENVZ_WARN, OPENVZ_ERR };
#define OPENVZ_NAME_MAX 8 #define openvzLog(level, msg...) { if(level == OPENVZ_WARN) \
#define OPENVZ_TMPL_MAX 256 fprintf(stderr, "\nWARNING: ");\
#define OPENVZ_UNAME_MAX 32 else \
#define OPENVZ_IP_MAX 16 fprintf(stderr, "\nERROR: ");\
#define OPENVZ_HOSTNAME_MAX 256 fprintf(stderr, "\n\t");\
#define OPENVZ_PROFILE_MAX 256 fprintf(stderr, msg);\
#define OPENVZ_MAX_ERROR_LEN 1024 fprintf(stderr, "\n"); }
#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{ /* OpenVZ commands - Replace with wrapper scripts later? */
VM_LEVEL = 0, #define VZLIST "vzlist"
USER_LEVEL = 1, #define VZCTL "vzctl"
struct openvz_driver {
virCapsPtr caps;
virDomainObjPtr domains;
}; };
/* 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;
};
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, ...) void openvzError (virConnectPtr conn, virErrorNumber code, const char *fmt, ...)
ATTRIBUTE_FORMAT(printf, 3, 4); ATTRIBUTE_FORMAT(printf, 3, 4);
int openvz_readline(int fd, char *ptr, int maxlen); int openvz_readline(int fd, char *ptr, int maxlen);
int openvzReadConfigParam(int vpsid ,const char * param, char *value, int maxlen); int openvzReadConfigParam(int vpsid ,const char * param, char *value, int maxlen);
struct openvz_vm *openvzFindVMByID(const struct openvz_driver *driver, int id); virCapsPtr openvzCapsInit(void);
struct openvz_vm *openvzFindVMByUUID(const struct openvz_driver *driver, int openvzLoadDomains(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);
void openvzFreeDriver(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 strtoI(const char *str);
int openvzCheckEmptyMac(const unsigned char *mac); int openvzCheckEmptyMac(const unsigned char *mac);
char *openvzMacToString(const unsigned char *mac); char *openvzMacToString(const unsigned char *mac);

View File

@ -60,33 +60,6 @@
#define CMDBUF_LEN 1488 #define CMDBUF_LEN 1488
#define CMDOP_LEN 288 #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 openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid);
static int openvzGetMaxVCPUs(virConnectPtr conn, const char *type); static int openvzGetMaxVCPUs(virConnectPtr conn, const char *type);
static int openvzDomainGetMaxVcpus(virDomainPtr dom); static int openvzDomainGetMaxVcpus(virDomainPtr dom);
@ -110,7 +83,7 @@ static void cmdExecFree(const char *cmdExec[])
static int openvzDomainDefineCmd(virConnectPtr conn, static int openvzDomainDefineCmd(virConnectPtr conn,
const char *args[], const char *args[],
int maxarg, int maxarg,
struct openvz_vm_def *vmdef) virDomainDefPtr vmdef)
{ {
int narg; int narg;
@ -143,15 +116,29 @@ static int openvzDomainDefineCmd(virConnectPtr conn,
ADD_ARG_LIT("--quiet"); ADD_ARG_LIT("--quiet");
ADD_ARG_LIT("create"); ADD_ARG_LIT("create");
ADD_ARG_LIT(vmdef->name); 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("--ostemplate");
ADD_ARG_LIT(vmdef->fs.tmpl); ADD_ARG_LIT(vmdef->fss->src);
} }
#if 0
if ((vmdef->profile && *(vmdef->profile))) { if ((vmdef->profile && *(vmdef->profile))) {
ADD_ARG_LIT("--config"); ADD_ARG_LIT("--config");
ADD_ARG_LIT(vmdef->profile); ADD_ARG_LIT(vmdef->profile);
} }
#endif
ADD_ARG(NULL); ADD_ARG(NULL);
return 0; return 0;
@ -165,39 +152,48 @@ static int openvzDomainDefineCmd(virConnectPtr conn,
static virDomainPtr openvzDomainLookupByID(virConnectPtr conn, static virDomainPtr openvzDomainLookupByID(virConnectPtr conn,
int id) { int id) {
struct openvz_driver *driver = (struct openvz_driver *)conn->privateData; struct openvz_driver *driver = (struct openvz_driver *)conn->privateData;
struct openvz_vm *vm; virDomainObjPtr vm;
virDomainPtr dom; virDomainPtr dom;
vm = openvzFindVMByID(driver, id); vm = virDomainFindByID(driver->domains, id);
if (!vm) { if (!vm) {
openvzError(conn, VIR_ERR_NO_DOMAIN, NULL); openvzError(conn, VIR_ERR_NO_DOMAIN, NULL);
return NULL; return NULL;
} }
dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid); dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (!dom) { if (!dom)
openvzError(conn, VIR_ERR_NO_MEMORY, _("virDomainPtr"));
return NULL; return NULL;
}
dom->id = vm->vpsid; dom->id = vm->def->id;
return dom; return dom;
} }
static char *openvzGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) static char *openvzGetOSType(virDomainPtr dom)
{ {
/* OpenVZ runs on Linux and runs only Linux */ struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData;
return strdup("linux"); 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, static virDomainPtr openvzDomainLookupByUUID(virConnectPtr conn,
const unsigned char *uuid) { const unsigned char *uuid) {
struct openvz_driver *driver = (struct openvz_driver *)conn->privateData; struct openvz_driver *driver = (struct openvz_driver *)conn->privateData;
struct openvz_vm *vm = openvzFindVMByUUID(driver, uuid); virDomainObjPtr vm = virDomainFindByUUID(driver->domains, uuid);
virDomainPtr dom; virDomainPtr dom;
if (!vm) { if (!vm) {
@ -205,20 +201,18 @@ static virDomainPtr openvzDomainLookupByUUID(virConnectPtr conn,
return NULL; return NULL;
} }
dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid); dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (!dom) { if (!dom)
openvzError(conn, VIR_ERR_NO_MEMORY, _("virDomainPtr"));
return NULL; return NULL;
}
dom->id = vm->vpsid; dom->id = vm->def->id;
return dom; return dom;
} }
static virDomainPtr openvzDomainLookupByName(virConnectPtr conn, static virDomainPtr openvzDomainLookupByName(virConnectPtr conn,
const char *name) { const char *name) {
struct openvz_driver *driver = (struct openvz_driver *)conn->privateData; struct openvz_driver *driver = (struct openvz_driver *)conn->privateData;
struct openvz_vm *vm = openvzFindVMByName(driver, name); virDomainObjPtr vm = virDomainFindByName(driver->domains, name);
virDomainPtr dom; virDomainPtr dom;
if (!vm) { if (!vm) {
@ -226,74 +220,81 @@ static virDomainPtr openvzDomainLookupByName(virConnectPtr conn,
return NULL; return NULL;
} }
dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid); dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (!dom) { if (!dom)
openvzError(conn, VIR_ERR_NO_MEMORY, _("virDomainPtr"));
return NULL; return NULL;
}
dom->id = vm->def->id;
dom->id = vm->vpsid;
return dom; return dom;
} }
static int openvzDomainGetInfo(virDomainPtr dom, static int openvzDomainGetInfo(virDomainPtr dom,
virDomainInfoPtr info) { virDomainInfoPtr info) {
struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData; 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) { if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN, openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching uuid")); _("no domain with matching uuid"));
return -1; return -1;
} }
info->state = vm->status; info->state = vm->state;
if (!openvzIsActiveVM(vm)) { if (!virDomainIsActive(vm)) {
info->cpuTime = 0; info->cpuTime = 0;
} else { } else {
if (openvzGetProcessInfo(&(info->cpuTime), dom->id) < 0) { if (openvzGetProcessInfo(&(info->cpuTime), dom->id) < 0) {
openvzError(dom->conn, VIR_ERR_OPERATION_FAILED, 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; return -1;
} }
} }
/* TODO These need to be calculated differently for OpenVZ */ info->maxMem = vm->def->maxmem;
//info->cpuTime = info->memory = vm->def->memory;
//info->maxMem = vm->def->maxmem; info->nrVirtCpu = vm->def->vcpus;
//info->memory = vm->def->memory;
info->nrVirtCpu = vm->vmdef->vcpus;
return 0; return 0;
} }
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 uuid"));
return NULL;
}
return virDomainDefFormat(dom->conn, vm->def, flags);
}
static int openvzDomainShutdown(virDomainPtr dom) { static int openvzDomainShutdown(virDomainPtr dom) {
struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData; 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);
const char *prog[] = {VZCTL, "--quiet", "stop", vm->vmdef->name, NULL}; const char *prog[] = {VZCTL, "--quiet", "stop", vm->def->name, NULL};
if (!vm) { if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN, openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id")); _("no domain with matching uuid"));
return -1; return -1;
} }
if (vm->status != VIR_DOMAIN_RUNNING) { if (vm->state != VIR_DOMAIN_RUNNING) {
openvzError(dom->conn, VIR_ERR_OPERATION_DENIED,
_("domain is not in running state"));
return -1;
}
if (virRun(dom->conn, prog, NULL) < 0) {
openvzError(dom->conn, VIR_ERR_INTERNAL_ERROR, openvzError(dom->conn, VIR_ERR_INTERNAL_ERROR,
_("Could not exec %s"), VZCTL); _("domain is not in running state"));
return -1; return -1;
} }
vm->vpsid = -1; if (virRun(dom->conn, prog, NULL) < 0)
vm->status = VIR_DOMAIN_SHUTOFF; return -1;
ovz_driver.num_inactive ++;
ovz_driver.num_active --; vm->def->id = -1;
vm->state = VIR_DOMAIN_SHUTOFF;
return 0; return 0;
} }
@ -301,27 +302,24 @@ static int openvzDomainShutdown(virDomainPtr dom) {
static int openvzDomainReboot(virDomainPtr dom, static int openvzDomainReboot(virDomainPtr dom,
unsigned int flags ATTRIBUTE_UNUSED) { unsigned int flags ATTRIBUTE_UNUSED) {
struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData; 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);
const char *prog[] = {VZCTL, "--quiet", "restart", vm->vmdef->name, NULL}; const char *prog[] = {VZCTL, "--quiet", "restart", vm->def->name, NULL};
if (!vm) { if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN, openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching id")); _("no domain with matching uuid"));
return -1; return -1;
} }
if (vm->status != VIR_DOMAIN_RUNNING) { if (vm->state != VIR_DOMAIN_RUNNING) {
openvzError(dom->conn, VIR_ERR_OPERATION_DENIED,
_("domain is not in running state"));
return -1;
}
if (virRun(dom->conn, prog, NULL) < 0) {
openvzError(dom->conn, VIR_ERR_INTERNAL_ERROR, openvzError(dom->conn, VIR_ERR_INTERNAL_ERROR,
_("Could not exec %s"), VZCTL); _("domain is not in running state"));
return -1; return -1;
} }
if (virRun(dom->conn, prog, NULL) < 0)
return -1;
return 0; return 0;
} }
@ -421,24 +419,31 @@ static virDomainPtr
openvzDomainDefineXML(virConnectPtr conn, const char *xml) openvzDomainDefineXML(virConnectPtr conn, const char *xml)
{ {
struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; struct openvz_driver *driver = (struct openvz_driver *) conn->privateData;
struct openvz_vm_def *vmdef = NULL; virDomainDefPtr vmdef = NULL;
struct openvz_vm *vm = NULL; virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
const char *prog[OPENVZ_MAX_ARG]; const char *prog[OPENVZ_MAX_ARG];
prog[0] = NULL; prog[0] = NULL;
if ((vmdef = openvzParseVMDef(conn, xml, NULL)) == NULL) if ((vmdef = virDomainDefParseString(conn, driver->caps, xml)) == NULL)
return 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) { if (vm) {
virDomainDefFree(vmdef);
openvzLog(OPENVZ_ERR, _("Already an OPENVZ VM active with the id '%s'"), openvzLog(OPENVZ_ERR, _("Already an OPENVZ VM active with the id '%s'"),
vmdef->name); vmdef->name);
return NULL; return NULL;
} }
if (!(vm = openvzAssignVMDef(conn, driver, vmdef))) { if (!(vm = virDomainAssignDef(conn, &driver->domains, vmdef))) {
openvzFreeVMDef(vmdef); virDomainDefFree(vmdef);
openvzLog(OPENVZ_ERR, "%s", _("Error creating OPENVZ VM")); return NULL;
} }
if (openvzDomainDefineCmd(conn, prog, OPENVZ_MAX_ARG, vmdef) < 0) { if (openvzDomainDefineCmd(conn, prog, OPENVZ_MAX_ARG, vmdef) < 0) {
@ -461,11 +466,11 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
goto exit; goto exit;
} }
dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid); dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) 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, openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("Could not configure network")); _("Could not configure network"));
goto exit; goto exit;
@ -488,27 +493,33 @@ static virDomainPtr
openvzDomainCreateLinux(virConnectPtr conn, const char *xml, openvzDomainCreateLinux(virConnectPtr conn, const char *xml,
unsigned int flags ATTRIBUTE_UNUSED) unsigned int flags ATTRIBUTE_UNUSED)
{ {
struct openvz_vm_def *vmdef = NULL; virDomainDefPtr vmdef = NULL;
struct openvz_vm *vm = NULL; virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; struct openvz_driver *driver = (struct openvz_driver *) conn->privateData;
const char *progstart[] = {VZCTL, "--quiet", "start", NULL, NULL}; const char *progstart[] = {VZCTL, "--quiet", "start", NULL, NULL};
const char *progcreate[OPENVZ_MAX_ARG]; const char *progcreate[OPENVZ_MAX_ARG];
progcreate[0] = NULL; progcreate[0] = NULL;
if (!(vmdef = openvzParseVMDef(conn, xml, NULL))) if ((vmdef = virDomainDefParseString(conn, driver->caps, xml)) == NULL)
return 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) { if (vm) {
openvzFreeVMDef(vmdef); virDomainDefFree(vmdef);
openvzLog(OPENVZ_ERR, openvzLog(OPENVZ_ERR,
_("Already an OPENVZ VM defined with the id '%d'"), _("Already an OPENVZ VM defined with the id '%d'"),
strtoI(vmdef->name)); strtoI(vmdef->name));
return NULL; return NULL;
} }
if (!(vm = openvzAssignVMDef(conn, driver, vmdef))) { if (!(vm = virDomainAssignDef(conn, &driver->domains, vmdef))) {
openvzLog(OPENVZ_ERR, "%s", _("Error creating OPENVZ VM")); virDomainDefFree(vmdef);
return NULL; return NULL;
} }
@ -530,7 +541,7 @@ openvzDomainCreateLinux(virConnectPtr conn, const char *xml,
goto exit; goto exit;
} }
if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->net) < 0) { if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets) < 0) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("Could not configure network")); _("Could not configure network"));
goto exit; goto exit;
@ -544,20 +555,19 @@ openvzDomainCreateLinux(virConnectPtr conn, const char *xml,
goto exit; goto exit;
} }
vm->vpsid = strtoI(vmdef->name); vm->pid = strtoI(vmdef->name);
vm->status = VIR_DOMAIN_RUNNING; vm->def->id = vm->pid;
ovz_driver.num_inactive--; vm->state = VIR_DOMAIN_RUNNING;
ovz_driver.num_active++;
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid);
if (dom) if (dom)
dom->id = vm->vpsid; dom->id = vm->def->id;
if (vmdef->vcpus > 0) { if (vmdef->vcpus > 0) {
if (openvzDomainSetVcpus(dom, vmdef->vcpus) < 0) { if (openvzDomainSetVcpus(dom, vmdef->vcpus) < 0) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("Could not set number of virtual cpu")); _("Could not set number of virtual cpu"));
goto exit; goto exit;
} }
} }
@ -570,8 +580,8 @@ static int
openvzDomainCreate(virDomainPtr dom) openvzDomainCreate(virDomainPtr dom)
{ {
struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData; struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData;
struct openvz_vm *vm = openvzFindVMByName(driver, dom->name); virDomainObjPtr vm = virDomainFindByName(driver->domains, dom->name);
const char *prog[] = {VZCTL, "--quiet", "start", vm->vmdef->name, NULL }; const char *prog[] = {VZCTL, "--quiet", "start", vm->def->name, NULL };
if (!vm) { if (!vm) {
openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN, openvzError(dom->conn, VIR_ERR_INVALID_DOMAIN,
@ -579,7 +589,7 @@ openvzDomainCreate(virDomainPtr dom)
return -1; return -1;
} }
if (vm->status != VIR_DOMAIN_SHUTOFF) { if (vm->state != VIR_DOMAIN_SHUTOFF) {
openvzError(dom->conn, VIR_ERR_OPERATION_DENIED, openvzError(dom->conn, VIR_ERR_OPERATION_DENIED,
_("domain is not in shutoff state")); _("domain is not in shutoff state"));
return -1; return -1;
@ -591,10 +601,9 @@ openvzDomainCreate(virDomainPtr dom)
return -1; return -1;
} }
vm->vpsid = strtoI(vm->vmdef->name); vm->pid = strtoI(vm->def->name);
vm->status = VIR_DOMAIN_RUNNING; vm->def->id = vm->pid;
ovz_driver.num_inactive --; vm->state = VIR_DOMAIN_RUNNING;
ovz_driver.num_active ++;
return 0; return 0;
} }
@ -604,15 +613,15 @@ openvzDomainUndefine(virDomainPtr dom)
{ {
virConnectPtr conn= dom->conn; virConnectPtr conn= dom->conn;
struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; struct openvz_driver *driver = (struct openvz_driver *) conn->privateData;
struct openvz_vm *vm = openvzFindVMByUUID(driver, dom->uuid); virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
const char *prog[] = { VZCTL, "--quiet", "destroy", vm->vmdef->name, NULL }; const char *prog[] = { VZCTL, "--quiet", "destroy", vm->def->name, NULL };
if (!vm) { if (!vm) {
openvzError(conn, VIR_ERR_INVALID_DOMAIN, _("no domain with matching uuid")); openvzError(conn, VIR_ERR_INVALID_DOMAIN, _("no domain with matching uuid"));
return -1; return -1;
} }
if (openvzIsActiveVM(vm)) { if (virDomainIsActive(vm)) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("cannot delete active domain")); openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("cannot delete active domain"));
return -1; return -1;
} }
@ -623,7 +632,8 @@ openvzDomainUndefine(virDomainPtr dom)
return -1; return -1;
} }
openvzRemoveInactiveVM(driver, vm); virDomainRemoveInactive(&driver->domains, vm);
return 0; return 0;
} }
@ -632,8 +642,8 @@ openvzDomainSetAutostart(virDomainPtr dom, int autostart)
{ {
virConnectPtr conn= dom->conn; virConnectPtr conn= dom->conn;
struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; struct openvz_driver *driver = (struct openvz_driver *) conn->privateData;
struct openvz_vm *vm = openvzFindVMByUUID(driver, dom->uuid); virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
const char *prog[] = { VZCTL, "--quiet", "set", vm->vmdef->name, const char *prog[] = { VZCTL, "--quiet", "set", vm->def->name,
"--onboot", autostart ? "yes" : "no", "--onboot", autostart ? "yes" : "no",
"--save", NULL }; "--save", NULL };
@ -655,7 +665,7 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart)
{ {
virConnectPtr conn= dom->conn; virConnectPtr conn= dom->conn;
struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; 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]; char value[1024];
if (!vm) { if (!vm) {
@ -663,7 +673,7 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart)
return -1; 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")); openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("Could not read container config"));
return -1; return -1;
} }
@ -692,39 +702,39 @@ static int openvzDomainGetMaxVcpus(virDomainPtr dom) {
static int openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) { static int openvzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) {
virConnectPtr conn= dom->conn; virConnectPtr conn= dom->conn;
struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; 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]; 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 }; "--cpus", str_vcpus, "--save", NULL };
snprintf(str_vcpus, 31, "%d", nvcpus); snprintf(str_vcpus, 31, "%d", nvcpus);
str_vcpus[31] = '\0'; str_vcpus[31] = '\0';
if (nvcpus <= 0) { if (nvcpus <= 0) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("VCPUs should be >= 1")); _("VCPUs should be >= 1"));
return -1; return -1;
} }
if (!vm) { if (!vm) {
openvzError(conn, VIR_ERR_INVALID_DOMAIN, openvzError(conn, VIR_ERR_INVALID_DOMAIN,
_("no domain with matching uuid")); _("no domain with matching uuid"));
return -1; return -1;
} }
if (virRun(conn, prog, NULL) < 0) { if (virRun(conn, prog, NULL) < 0) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("Could not exec %s"), VZCTL); _("Could not exec %s"), VZCTL);
return -1; return -1;
} }
vm->vmdef->vcpus = nvcpus; vm->def->vcpus = nvcpus;
return 0; return 0;
} }
static const char *openvzProbe(void) static const char *openvzProbe(void)
{ {
#ifdef __linux__ #ifdef __linux__
if ((getuid() == 0) && (virFileExists("/proc/vz"))) if ((geteuid() == 0) && (virFileExists("/proc/vz")))
return("openvz:///system"); return("openvz:///system");
#endif #endif
return(NULL); return(NULL);
@ -735,51 +745,48 @@ static virDrvOpenStatus openvzOpen(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED, virConnectAuthPtr auth ATTRIBUTE_UNUSED,
int flags 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 */ /*Just check if the user is root. Nothing really to open for OpenVZ */
if (getuid()) { // OpenVZ tools can only be used by r00t if (geteuid()) { // OpenVZ tools can only be used by r00t
return VIR_DRV_OPEN_DECLINED; return VIR_DRV_OPEN_DECLINED;
} else { } else {
if (uri == NULL || uri->scheme == NULL || uri->path == NULL) if (uri == NULL ||
return VIR_DRV_OPEN_DECLINED; uri->scheme == NULL ||
if (STRNEQ (uri->scheme, "openvz")) uri->path == NULL ||
return VIR_DRV_OPEN_DECLINED; STRNEQ (uri->scheme, "openvz") ||
if (STRNEQ (uri->path, "/system")) STRNEQ (uri->path, "/system"))
return VIR_DRV_OPEN_DECLINED; return VIR_DRV_OPEN_DECLINED;
} }
/* See if we are running an OpenVZ enabled kernel */ /* See if we are running an OpenVZ enabled kernel */
if(access("/proc/vz/veinfo", F_OK) == -1 || if(access("/proc/vz/veinfo", F_OK) == -1 ||
access("/proc/user_beancounters", F_OK) == -1) { access("/proc/user_beancounters", F_OK) == -1) {
return VIR_DRV_OPEN_DECLINED; return VIR_DRV_OPEN_DECLINED;
} }
conn->privateData = &ovz_driver; if (VIR_ALLOC(driver) < 0) {
openvzError(conn, VIR_ERR_NO_MEMORY, NULL);
return VIR_DRV_OPEN_ERROR;
}
openvzAssignUUIDs(); if (!(driver->caps = openvzCapsInit()))
goto cleanup;
vms = openvzGetVPSInfo(conn); if (openvzLoadDomains(driver) < 0)
ovz_driver.vms = vms; goto cleanup;
return VIR_DRV_OPEN_SUCCESS; conn->privateData = driver;
return VIR_DRV_OPEN_SUCCESS;
cleanup:
openvzFreeDriver(driver);
return VIR_DRV_OPEN_ERROR;
}; };
static int openvzClose(virConnectPtr conn) { static int openvzClose(virConnectPtr conn) {
struct openvz_driver *driver = (struct openvz_driver *)conn->privateData; 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; conn->privateData = NULL;
return 0; return 0;
@ -794,6 +801,12 @@ static int openvzGetNodeInfo(virConnectPtr conn,
return virNodeInfoPopulate(conn, nodeinfo); 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) { static int openvzListDomains(virConnectPtr conn, int *ids, int nids) {
int got = 0; int got = 0;
int veid, pid; int veid, pid;
@ -829,14 +842,22 @@ static int openvzListDomains(virConnectPtr conn, int *ids, int nids) {
} }
static int openvzNumDomains(virConnectPtr conn ATTRIBUTE_UNUSED) { 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, static int openvzListDefinedDomains(virConnectPtr conn,
char **const names, int nnames) { char **const names, int nnames) {
int got = 0; int got = 0;
int veid, pid, outfd = -1, errfd = -1, ret; int veid, pid, outfd = -1, errfd = -1, ret;
char vpsname[OPENVZ_NAME_MAX]; char vpsname[32];
char buf[32]; char buf[32];
char *endptr; char *endptr;
const char *cmd[] = {VZLIST, "-ovpsid", "-H", "-S", NULL}; const char *cmd[] = {VZLIST, "-ovpsid", "-H", "-S", NULL};
@ -858,12 +879,19 @@ static int openvzListDefinedDomains(virConnectPtr conn,
_("Could not parse VPS ID %s"), buf); _("Could not parse VPS ID %s"), buf);
continue; continue;
} }
sprintf(vpsname, "%d", veid); snprintf(vpsname, sizeof(vpsname), "%d", veid);
names[got] = strdup(vpsname); if (!(names[got] = strdup(vpsname)))
goto no_memory;
got ++; got ++;
} }
waitpid(pid, NULL, 0); waitpid(pid, NULL, 0);
return got; 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) { static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid) {
@ -911,8 +939,16 @@ Version: 2.2
return 0; return 0;
} }
static int openvzNumDefinedDomains(virConnectPtr conn ATTRIBUTE_UNUSED) { static int openvzNumDefinedDomains(virConnectPtr conn) {
return ovz_driver.num_inactive; 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 = { static virDriver openvzDriver = {
@ -929,7 +965,7 @@ static virDriver openvzDriver = {
NULL, /* uri */ NULL, /* uri */
openvzGetMaxVCPUs, /* getMaxVcpus */ openvzGetMaxVCPUs, /* getMaxVcpus */
openvzGetNodeInfo, /* nodeGetInfo */ openvzGetNodeInfo, /* nodeGetInfo */
NULL, /* getCapabilities */ openvzGetCapabilities, /* getCapabilities */
openvzListDomains, /* listDomains */ openvzListDomains, /* listDomains */
openvzNumDomains, /* numOfDomains */ openvzNumDomains, /* numOfDomains */
openvzDomainCreateLinux, /* domainCreateLinux */ openvzDomainCreateLinux, /* domainCreateLinux */
@ -953,7 +989,7 @@ static virDriver openvzDriver = {
NULL, /* domainPinVcpu */ NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */ NULL, /* domainGetVcpus */
openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */ openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */
NULL, /* domainDumpXML */ openvzDomainDumpXML, /* domainDumpXML */
openvzListDefinedDomains, /* listDomains */ openvzListDefinedDomains, /* listDomains */
openvzNumDefinedDomains, /* numOfDomains */ openvzNumDefinedDomains, /* numOfDomains */
openvzDomainCreate, /* domainCreate */ openvzDomainCreate, /* domainCreate */

View File

@ -31,24 +31,6 @@
#include "internal.h" #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); 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 #endif