[libvirt] PATCH: Switch openvz driver to domain APIs
by Daniel P. Berrange
This patch is the minimum effort port of the OpenVZ driver over to the
new generic domain XML routines. It basically removes all the existing
config format stuff from openvz_conf, defines a set of openvz capabilities
and implements the DumpXML method too. This is enough to get all the core
libvirt functions working. The biggest flaw I see currently is that the
openvz driver doesn't load the existing device config for networks or
filesystems of existing VMs, so you can't see that info in the XML dump
Daniel
diff -r e270be59a80f src/openvz_conf.c
--- a/src/openvz_conf.c Wed Aug 27 17:03:25 2008 +0100
+++ b/src/openvz_conf.c Wed Aug 27 17:26:08 2008 +0100
@@ -40,39 +40,29 @@
#include <limits.h>
#include <errno.h>
#include <string.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 <sys/utsname.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, virErro
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)
@@ -135,6 +85,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
@@ -164,438 +151,105 @@ char *openvzMacToString(const unsigned c
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;
- }
-
- 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) {
+
+ dom = driver->domains;
+ while (dom) {
+ virDomainObjPtr tmp = dom->next;
+ virDomainObjFree(dom);
+ dom = tmp;
+ }
+
+ virCapabilitiesFree(driver->caps);
+}
+
+
+
+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;
+ virDomainObjPtr dom = NULL, prev = NULL;
+
+ 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 (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 (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;
- }
- 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);
+
+ openvzError(NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to parse vzlist output"));
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC(dom) < 0 ||
+ VIR_ALLOC(dom->def) < 0)
+ goto no_memory;
+
+ if (STRNEQ(status, "stopped"))
+ dom->state = VIR_DOMAIN_RUNNING;
+ else
+ dom->state = VIR_DOMAIN_SHUTOFF;
+
+ 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;
+ }
+
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;
- }
-
- /*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;
- } else if (ret > 0) {
- vmdef->vcpus = strtoI(temp);
- }
-
-
- (*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;
- }
- return NULL;
+ ret = virUUIDParse(uuidstr, dom->def->uuid);
+
+ if (ret == -1) {
+ openvzError(NULL, VIR_ERR_INTERNAL_ERROR,
+ _("UUID in config file malformed"));
+ goto cleanup;
+ }
+
+ dom->def->vcpus = 1;
+ if (!(dom->def->os.type = strdup("exe")))
+ goto no_memory;
+ if (!(dom->def->os.init = strdup("/sbin/init")))
+ goto no_memory;
+
+ /* XXX load rest of VM config data .... */
+
+ if (prev) {
+ prev->next = dom;
+ } else {
+ driver->domains = dom;
+ }
+ prev = dom;
+ }
+
+ fclose(fp);
+
+ return 0;
+
+ no_memory:
+ openvzError(NULL, VIR_ERR_NO_MEMORY, NULL);
+
+ cleanup:
+ fclose(fp);
+ virDomainObjFree(dom);
+ return -1;
}
/*
@@ -797,7 +451,7 @@ openvzSetUUID(int vpsid){
*
*/
-int openvzAssignUUIDs(void)
+static int openvzAssignUUIDs(void)
{
DIR *dp;
struct dirent *dent;
diff -r e270be59a80f src/openvz_conf.h
--- a/src/openvz_conf.h Wed Aug 27 17:03:25 2008 +0100
+++ b/src/openvz_conf.h Wed Aug 27 17:03:45 2008 +0100
@@ -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
+#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"); }
-enum openvz_quota{
- VM_LEVEL = 0,
- USER_LEVEL = 1,
+/* OpenVZ commands - Replace with wrapper scripts later? */
+#define VZLIST "vzlist"
+#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, ...)
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 -r e270be59a80f src/openvz_driver.c
--- a/src/openvz_driver.c Wed Aug 27 17:03:25 2008 +0100
+++ b/src/openvz_driver.c Wed Aug 27 17:29:40 2008 +0100
@@ -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 int openvzDomainDefineCmd(virConn
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(virConn
ADD_ARG_LIT("--quiet");
ADD_ARG_LIT("create");
ADD_ARG_LIT(vmdef->name);
-
- if ((vmdef->fs.tmpl && *(vmdef->fs.tmpl))) {
+
+ 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;
+ }
+
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,43 @@ static int openvzDomainDefineCmd(virConn
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"));
- return NULL;
- }
-
- dom->id = vm->vpsid;
+ dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
+ if (!dom)
+ return NULL;
+
+ dom->id = vm->def->id;
return dom;
}
-static char *openvzGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED)
-{
- /* OpenVZ runs on Linux and runs only Linux */
- return strdup("linux");
+static char *openvzGetOSType(virDomainPtr dom)
+{
+ struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData;
+ virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
+ char *ret = strdup(vm->def->os.type);
+
+ if (!ret)
+ 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 +196,18 @@ static virDomainPtr openvzDomainLookupBy
return NULL;
}
- dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid);
- if (!dom) {
- openvzError(conn, VIR_ERR_NO_MEMORY, _("virDomainPtr"));
- return NULL;
- }
-
- dom->id = vm->vpsid;
+ dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
+ if (!dom)
+ return NULL;
+
+ 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 +215,83 @@ static virDomainPtr openvzDomainLookupBy
return NULL;
}
- dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid);
- if (!dom) {
- openvzError(conn, VIR_ERR_NO_MEMORY, _("virDomainPtr"));
- return NULL;
- }
-
- dom->id = vm->vpsid;
+ dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
+ if (!dom)
+ return NULL;
+
+ 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"));
- return -1;
- }
-
- info->state = vm->status;
-
- if (!openvzIsActiveVM(vm)) {
+ _("no domain with matching uuid"));
+ return -1;
+ }
+
+ 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;
- return 0;
-}
+ info->maxMem = vm->def->maxmem;
+ info->memory = vm->def->memory;
+ info->nrVirtCpu = vm->def->vcpus;
+ 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) {
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};
+ 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 id"));
- return -1;
- }
-
- if (vm->status != 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) {
+ _("no domain with matching uuid"));
+ return -1;
+ }
+
+ if (vm->state != VIR_DOMAIN_RUNNING) {
openvzError(dom->conn, VIR_ERR_INTERNAL_ERROR,
- _("Could not exec %s"), VZCTL);
- return -1;
- }
-
- vm->vpsid = -1;
- vm->status = VIR_DOMAIN_SHUTOFF;
- ovz_driver.num_inactive ++;
- ovz_driver.num_active --;
+ _("domain is not in running state"));
+ return -1;
+ }
+
+ if (virRun(dom->conn, prog, NULL) < 0)
+ return -1;
+
+ vm->def->id = -1;
+ vm->state = VIR_DOMAIN_SHUTOFF;
return 0;
}
@@ -301,26 +299,23 @@ static int openvzDomainReboot(virDomainP
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"));
- return -1;
- }
-
- if (vm->status != 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) {
+ _("no domain with matching uuid"));
+ return -1;
+ }
+
+ if (vm->state != VIR_DOMAIN_RUNNING) {
openvzError(dom->conn, VIR_ERR_INTERNAL_ERROR,
- _("Could not exec %s"), VZCTL);
- return -1;
- }
+ _("domain is not in running state"));
+ return -1;
+ }
+
+ if (virRun(dom->conn, prog, NULL) < 0)
+ return -1;
return 0;
}
@@ -421,24 +416,31 @@ openvzDomainDefineXML(virConnectPtr conn
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)
- return NULL;
-
- vm = openvzFindVMByName(driver, vmdef->name);
+ 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 = 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 +463,11 @@ openvzDomainDefineXML(virConnectPtr conn
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;
-
- if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->net) < 0) {
+ dom->id = -1;
+
+ if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets) < 0) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("Could not configure network"));
goto exit;
@@ -488,27 +490,33 @@ openvzDomainCreateLinux(virConnectPtr co
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)))
- return NULL;
-
- vm = openvzFindVMByName(driver, vmdef->name);
+ 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 = 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 +538,7 @@ openvzDomainCreateLinux(virConnectPtr co
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 +552,19 @@ openvzDomainCreateLinux(virConnectPtr co
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 +577,8 @@ openvzDomainCreate(virDomainPtr dom)
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 +586,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 +598,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 +610,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 +629,8 @@ openvzDomainUndefine(virDomainPtr dom)
return -1;
}
- openvzRemoveInactiveVM(driver, vm);
+ virDomainRemoveInactive(&driver->domains, vm);
+
return 0;
}
@@ -632,8 +639,8 @@ openvzDomainSetAutostart(virDomainPtr do
{
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 +662,7 @@ openvzDomainGetAutostart(virDomainPtr do
{
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 +670,7 @@ openvzDomainGetAutostart(virDomainPtr do
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,32 +699,32 @@ static int openvzDomainSetVcpus(virDomai
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);
- return -1;
- }
-
- vm->vmdef->vcpus = nvcpus;
+ _("Could not exec %s"), VZCTL);
+ return -1;
+ }
+
+ vm->def->vcpus = nvcpus;
return 0;
}
@@ -735,51 +742,48 @@ static virDrvOpenStatus openvzOpen(virCo
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 (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;
+ }
/* 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;
- }
-
- conn->privateData = &ovz_driver;
-
- openvzAssignUUIDs();
-
- vms = openvzGetVPSInfo(conn);
- ovz_driver.vms = vms;
-
- return VIR_DRV_OPEN_SUCCESS;
+ 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;
+
+ if (openvzLoadDomains(driver) < 0)
+ goto cleanup;
+
+ conn->privateData = driver;
+
+ 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;
@@ -792,6 +796,12 @@ static int openvzGetNodeInfo(virConnectP
static int openvzGetNodeInfo(virConnectPtr conn,
virNodeInfoPtr 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) {
@@ -829,14 +839,22 @@ static int openvzListDomains(virConnectP
}
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,7 +876,7 @@ static int openvzListDefinedDomains(virC
_("Could not parse VPS ID %s"), buf);
continue;
}
- sprintf(vpsname, "%d", veid);
+ snprintf(vpsname, sizeof(vpsname), "%d", veid);
names[got] = strdup(vpsname);
got ++;
}
@@ -911,8 +929,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 +955,7 @@ static virDriver openvzDriver = {
NULL, /* uri */
openvzGetMaxVCPUs, /* getMaxVcpus */
openvzGetNodeInfo, /* nodeGetInfo */
- NULL, /* getCapabilities */
+ openvzGetCapabilities, /* getCapabilities */
openvzListDomains, /* listDomains */
openvzNumDomains, /* numOfDomains */
openvzDomainCreateLinux, /* domainCreateLinux */
@@ -953,7 +979,7 @@ static virDriver openvzDriver = {
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */
- NULL, /* domainDumpXML */
+ openvzDomainDumpXML, /* domainDumpXML */
openvzListDefinedDomains, /* listDomains */
openvzNumDefinedDomains, /* numOfDomains */
openvzDomainCreate, /* domainCreate */
diff -r e270be59a80f src/openvz_driver.h
--- a/src/openvz_driver.h Wed Aug 27 17:03:25 2008 +0100
+++ b/src/openvz_driver.h Wed Aug 27 17:03:45 2008 +0100
@@ -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
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
16 years, 7 months
[libvirt] [PATCH] Fix vnc port determining for xend
by Cole Robinson
Current libvirt checks xenstore for a xen guests
fixed vnc port on xend > 3.0.3. At least on f8
though, hvm guests don't store the vnc port in
xenstore, it is stored in the sexpr.
Patch fixes the logic to look in the sexpr if
the xenstore lookup appears to fail. This fixes
setting static vnc ports for f8 xen hvm guests.
Thanks,
Cole
diff --git a/src/xend_internal.c b/src/xend_internal.c
index 2a687c3..0b62dd0 100644
--- a/src/xend_internal.c
+++ b/src/xend_internal.c
@@ -2121,6 +2121,10 @@ xenDaemonParseSxprGraphicsNew(virConnectPtr conn,
goto no_memory;
} else {
int port = xenStoreDomainGetVNCPort(conn, def->id);
+ if (port == -1) {
+ // Didn't find port entry in xenstore
+ port = sexpr_int(node, "device/vfb/vncdisplay");
+ }
const char *listenAddr = sexpr_node(node, "device/vfb/vnclisten");
const char *vncPasswd = sexpr_node(node, "device/vfb/vncpasswd");;
const char *keymap = sexpr_node(node, "device/vfb/keymap");
16 years, 7 months
[libvirt] PATCH: Add a augeas lens for libvirtd.conf
by Daniel P. Berrange
Augeas is a awesome config file manipulation tool. libvirtd has a config
file. libvirtd meet augeas; augeas meet libvirt.
Now instead of telling people
'edit /etc/libvirt/libvirtd.conf and change listen_tls to 1,
and auth_tls to sasl'
we can say run
# augtool <<EOF
set /files/etc/libvirt/libvirtd.conf/listen_tls 1
set /files/etc/libvirt/libvirtd.conf/auth_tls sasl
save
EOF
THis patch is intended to be committed to libvirt, so the config file rules
are distributed alongside libvirt. I'm CC'ing augeas-devel for feedback on
the lens itself.
libvirt.spec.in | 2
qemud/Makefile.am | 8
qemud/libvirtd.aug | 64 ++++++
qemud/test_libvirtd.aug | 484 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 558 insertions(+)
Daniel
Index: qemud/Makefile.am
===================================================================
RCS file: /data/cvs/libvirt/qemud/Makefile.am,v
retrieving revision 1.51
diff -u -p -r1.51 Makefile.am
--- qemud/Makefile.am 20 Aug 2008 20:48:35 -0000 1.51
+++ qemud/Makefile.am 26 Aug 2008 20:03:48 -0000
@@ -24,6 +24,8 @@ EXTRA_DIST = \
libvirtd.policy \
libvirtd.sasl \
libvirtd.sysconf \
+ libvirtd.aug \
+ test_libvirtd.aug \
$(AVAHI_SOURCES) \
$(DAEMON_SOURCES)
@@ -56,6 +58,12 @@ sbin_PROGRAMS = libvirtd
confdir = $(sysconfdir)/libvirt/
conf_DATA = libvirtd.conf
+augeasdir = $(datadir)/augeas/lenses
+augeas_DATA = libvirtd.aug
+
+augeastestsdir = $(datadir)/augeas/lenses/tests
+augeastests_DATA = test_libvirtd.aug
+
libvirtd_SOURCES = $(DAEMON_SOURCES)
#-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199506L
Index: qemud/libvirtd.aug
===================================================================
RCS file: qemud/libvirtd.aug
diff -N qemud/libvirtd.aug
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ qemud/libvirtd.aug 26 Aug 2008 20:03:48 -0000
@@ -0,0 +1,64 @@
+(* /etc/libvirt/libvirtd.conf *)
+
+module Libvirtd =
+ autoload xfm
+
+ let eol = del /[ \t]*\n/ "\n"
+ let value_sep = del /[ \t]*=[ \t]*/ " = "
+ let prespace = del /[ \t]*/ ""
+
+ let array_sep = del /,[ \t\n]*/ ", "
+ let array_start = del /\[[ \t\n]*/ "[ "
+ let array_end = del /\]/ " ]"
+
+ let str_val = del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\""
+ let bool_val = store /0|1/
+ let str_array_element = [ str_val ] . del /[ \t\n]*/ ""
+ let str_array_val = array_start . ( str_array_element . ( array_sep . str_array_element ) * ) ? . array_end
+
+ let str_entry (kw:string) = [ prespace . key kw . value_sep . str_val . eol ]
+ let bool_entry (kw:string) = [ prespace . key kw . value_sep . bool_val . eol ]
+ let str_array_entry (kw:string) = [ prespace . key kw . value_sep . str_array_val . eol ]
+
+ let network_entry = bool_entry "listen_tls"
+ | bool_entry "listen_tcp"
+ | str_entry "tls_port"
+ | str_entry "tcp_port"
+ | str_entry "listen_addr"
+ | bool_entry "mdns_adv"
+ | str_entry "mdns_name"
+
+ let sock_acl_entry = str_entry "unix_sock_group"
+ | str_entry "unix_sock_ro_perms"
+ | str_entry "unix_sock_rw_perms"
+
+ let authentication_entry = str_entry "auth_unix_ro"
+ | str_entry "auth_unix_rw"
+ | str_entry "auth_tcp"
+ | str_entry "auth_tls"
+
+ let certificate_entry = str_entry "key_file"
+ | str_entry "cert_file"
+ | str_entry "ca_file"
+ | str_entry "crl_file"
+
+ let authorization_entry = bool_entry "tls_no_verify_certificate"
+ | str_array_entry "tls_allowed_dn_list"
+ | str_array_entry "sasl_allowed_username_list"
+
+ let entry = network_entry
+ | sock_acl_entry
+ | authentication_entry
+ | certificate_entry
+ | authorization_entry
+
+ let comment = [ label "comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
+ let empty = [ label "empty" . del /[ \t]*\n/ "" ]
+
+ let lns = ( entry | comment | empty ) +
+
+ let filter = incl "/etc/libvirt/libvirtd.conf"
+ . Util.stdexcl
+
+ let xfm = transform lns filter
+
Index: qemud/test_libvirtd.aug
===================================================================
RCS file: qemud/test_libvirtd.aug
diff -N qemud/test_libvirtd.aug
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ qemud/test_libvirtd.aug 26 Aug 2008 20:03:48 -0000
@@ -0,0 +1,484 @@
+module Test_libvirtd =
+ let conf1 = "# Master libvirt daemon configuration file
+#
+# For further information consult http://libvirt.org/format.html
+
+
+#################################################################
+#
+# Network connectivity controls
+#
+
+# Flag listening for secure TLS connections on the public TCP/IP port.
+# NB, must pass the --listen flag to the libvirtd process for this to
+# have any effect.
+#
+# It is necessary to setup a CA and issue server certificates before
+# using this capability.
+#
+# This is enabled by default, uncomment this to disable it
+listen_tls = 0
+"
+
+ let conf = "# Master libvirt daemon configuration file
+#
+# For further information consult http://libvirt.org/format.html
+
+
+#################################################################
+#
+# Network connectivity controls
+#
+
+# Flag listening for secure TLS connections on the public TCP/IP port.
+# NB, must pass the --listen flag to the libvirtd process for this to
+# have any effect.
+#
+# It is necessary to setup a CA and issue server certificates before
+# using this capability.
+#
+# This is enabled by default, uncomment this to disable it
+listen_tls = 0
+
+# Listen for unencrypted TCP connections on the public TCP/IP port.
+# NB, must pass the --listen flag to the libvirtd process for this to
+# have any effect.
+#
+# Using the TCP socket requires SASL authentication by default. Only
+# SASL mechanisms which support data encryption are allowed. This is
+# DIGEST_MD5 and GSSAPI (Kerberos5)
+#
+# This is disabled by default, uncomment this to enable it.
+listen_tcp = 1
+
+
+
+# Override the port for accepting secure TLS connections
+# This can be a port number, or service name
+#
+tls_port = \"16514\"
+
+# Override the port for accepting insecure TCP connections
+# This can be a port number, or service name
+#
+tcp_port = \"16509\"
+
+
+# Override the default configuration which binds to all network
+# interfaces. This can be a numeric IPv4/6 address, or hostname
+#
+listen_addr = \"192.168.0.1\"
+
+
+# Flag toggling mDNS advertizement of the libvirt service.
+#
+# Alternatively can disable for all services on a host by
+# stopping the Avahi daemon
+#
+# This is enabled by default, uncomment this to disable it
+mdns_adv = 0
+
+# Override the default mDNS advertizement name. This must be
+# unique on the immediate broadcast network.
+#
+# The default is \"Virtualization Host HOSTNAME\", where HOSTNAME
+# is subsituted for the short hostname of the machine (without domain)
+#
+mdns_name = \"Virtualization Host Joe Demo\"
+
+
+#################################################################
+#
+# UNIX socket access controls
+#
+
+# Set the UNIX domain socket group ownership. This can be used to
+# allow a 'trusted' set of users access to management capabilities
+# without becoming root.
+#
+# This is restricted to 'root' by default.
+unix_sock_group = \"libvirt\"
+
+# Set the UNIX socket permissions for the R/O socket. This is used
+# for monitoring VM status only
+#
+# Default allows any user. If setting group ownership may want to
+# restrict this to:
+unix_sock_ro_perms = \"0777\"
+
+# Set the UNIX socket permissions for the R/W socket. This is used
+# for full management of VMs
+#
+# Default allows only root. If PolicyKit is enabled on the socket,
+# the default will change to allow everyone (eg, 0777)
+#
+# If not using PolicyKit and setting group ownership for access
+# control then you may want to relax this to:
+unix_sock_rw_perms = \"0770\"
+
+
+
+#################################################################
+#
+# Authentication.
+#
+# - none: do not perform auth checks. If you can connect to the
+# socket you are allowed. This is suitable if there are
+# restrictions on connecting to the socket (eg, UNIX
+# socket permissions), or if there is a lower layer in
+# the network providing auth (eg, TLS/x509 certificates)
+#
+# - sasl: use SASL infrastructure. The actual auth scheme is then
+# controlled from /etc/sasl2/libvirt.conf. For the TCP
+# socket only GSSAPI & DIGEST-MD5 mechanisms will be used.
+# For non-TCP or TLS sockets, any scheme is allowed.
+#
+# - polkit: use PolicyKit to authenticate. This is only suitable
+# for use on the UNIX sockets. The default policy will
+# require a user to supply their own password to gain
+# full read/write access (aka sudo like), while anyone
+# is allowed read/only access.
+#
+# Set an authentication scheme for UNIX read-only sockets
+# By default socket permissions allow anyone to connect
+#
+# To restrict monitoring of domains you may wish to enable
+# an authentication mechanism here
+auth_unix_ro = \"none\"
+
+# Set an authentication scheme for UNIX read-write sockets
+# By default socket permissions only allow root. If PolicyKit
+# support was compiled into libvirt, the default will be to
+# use 'polkit' auth.
+#
+# If the unix_sock_rw_perms are changed you may wish to enable
+# an authentication mechanism here
+auth_unix_rw = \"none\"
+
+# Change the authentication scheme for TCP sockets.
+#
+# If you don't enable SASL, then all TCP traffic is cleartext.
+# Don't do this outside of a dev/test scenario. For real world
+# use, always enable SASL and use the GSSAPI or DIGEST-MD5
+# mechanism in /etc/sasl2/libvirt.conf
+auth_tcp = \"sasl\"
+
+# Change the authentication scheme for TLS sockets.
+#
+# TLS sockets already have encryption provided by the TLS
+# layer, and limited authentication is done by certificates
+#
+# It is possible to make use of any SASL authentication
+# mechanism as well, by using 'sasl' for this option
+auth_tls = \"none\"
+
+
+
+#################################################################
+#
+# TLS x509 certificate configuration
+#
+
+
+# Override the default server key file path
+#
+key_file = \"/etc/pki/libvirt/private/serverkey.pem\"
+
+# Override the default server certificate file path
+#
+cert_file = \"/etc/pki/libvirt/servercert.pem\"
+
+# Override the default CA certificate path
+#
+ca_file = \"/etc/pki/CA/cacert.pem\"
+
+# Specify a certificate revocation list.
+#
+# Defaults to not using a CRL, uncomment to enable it
+crl_file = \"/etc/pki/CA/crl.pem\"
+
+
+
+#################################################################
+#
+# Authorization controls
+#
+
+
+# Flag to disable verification of client certificates
+#
+# Client certificate verification is the primary authentication mechanism.
+# Any client which does not present a certificate signed by the CA
+# will be rejected.
+#
+# Default is to always verify. Uncommenting this will disable
+# verification - make sure an IP whitelist is set
+tls_no_verify_certificate = 1
+
+
+# A whitelist of allowed x509 Distinguished Names
+# This list may contain wildcards such as
+#
+# \"C=GB,ST=London,L=London,O=Red Hat,CN=*\"
+#
+# See the POSIX fnmatch function for the format of the wildcards.
+#
+# NB If this is an empty list, no client can connect, so comment out
+# entirely rather than using empty list to disable these checks
+#
+# By default, no DN's are checked
+ tls_allowed_dn_list = [\"DN1\", \"DN2\"]
+
+
+# A whitelist of allowed SASL usernames. The format for usernames
+# depends on the SASL authentication mechanism. Kerberos usernames
+# look like username@REALM
+#
+# This list may contain wildcards such as
+#
+# \"*(a)EXAMPLE.COM\"
+#
+# See the POSIX fnmatch function for the format of the wildcards.
+#
+# NB If this is an empty list, no client can connect, so comment out
+# entirely rather than using empty list to disable these checks
+#
+# By default, no Username's are checked
+sasl_allowed_username_list = [
+ \"joe(a)EXAMPLE.COM\",
+ \"fred(a)EXAMPLE.COM\"
+]
+"
+
+ test Libvirtd.lns get conf =
+ { "comment" = "Master libvirt daemon configuration file" }
+ { "comment" = "" }
+ { "comment" = "For further information consult http://libvirt.org/format.html" }
+ { "empty" }
+ { "empty" }
+ { "comment" = "################################################################" }
+ { "comment" = "" }
+ { "comment" = "Network connectivity controls" }
+ { "comment" = "" }
+ { "empty" }
+ { "comment" = "Flag listening for secure TLS connections on the public TCP/IP port." }
+ { "comment" = "NB, must pass the --listen flag to the libvirtd process for this to" }
+ { "comment" = "have any effect." }
+ { "comment" = "" }
+ { "comment" = "It is necessary to setup a CA and issue server certificates before" }
+ { "comment" = "using this capability." }
+ { "comment" = "" }
+ { "comment" = "This is enabled by default, uncomment this to disable it" }
+ { "listen_tls" = "0" }
+ { "empty" }
+ { "comment" = "Listen for unencrypted TCP connections on the public TCP/IP port." }
+ { "comment" = "NB, must pass the --listen flag to the libvirtd process for this to" }
+ { "comment" = "have any effect." }
+ { "comment" = "" }
+ { "comment" = "Using the TCP socket requires SASL authentication by default. Only" }
+ { "comment" = "SASL mechanisms which support data encryption are allowed. This is" }
+ { "comment" = "DIGEST_MD5 and GSSAPI (Kerberos5)" }
+ { "comment" = "" }
+ { "comment" = "This is disabled by default, uncomment this to enable it." }
+ { "listen_tcp" = "1" }
+ { "empty" }
+ { "empty" }
+ { "empty" }
+ { "comment" = "Override the port for accepting secure TLS connections" }
+ { "comment" = "This can be a port number, or service name" }
+ { "comment" = "" }
+ { "tls_port" = "16514" }
+ { "empty" }
+ { "comment" = "Override the port for accepting insecure TCP connections" }
+ { "comment" = "This can be a port number, or service name" }
+ { "comment" = "" }
+ { "tcp_port" = "16509" }
+ { "empty" }
+ { "empty" }
+ { "comment" = "Override the default configuration which binds to all network" }
+ { "comment" = "interfaces. This can be a numeric IPv4/6 address, or hostname" }
+ { "comment" = "" }
+ { "listen_addr" = "192.168.0.1" }
+ { "empty" }
+ { "empty" }
+ { "comment" = "Flag toggling mDNS advertizement of the libvirt service." }
+ { "comment" = "" }
+ { "comment" = "Alternatively can disable for all services on a host by" }
+ { "comment" = "stopping the Avahi daemon" }
+ { "comment" = "" }
+ { "comment" = "This is enabled by default, uncomment this to disable it" }
+ { "mdns_adv" = "0" }
+ { "empty" }
+ { "comment" = "Override the default mDNS advertizement name. This must be" }
+ { "comment" = "unique on the immediate broadcast network." }
+ { "comment" = "" }
+ { "comment" = "The default is \"Virtualization Host HOSTNAME\", where HOSTNAME" }
+ { "comment" = "is subsituted for the short hostname of the machine (without domain)" }
+ { "comment" = "" }
+ { "mdns_name" = "Virtualization Host Joe Demo" }
+ { "empty" }
+ { "empty" }
+ { "comment" = "################################################################" }
+ { "comment" = "" }
+ { "comment" = "UNIX socket access controls" }
+ { "comment" = "" }
+ { "empty" }
+ { "comment" = "Set the UNIX domain socket group ownership. This can be used to" }
+ { "comment" = "allow a 'trusted' set of users access to management capabilities" }
+ { "comment" = "without becoming root." }
+ { "comment" = "" }
+ { "comment" = "This is restricted to 'root' by default." }
+ { "unix_sock_group" = "libvirt" }
+ { "empty" }
+ { "comment" = "Set the UNIX socket permissions for the R/O socket. This is used" }
+ { "comment" = "for monitoring VM status only" }
+ { "comment" = "" }
+ { "comment" = "Default allows any user. If setting group ownership may want to" }
+ { "comment" = "restrict this to:" }
+ { "unix_sock_ro_perms" = "0777" }
+ { "empty" }
+ { "comment" = "Set the UNIX socket permissions for the R/W socket. This is used" }
+ { "comment" = "for full management of VMs" }
+ { "comment" = "" }
+ { "comment" = "Default allows only root. If PolicyKit is enabled on the socket," }
+ { "comment" = "the default will change to allow everyone (eg, 0777)" }
+ { "comment" = "" }
+ { "comment" = "If not using PolicyKit and setting group ownership for access" }
+ { "comment" = "control then you may want to relax this to:" }
+ { "unix_sock_rw_perms" = "0770" }
+ { "empty" }
+ { "empty" }
+ { "empty" }
+ { "comment" = "################################################################" }
+ { "comment" = "" }
+ { "comment" = "Authentication." }
+ { "comment" = "" }
+ { "comment" = "- none: do not perform auth checks. If you can connect to the" }
+ { "comment" = "socket you are allowed. This is suitable if there are" }
+ { "comment" = "restrictions on connecting to the socket (eg, UNIX" }
+ { "comment" = "socket permissions), or if there is a lower layer in" }
+ { "comment" = "the network providing auth (eg, TLS/x509 certificates)" }
+ { "comment" = "" }
+ { "comment" = "- sasl: use SASL infrastructure. The actual auth scheme is then" }
+ { "comment" = "controlled from /etc/sasl2/libvirt.conf. For the TCP" }
+ { "comment" = "socket only GSSAPI & DIGEST-MD5 mechanisms will be used." }
+ { "comment" = "For non-TCP or TLS sockets, any scheme is allowed." }
+ { "comment" = "" }
+ { "comment" = "- polkit: use PolicyKit to authenticate. This is only suitable" }
+ { "comment" = "for use on the UNIX sockets. The default policy will" }
+ { "comment" = "require a user to supply their own password to gain" }
+ { "comment" = "full read/write access (aka sudo like), while anyone" }
+ { "comment" = "is allowed read/only access." }
+ { "comment" = "" }
+ { "comment" = "Set an authentication scheme for UNIX read-only sockets" }
+ { "comment" = "By default socket permissions allow anyone to connect" }
+ { "comment" = "" }
+ { "comment" = "To restrict monitoring of domains you may wish to enable" }
+ { "comment" = "an authentication mechanism here" }
+ { "auth_unix_ro" = "none" }
+ { "empty" }
+ { "comment" = "Set an authentication scheme for UNIX read-write sockets" }
+ { "comment" = "By default socket permissions only allow root. If PolicyKit" }
+ { "comment" = "support was compiled into libvirt, the default will be to" }
+ { "comment" = "use 'polkit' auth." }
+ { "comment" = "" }
+ { "comment" = "If the unix_sock_rw_perms are changed you may wish to enable" }
+ { "comment" = "an authentication mechanism here" }
+ { "auth_unix_rw" = "none" }
+ { "empty" }
+ { "comment" = "Change the authentication scheme for TCP sockets." }
+ { "comment" = "" }
+ { "comment" = "If you don't enable SASL, then all TCP traffic is cleartext." }
+ { "comment" = "Don't do this outside of a dev/test scenario. For real world" }
+ { "comment" = "use, always enable SASL and use the GSSAPI or DIGEST-MD5" }
+ { "comment" = "mechanism in /etc/sasl2/libvirt.conf" }
+ { "auth_tcp" = "sasl" }
+ { "empty" }
+ { "comment" = "Change the authentication scheme for TLS sockets." }
+ { "comment" = "" }
+ { "comment" = "TLS sockets already have encryption provided by the TLS" }
+ { "comment" = "layer, and limited authentication is done by certificates" }
+ { "comment" = "" }
+ { "comment" = "It is possible to make use of any SASL authentication" }
+ { "comment" = "mechanism as well, by using 'sasl' for this option" }
+ { "auth_tls" = "none" }
+ { "empty" }
+ { "empty" }
+ { "empty" }
+ { "comment" = "################################################################" }
+ { "comment" = "" }
+ { "comment" = "TLS x509 certificate configuration" }
+ { "comment" = "" }
+ { "empty" }
+ { "empty" }
+ { "comment" = "Override the default server key file path" }
+ { "comment" = "" }
+ { "key_file" = "/etc/pki/libvirt/private/serverkey.pem" }
+ { "empty" }
+ { "comment" = "Override the default server certificate file path" }
+ { "comment" = "" }
+ { "cert_file" = "/etc/pki/libvirt/servercert.pem" }
+ { "empty" }
+ { "comment" = "Override the default CA certificate path" }
+ { "comment" = "" }
+ { "ca_file" = "/etc/pki/CA/cacert.pem" }
+ { "empty" }
+ { "comment" = "Specify a certificate revocation list." }
+ { "comment" = "" }
+ { "comment" = "Defaults to not using a CRL, uncomment to enable it" }
+ { "crl_file" = "/etc/pki/CA/crl.pem" }
+ { "empty" }
+ { "empty" }
+ { "empty" }
+ { "comment" = "################################################################" }
+ { "comment" = "" }
+ { "comment" = "Authorization controls" }
+ { "comment" = "" }
+ { "empty" }
+ { "empty" }
+ { "comment" = "Flag to disable verification of client certificates" }
+ { "comment" = "" }
+ { "comment" = "Client certificate verification is the primary authentication mechanism." }
+ { "comment" = "Any client which does not present a certificate signed by the CA" }
+ { "comment" = "will be rejected." }
+ { "comment" = "" }
+ { "comment" = "Default is to always verify. Uncommenting this will disable" }
+ { "comment" = "verification - make sure an IP whitelist is set" }
+ { "tls_no_verify_certificate" = "1" }
+ { "empty" }
+ { "empty" }
+ { "comment" = "A whitelist of allowed x509 Distinguished Names" }
+ { "comment" = "This list may contain wildcards such as" }
+ { "comment" = "" }
+ { "comment" = "\"C=GB,ST=London,L=London,O=Red Hat,CN=*\"" }
+ { "comment" = "" }
+ { "comment" = "See the POSIX fnmatch function for the format of the wildcards." }
+ { "comment" = "" }
+ { "comment" = "NB If this is an empty list, no client can connect, so comment out" }
+ { "comment" = "entirely rather than using empty list to disable these checks" }
+ { "comment" = "" }
+ { "comment" = "By default, no DN's are checked" }
+ { "tls_allowed_dn_list"
+ { = "DN1"}
+ { = "DN2"}
+ }
+ { "empty" }
+ { "empty" }
+ { "comment" = "A whitelist of allowed SASL usernames. The format for usernames" }
+ { "comment" = "depends on the SASL authentication mechanism. Kerberos usernames" }
+ { "comment" = "look like username@REALM" }
+ { "comment" = "" }
+ { "comment" = "This list may contain wildcards such as" }
+ { "comment" = "" }
+ { "comment" = "\"*(a)EXAMPLE.COM\"" }
+ { "comment" = "" }
+ { "comment" = "See the POSIX fnmatch function for the format of the wildcards." }
+ { "comment" = "" }
+ { "comment" = "NB If this is an empty list, no client can connect, so comment out" }
+ { "comment" = "entirely rather than using empty list to disable these checks" }
+ { "comment" = "" }
+ { "comment" = "By default, no Username's are checked" }
+ { "sasl_allowed_username_list"
+ { = "joe(a)EXAMPLE.COM" }
+ { = "fred(a)EXAMPLE.COM" }
+ }
Index: libvirt.spec.in
===================================================================
RCS file: /data/cvs/libvirt/libvirt.spec.in,v
retrieving revision 1.91
diff -u -p -r1.91 libvirt.spec.in
--- libvirt.spec.in 21 Aug 2008 09:28:54 -0000 1.91
+++ libvirt.spec.in 26 Aug 2008 20:04:24 -0000
@@ -252,6 +252,8 @@ fi
%dir %{_localstatedir}/lib/libvirt/
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/images/
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/boot/
+%{_datadir}/augeas/lenses/libvirtd.aug
+%{_datadir}/augeas/lenses/tests/test_libvirtd.aug
%if %{with_polkit}
%{_datadir}/PolicyKit/policy/org.libvirt.unix.policy
%endif
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
16 years, 7 months
[libvirt] [PATCH] virsh dump should not be live
by John Levon
Live dumps are much less likely to produce usable cores. They also
trigger a Xen bug that crashes xend.
Signed-off-by: John Levon <john.levon(a)sun.com>
Index: src/xend_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xend_internal.c,v
retrieving revision 1.211
diff -u -r1.211 xend_internal.c
--- src/xend_internal.c 28 Aug 2008 11:59:07 -0000 1.211
+++ src/xend_internal.c 28 Aug 2008 14:10:45 -0000
@@ -3037,7 +3037,7 @@
if (domain->id < 0)
return(-1);
return xend_op(domain->conn, domain->name, "op", "dump", "file", filename,
- "live", "1", "crash", "0", NULL);
+ "live", "0", "crash", "0", NULL);
}
/**
16 years, 7 months
[libvirt] [PATCH] use poweroff not halt for virsh shutdown
by John Levon
"halt" means just that, and we want to "poweroff". Linux doesn't care,
but Solaris differentiates between the two.
Signed-off-by: John Levon <john.levon(a)sun.com>
Index: src/xend_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xend_internal.c,v
retrieving revision 1.211
diff -u -r1.211 xend_internal.c
--- src/xend_internal.c 28 Aug 2008 11:59:07 -0000 1.211
+++ src/xend_internal.c 28 Aug 2008 14:04:21 -0000
@@ -2884,7 +2884,7 @@
}
if (domain->id < 0)
return(-1);
- return xend_op(domain->conn, domain->name, "op", "shutdown", "reason", "halt", NULL);
+ return xend_op(domain->conn, domain->name, "op", "shutdown", "reason", "poweroff", NULL);
}
/**
Index: src/xs_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xs_internal.c,v
retrieving revision 1.68
diff -u -r1.68 xs_internal.c
--- src/xs_internal.c 20 Aug 2008 20:48:36 -0000 1.68
+++ src/xs_internal.c 28 Aug 2008 14:04:22 -0000
@@ -654,7 +654,7 @@
* this is very hackish, the domU kernel probes for a special
* node in the xenstore and launch the shutdown command if found.
*/
- return(virDomainDoStoreWrite(domain, "control/shutdown", "halt"));
+ return(virDomainDoStoreWrite(domain, "control/shutdown", "poweroff"));
}
/**
16 years, 7 months
[libvirt] Java bindings
by Alejandro Berna Juan
Hi all, I'm Alejandro Berna from i2CAT (a non-profit foundation in
Barcelona, Spain, www.i2cat.net). I'm collaborating in a Europena project
called Federica ( www.fp7-*federica*.eu ). One of the branch of this project
is to permit virtualization of different hosts in the Federica test-bed. We
are doing some studies about the different management interfaces of Xen. Our
objective is to create a software remote client for Xen tool (in java if
it's possible) that can do (general functionalities):
- Create virtual machines assigning virtual interfaces.
- Permit choose the OS assigned to this virtual machine
- Install new applications to be tested in the virtual machines
- Configure a vm to become a router and permit to configure this router as
it was a physical router.
All these actions have to be performed remotelly. I have not found too much
information about libvrt but I think that can be usefull for our achieves.
If you agree that with libvrt we can perform these actions, maybe I can
build the java bindings for libvrt inside the Federica work. I'm waiting for
your opinions, thank you,
--
Alejandro Berna Juan
alejandro.berna(a)i2cat.net
16 years, 7 months
[libvirt] [PATCH] xen: fix domain lookup after define
by Cole Robinson
Defining a xen domain will succeed, but report
error because we weren't properly passing the
domain's name to the post-define lookup.
Attached patch fixes this, and also adds a
debug statement to show the sexpr we create
from the passed xml.
Thanks,
Cole
diff --git a/src/xend_internal.c b/src/xend_internal.c
index 2a687c3..124ee8b 100644
--- a/src/xend_internal.c
+++ b/src/xend_internal.c
@@ -4270,7 +4270,6 @@ xenDaemonDomainMigratePerform (virDomainPtr domain,
virDomainPtr xenDaemonDomainDefineXML(virConnectPtr conn, const char *xmlDesc) {
int ret;
char *sexpr;
- char *name = NULL;
virDomainPtr dom;
xenUnifiedPrivatePtr priv;
virDomainDefPtr def;
@@ -4292,15 +4291,17 @@ virDomainPtr xenDaemonDomainDefineXML(virConnectPtr conn, const char *xmlDesc) {
goto error;
}
+ DEBUG("Defining w/ sexpr: \n%s", sexpr);
+
ret = xend_op(conn, "", "op", "new", "config", sexpr, NULL);
VIR_FREE(sexpr);
if (ret != 0) {
virXendError(conn, VIR_ERR_XEN_CALL,
- _("Failed to create inactive domain %s\n"), name);
+ _("Failed to create inactive domain %s\n"), def->name);
goto error;
}
- dom = virDomainLookupByName(conn, name);
+ dom = virDomainLookupByName(conn, def->name);
if (dom == NULL) {
goto error;
}
16 years, 7 months
[libvirt] [PATCH] [LXC] Add version implementation
by Dan Smith
This patch adds an implementation of the version function to the LXC driver.
The providers use the hypervisor version in a field of one of the instances,
so we need to have something meaningful here. AFAICT, the only real option
we have (considering the limitations of the libvirt version information) is
to use the kernel version.
diff -r be3be31c94a2 -r 0cabead40d65 src/lxc_driver.c
--- a/src/lxc_driver.c Fri Aug 29 07:11:15 2008 +0000
+++ b/src/lxc_driver.c Fri Aug 29 09:10:41 2008 -0700
@@ -1110,6 +1110,29 @@
return 0;
}
+static int lxcVersion(virConnectPtr conn, unsigned long *version)
+{
+ struct utsname ver;
+ int maj;
+ int min;
+ int rev;
+
+ if (uname(&ver) != 0) {
+ lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("uname(): %m"));
+ return -1;
+ }
+
+ if (sscanf(ver.release, "%i.%i.%i", &maj, &min, &rev) != 3) {
+ lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Unknown release: %s"), ver.release);
+ return -1;
+ }
+
+ *version = (maj * 1000 * 1000) + (min * 1000) + rev;
+
+ return 0;
+}
/* Function Tables */
static virDriver lxcDriver = {
@@ -1121,7 +1144,7 @@
lxcClose, /* close */
NULL, /* supports_feature */
NULL, /* type */
- NULL, /* version */
+ lxcVersion, /* version */
NULL, /* getHostname */
NULL, /* getURI */
NULL, /* getMaxVcpus */
16 years, 7 months
[libvirt] [PATCH] Fix ejecting cdroms with latest qemu syntax
by Cole Robinson
Originally, ejecting a cdrom from a qemu guest entailed
passing 'eject cdrom' to the monitor. But since qemu
added the -drive option, more than one cdrom can be
specified, so just using 'cdrom' isn't explicit enough.
The attached patch updates media change/eject to use
the current qemu syntax. The new generated commands
look something like "eject ide0-cd1", with the name
derived from device target and bus type.
While I was in there I added support for inserting/
ejecting media from scsi cdroms and floppy devices.
This is built around my previous two patches:
- Fix cd eject segfault
- Attempt to detect cdrom change failures
Thanks,
Cole
16 years, 7 months
[libvirt] [PATCH] Attempt to detect cdrom change failures
by Cole Robinson
If a 'change' or 'eject' qemu monitor command fails,
an error message is printed to the monitor of the
form "device {not found, is locked, is not
removable"}. This is really the only indication we
have that the command errored out, so scrape the
monitor reply for "\ndevice " and fail if it is
found.
Thanks,
Cole
commit 8caba367b62b4fb961722cd641d8172bb441b84e
Author: Cole Robinson <crobinso(a)dhcp-100-19-219.bos.redhat.com>
Date: Fri Aug 22 16:35:24 2008 -0400
Scrape cdrom attach/eject monitor output to try and determine failure.
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 9a26375..05e7402 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -2994,6 +2994,19 @@ static int qemudDomainChangeCDROM(virDomainPtr dom,
VIR_FREE(newsrc);
return -1;
}
+
+ /* If the command failed qemu prints:
+ * device not found, device is locked ...
+ * No message is printed on success it seems */
+ DEBUG ("cdrom change reply: %s", reply);
+ if (strstr(reply, "\ndevice ")) {
+ qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ "%s", _("changing cdrom media failed));
+ VIR_FREE(reply);
+ VIR_FREE(cmd);
+ return -1;
+ }
+
VIR_FREE(reply);
VIR_FREE(cmd);
16 years, 7 months