mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 02:51:16 +00:00
OpenVZ xml refactoring
* src/domain_conf.[ch] src/openvz_conf.[ch] src/openvz_driver.c: patch from Evgeniy Sokolov doing the OpenVZ xml refactoring, still needs to be ported to the new XML parsing code but implements the new format. Daniel
This commit is contained in:
parent
387e06421f
commit
996933bbcd
@ -1,3 +1,10 @@
|
|||||||
|
Mon Jul 28 16:04:58 CEST 2008 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
|
* src/domain_conf.[ch] src/openvz_conf.[ch] src/openvz_driver.c:
|
||||||
|
patch from Evgeniy Sokolov doing the OpenVZ xml refactoring,
|
||||||
|
still needs to be ported to the new XML parsing code but
|
||||||
|
implements the new format.
|
||||||
|
|
||||||
Mon Jul 28 14:50:55 CEST 2008 Daniel Veillard <veillard@redhat.com>
|
Mon Jul 28 14:50:55 CEST 2008 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
* src/qemu_driver.c: patch from Guido Günther to make sure create
|
* src/qemu_driver.c: patch from Guido Günther to make sure create
|
||||||
|
@ -640,7 +640,7 @@ static void virDomainNetRandomMAC(virDomainNetDefPtr def) {
|
|||||||
* @param node XML nodeset to parse for net definition
|
* @param node XML nodeset to parse for net definition
|
||||||
* @return 0 on success, -1 on failure
|
* @return 0 on success, -1 on failure
|
||||||
*/
|
*/
|
||||||
static virDomainNetDefPtr
|
virDomainNetDefPtr
|
||||||
virDomainNetDefParseXML(virConnectPtr conn,
|
virDomainNetDefParseXML(virConnectPtr conn,
|
||||||
xmlNodePtr node) {
|
xmlNodePtr node) {
|
||||||
virDomainNetDefPtr def;
|
virDomainNetDefPtr def;
|
||||||
|
@ -474,6 +474,9 @@ int virDomainLoadAllConfigs(virConnectPtr conn,
|
|||||||
int virDomainDeleteConfig(virConnectPtr conn,
|
int virDomainDeleteConfig(virConnectPtr conn,
|
||||||
virDomainObjPtr dom);
|
virDomainObjPtr dom);
|
||||||
|
|
||||||
|
virDomainNetDefPtr virDomainNetDefParseXML(virConnectPtr conn,
|
||||||
|
xmlNodePtr node);
|
||||||
|
|
||||||
VIR_ENUM_DECL(virDomainVirt)
|
VIR_ENUM_DECL(virDomainVirt)
|
||||||
VIR_ENUM_DECL(virDomainBoot)
|
VIR_ENUM_DECL(virDomainBoot)
|
||||||
VIR_ENUM_DECL(virDomainFeature)
|
VIR_ENUM_DECL(virDomainFeature)
|
||||||
|
@ -56,6 +56,8 @@
|
|||||||
#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 struct openvz_vm_def *openvzParseXML(virConnectPtr conn, xmlDocPtr xml);
|
||||||
@ -136,6 +138,34 @@ strtoI(const char *str)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* function checks MAC address is empty
|
||||||
|
return 0 - empty
|
||||||
|
1 - not
|
||||||
|
*/
|
||||||
|
int openvzCheckEmptyMac(const unsigned char *mac)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < VIR_DOMAIN_NET_MAC_SIZE; i++)
|
||||||
|
if (mac[i] != 0x00)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert mac address to string
|
||||||
|
return pointer to string or NULL
|
||||||
|
*/
|
||||||
|
char *openvzMacToString(const unsigned char *mac)
|
||||||
|
{
|
||||||
|
char str[20];
|
||||||
|
if (snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||||
|
mac[0], mac[1], mac[2],
|
||||||
|
mac[3], mac[4], mac[5]) >= 18)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return strdup(str);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
openvzRemoveInactiveVM(struct openvz_driver *driver, struct openvz_vm *vm)
|
openvzRemoveInactiveVM(struct openvz_driver *driver, struct openvz_vm *vm)
|
||||||
{
|
{
|
||||||
@ -148,30 +178,7 @@ void
|
|||||||
openvzFreeVMDef(struct openvz_vm_def *def)
|
openvzFreeVMDef(struct openvz_vm_def *def)
|
||||||
{
|
{
|
||||||
if (def) {
|
if (def) {
|
||||||
struct ovz_quota *quota = def->fs.quota;
|
virDomainNetDefFree(def->net);
|
||||||
struct ovz_ip *ip = def->net.ips;
|
|
||||||
struct ovz_ns *ns = def->net.ns;
|
|
||||||
|
|
||||||
while (quota) {
|
|
||||||
struct ovz_quota *prev = quota;
|
|
||||||
|
|
||||||
quota = quota->next;
|
|
||||||
VIR_FREE(prev);
|
|
||||||
}
|
|
||||||
while (ip) {
|
|
||||||
struct ovz_ip *prev = ip;
|
|
||||||
|
|
||||||
ip = ip->next;
|
|
||||||
VIR_FREE(prev);
|
|
||||||
}
|
|
||||||
while (ns) {
|
|
||||||
struct ovz_ns *prev = ns;
|
|
||||||
|
|
||||||
ns = ns->next;
|
|
||||||
VIR_FREE(prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
VIR_FREE(def);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,6 +292,91 @@ struct openvz_vm_def
|
|||||||
return def;
|
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("/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
|
* Parses a libvirt XML definition of a guest, and populates the
|
||||||
* the openvz_vm struct with matching data about the guests config
|
* the openvz_vm struct with matching data about the guests config
|
||||||
@ -293,12 +385,12 @@ static struct openvz_vm_def
|
|||||||
*openvzParseXML(virConnectPtr conn,
|
*openvzParseXML(virConnectPtr conn,
|
||||||
xmlDocPtr xml) {
|
xmlDocPtr xml) {
|
||||||
xmlNodePtr root = NULL;
|
xmlNodePtr root = NULL;
|
||||||
xmlChar *prop = NULL;
|
char *prop = NULL;
|
||||||
xmlXPathContextPtr ctxt = NULL;
|
xmlXPathContextPtr ctxt = NULL;
|
||||||
xmlXPathObjectPtr obj = NULL;
|
xmlXPathObjectPtr obj = NULL;
|
||||||
struct openvz_vm_def *def;
|
struct openvz_vm_def *def = NULL;
|
||||||
struct ovz_ip *ovzIp;
|
xmlNodePtr *nodes = NULL;
|
||||||
struct ovz_ns *ovzNs;
|
int i, n;
|
||||||
|
|
||||||
if (VIR_ALLOC(def) < 0) {
|
if (VIR_ALLOC(def) < 0) {
|
||||||
openvzError(conn, VIR_ERR_NO_MEMORY, _("xmlXPathContext"));
|
openvzError(conn, VIR_ERR_NO_MEMORY, _("xmlXPathContext"));
|
||||||
@ -306,7 +398,6 @@ static struct openvz_vm_def
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare parser / xpath context */
|
/* Prepare parser / xpath context */
|
||||||
|
|
||||||
root = xmlDocGetRootElement(xml);
|
root = xmlDocGetRootElement(xml);
|
||||||
if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "domain"))) {
|
if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "domain"))) {
|
||||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("incorrect root element"));
|
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("incorrect root element"));
|
||||||
@ -318,14 +409,15 @@ static struct openvz_vm_def
|
|||||||
openvzError(conn, VIR_ERR_NO_MEMORY, _("xmlXPathContext"));
|
openvzError(conn, VIR_ERR_NO_MEMORY, _("xmlXPathContext"));
|
||||||
goto bail_out;
|
goto bail_out;
|
||||||
}
|
}
|
||||||
|
ctxt->node = root;
|
||||||
|
|
||||||
/* Find out what type of OPENVZ virtualization to use */
|
/* Find out what type of OPENVZ virtualization to use */
|
||||||
if (!(prop = xmlGetProp(root, BAD_CAST "type"))) {
|
if (!(prop = virXMLPropString(root, "type"))) {
|
||||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("missing domain type attribute"));
|
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("missing domain type attribute"));
|
||||||
goto bail_out;
|
goto bail_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STRNEQ((char *)prop, "openvz")){
|
if (STRNEQ(prop, "openvz")){
|
||||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("invalid domain type attribute"));
|
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("invalid domain type attribute"));
|
||||||
goto bail_out;
|
goto bail_out;
|
||||||
}
|
}
|
||||||
@ -347,142 +439,55 @@ static struct openvz_vm_def
|
|||||||
}
|
}
|
||||||
strncpy(def->name, (const char *) obj->stringval, OPENVZ_NAME_MAX);
|
strncpy(def->name, (const char *) obj->stringval, OPENVZ_NAME_MAX);
|
||||||
xmlXPathFreeObject(obj);
|
xmlXPathFreeObject(obj);
|
||||||
|
obj = NULL;
|
||||||
|
|
||||||
/* Extract domain uuid */
|
/* Extract domain uuid */
|
||||||
obj = xmlXPathEval(BAD_CAST "string(/domain/uuid[1])", ctxt);
|
prop = virXPathString("string(./uuid[1])", ctxt);
|
||||||
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
if (!prop) {
|
||||||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if ((err = virUUIDGenerate(def->uuid))) {
|
if ((err = virUUIDGenerate(def->uuid))) {
|
||||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("Failed to generate UUID"));
|
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Failed to generate UUID: %s"),
|
||||||
|
strerror(err));
|
||||||
goto bail_out;
|
goto bail_out;
|
||||||
}
|
}
|
||||||
} else if (virUUIDParse((const char *)obj->stringval, def->uuid) < 0) {
|
} else {
|
||||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("malformed uuid element"));
|
if (virUUIDParse(prop, def->uuid) < 0) {
|
||||||
goto bail_out;
|
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("malformed uuid element"));
|
||||||
|
goto bail_out;
|
||||||
|
}
|
||||||
|
VIR_FREE(prop);
|
||||||
}
|
}
|
||||||
xmlXPathFreeObject(obj);
|
|
||||||
|
/* extract virtual CPUs */
|
||||||
|
if (virXPathULong("string(./vcpu[1])", ctxt, &def->vcpus) < 0)
|
||||||
|
def->vcpus = 0; //use default CPUs count
|
||||||
|
|
||||||
/* Extract filesystem info */
|
/* Extract filesystem info */
|
||||||
obj = xmlXPathEval(BAD_CAST "string(/domain/container/filesystem/template[1])", ctxt);
|
if (openvzParseDomainFS(conn, &(def->fs), ctxt)) {
|
||||||
if ((obj == NULL) || (obj->type != XPATH_STRING) || (obj->stringval == NULL)
|
|
||||||
|| (obj->stringval[0] == 0)) {
|
|
||||||
openvzError(conn, VIR_ERR_OS_TYPE, NULL);
|
|
||||||
goto bail_out;
|
|
||||||
}
|
|
||||||
strncpy(def->fs.tmpl, (const char *) obj->stringval, OPENVZ_TMPL_MAX);
|
|
||||||
xmlXPathFreeObject(obj);
|
|
||||||
|
|
||||||
/* TODO Add quota processing here */
|
|
||||||
|
|
||||||
/* TODO analysis of the network devices */
|
|
||||||
|
|
||||||
|
|
||||||
/* Extract network */
|
|
||||||
/* Extract ipaddress */
|
|
||||||
obj = xmlXPathEval(BAD_CAST"string(/domain/container/network/ipaddress[1])", ctxt);
|
|
||||||
if ((obj == NULL) || (obj->type != XPATH_STRING) || (obj->stringval == NULL)
|
|
||||||
|| (obj->stringval[0] == 0)) {
|
|
||||||
openvzLog(OPENVZ_WARN,
|
|
||||||
_("No IP address in the given xml config file '%s'"),
|
|
||||||
xml->name);
|
|
||||||
}
|
|
||||||
if (xmlStrlen(obj->stringval) >= (OPENVZ_IP_MAX)) {
|
|
||||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("ipaddress length too long"));
|
_("malformed filesystem tag"));
|
||||||
goto bail_out;
|
goto bail_out;
|
||||||
}
|
}
|
||||||
if (VIR_ALLOC(ovzIp) < 0) {
|
|
||||||
openvzLog(OPENVZ_ERR,
|
|
||||||
_("Failed to Create Memory for 'ovz_ip' structure"));
|
|
||||||
goto bail_out;
|
|
||||||
}
|
|
||||||
strncpy(ovzIp->ip, (const char *) obj->stringval, OPENVZ_IP_MAX);
|
|
||||||
def->net.ips = ovzIp;
|
|
||||||
xmlXPathFreeObject(obj);
|
|
||||||
|
|
||||||
/* Extract netmask */
|
/* analysis of the network devices */
|
||||||
obj = xmlXPathEval(BAD_CAST "string(/domain/container/network/netmask[1])", ctxt);
|
if ((n = virXPathNodeSet("/domain/devices/interface", ctxt, &nodes)) < 0) {
|
||||||
if ((obj == NULL) || (obj->type != XPATH_STRING)
|
|
||||||
|| (obj->stringval == NULL) || (obj->stringval[0] == 0))
|
|
||||||
openvzLog(OPENVZ_WARN,
|
|
||||||
_("No Netmask address in the given xml config file '%s'"),
|
|
||||||
xml->name);
|
|
||||||
|
|
||||||
if (strlen((const char *) obj->stringval) >= (OPENVZ_IP_MAX)) {
|
|
||||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("netmask length too long"));
|
"%s", _("cannot extract network devices"));
|
||||||
goto bail_out;
|
goto bail_out;
|
||||||
}
|
}
|
||||||
strncpy(def->net.ips->netmask, (const char *) obj->stringval, OPENVZ_IP_MAX);
|
|
||||||
xmlXPathFreeObject(obj);
|
|
||||||
|
|
||||||
/* Extract hostname */
|
for (i = n - 1 ; i >= 0 ; i--) {
|
||||||
obj = xmlXPathEval(BAD_CAST "string(/domain/container/network/hostname[1])", ctxt);
|
virDomainNetDefPtr net = virDomainNetDefParseXML(conn,
|
||||||
if ((obj == NULL) || (obj->type != XPATH_STRING) || (obj->stringval == NULL)
|
nodes[i]);
|
||||||
|| (obj->stringval[0] == 0))
|
if (!net)
|
||||||
openvzLog(OPENVZ_WARN,
|
goto bail_out;
|
||||||
_("No hostname in the given xml config file '%s'"),
|
|
||||||
xml->name);
|
|
||||||
|
|
||||||
if (strlen((const char *) obj->stringval) >= (OPENVZ_HOSTNAME_MAX - 1)) {
|
net->next = def->net;
|
||||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
def->net = net;
|
||||||
_("hostname length too long"));
|
|
||||||
goto bail_out;
|
|
||||||
}
|
}
|
||||||
strncpy(def->net.hostname, (const char *) obj->stringval, OPENVZ_HOSTNAME_MAX - 1);
|
VIR_FREE(nodes);
|
||||||
xmlXPathFreeObject(obj);
|
|
||||||
|
|
||||||
/* Extract gateway */
|
|
||||||
obj = xmlXPathEval(BAD_CAST"string(/domain/container/network/gateway[1])", ctxt);
|
|
||||||
if ((obj == NULL) || (obj->type != XPATH_STRING) || (obj->stringval == NULL)
|
|
||||||
|| (obj->stringval[0] == 0))
|
|
||||||
openvzLog(OPENVZ_WARN,
|
|
||||||
_("No Gateway address in the given xml config file '%s'"),
|
|
||||||
xml->name);
|
|
||||||
|
|
||||||
if (strlen((const char *) obj->stringval) >= (OPENVZ_IP_MAX)) {
|
|
||||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("gateway length too long"));
|
|
||||||
goto bail_out;
|
|
||||||
}
|
|
||||||
strncpy(def->net.def_gw, (const char *) obj->stringval, OPENVZ_IP_MAX);
|
|
||||||
xmlXPathFreeObject(obj);
|
|
||||||
|
|
||||||
/* Extract nameserver */
|
|
||||||
obj = xmlXPathEval(BAD_CAST "string(/domain/container/network/nameserver[1])", ctxt);
|
|
||||||
if ((obj == NULL) || (obj->type != XPATH_STRING) || (obj->stringval == NULL)
|
|
||||||
|| (obj->stringval[0] == 0))
|
|
||||||
openvzLog(OPENVZ_WARN,
|
|
||||||
_("No Nameserver address inthe given xml config file '%s'"),
|
|
||||||
xml->name);
|
|
||||||
|
|
||||||
if (strlen((const char *) obj->stringval) >= (OPENVZ_IP_MAX)) {
|
|
||||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("nameserver length too long"));
|
|
||||||
goto bail_out;
|
|
||||||
}
|
|
||||||
if (VIR_ALLOC(ovzNs) < 0) {
|
|
||||||
openvzLog(OPENVZ_ERR,
|
|
||||||
_("Failed to Create Memory for 'ovz_ns' structure"));
|
|
||||||
goto bail_out;
|
|
||||||
}
|
|
||||||
strncpy(ovzNs->ip, (const char *) obj->stringval, OPENVZ_IP_MAX);
|
|
||||||
def->net.ns = ovzNs;
|
|
||||||
xmlXPathFreeObject(obj);
|
|
||||||
|
|
||||||
/* Extract profile */
|
|
||||||
obj = xmlXPathEval(BAD_CAST "string(/domain/container/profile[1])", ctxt);
|
|
||||||
if ((obj == NULL) || (obj->type != XPATH_STRING) || (obj->stringval == NULL)
|
|
||||||
|| (obj->stringval[0] == 0)) {
|
|
||||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR, NULL);
|
|
||||||
goto bail_out;
|
|
||||||
}
|
|
||||||
if (strlen((const char *) obj->stringval) >= (OPENVZ_PROFILE_MAX - 1)) {
|
|
||||||
openvzError(conn, VIR_ERR_INTERNAL_ERROR, _("profile length too long"));
|
|
||||||
goto bail_out;
|
|
||||||
}
|
|
||||||
strncpy(def->profile, (const char *) obj->stringval, OPENVZ_PROFILE_MAX - 1);
|
|
||||||
xmlXPathFreeObject(obj);
|
|
||||||
|
|
||||||
xmlXPathFreeContext(ctxt);
|
xmlXPathFreeContext(ctxt);
|
||||||
return def;
|
return def;
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#define OPENVZ_CONF_H
|
#define OPENVZ_CONF_H
|
||||||
|
|
||||||
#include "openvz_driver.h"
|
#include "openvz_driver.h"
|
||||||
|
#include "domain_conf.h"
|
||||||
|
|
||||||
enum { OPENVZ_WARN, OPENVZ_ERR };
|
enum { OPENVZ_WARN, OPENVZ_ERR };
|
||||||
|
|
||||||
@ -61,33 +62,16 @@ struct vps_props {
|
|||||||
|
|
||||||
struct openvz_fs_def {
|
struct openvz_fs_def {
|
||||||
char tmpl[OPENVZ_TMPL_MAX];
|
char tmpl[OPENVZ_TMPL_MAX];
|
||||||
struct ovz_quota *quota;
|
long int disksize, diskinodes;
|
||||||
};
|
|
||||||
|
|
||||||
struct ovz_ip {
|
|
||||||
char ip[OPENVZ_IP_MAX];
|
|
||||||
char netmask[OPENVZ_IP_MAX];
|
|
||||||
struct ovz_ip *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ovz_ns {
|
|
||||||
char ip[OPENVZ_IP_MAX];
|
|
||||||
struct ovz_ns *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct openvz_net_def {
|
|
||||||
char hostname[OPENVZ_HOSTNAME_MAX];
|
|
||||||
char def_gw[OPENVZ_IP_MAX];
|
|
||||||
struct ovz_ip *ips;
|
|
||||||
struct ovz_ns *ns;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct openvz_vm_def {
|
struct openvz_vm_def {
|
||||||
char name[OPENVZ_NAME_MAX];
|
char name[OPENVZ_NAME_MAX];
|
||||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||||
char profile[OPENVZ_PROFILE_MAX];
|
char profile[OPENVZ_PROFILE_MAX];
|
||||||
|
unsigned long vcpus;
|
||||||
struct openvz_fs_def fs;
|
struct openvz_fs_def fs;
|
||||||
struct openvz_net_def net;
|
virDomainNetDefPtr net;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ovz_quota {
|
struct ovz_quota {
|
||||||
@ -133,4 +117,7 @@ void openvzFreeDriver(struct openvz_driver *driver);
|
|||||||
void openvzFreeVM(struct openvz_driver *driver, struct openvz_vm *vm, int checkCallee);
|
void openvzFreeVM(struct openvz_driver *driver, struct openvz_vm *vm, int checkCallee);
|
||||||
void openvzFreeVMDef(struct openvz_vm_def *def);
|
void openvzFreeVMDef(struct openvz_vm_def *def);
|
||||||
int strtoI(const char *str);
|
int strtoI(const char *str);
|
||||||
|
int openvzCheckEmptyMac(const unsigned char *mac);
|
||||||
|
char *openvzMacToString(const unsigned char *mac);
|
||||||
|
|
||||||
#endif /* OPENVZ_CONF_H */
|
#endif /* OPENVZ_CONF_H */
|
||||||
|
@ -155,14 +155,6 @@ static int openvzDomainDefineCmd(virConnectPtr conn,
|
|||||||
ADD_ARG_LIT("--config");
|
ADD_ARG_LIT("--config");
|
||||||
ADD_ARG_LIT(vmdef->profile);
|
ADD_ARG_LIT(vmdef->profile);
|
||||||
}
|
}
|
||||||
if ((vmdef->net.ips->ip && *(vmdef->net.ips->ip))) {
|
|
||||||
ADD_ARG_LIT("--ipadd");
|
|
||||||
ADD_ARG_LIT(vmdef->net.ips->ip);
|
|
||||||
}
|
|
||||||
if ((vmdef->net.hostname && *(vmdef->net.hostname))) {
|
|
||||||
ADD_ARG_LIT("--hostname");
|
|
||||||
ADD_ARG_LIT(vmdef->net.hostname);
|
|
||||||
}
|
|
||||||
|
|
||||||
ADD_ARG(NULL);
|
ADD_ARG(NULL);
|
||||||
return 0;
|
return 0;
|
||||||
@ -336,6 +328,98 @@ static int openvzDomainReboot(virDomainPtr dom,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
openvzDomainSetNetwork(virConnectPtr conn, const char *vpsid,
|
||||||
|
virDomainNetDefPtr net)
|
||||||
|
{
|
||||||
|
int rc = 0, narg;
|
||||||
|
char *prog[OPENVZ_MAX_ARG];
|
||||||
|
char *mac = NULL;
|
||||||
|
|
||||||
|
#define ADD_ARG_LIT(thisarg) \
|
||||||
|
do { \
|
||||||
|
if (narg >= OPENVZ_MAX_ARG) \
|
||||||
|
goto no_memory; \
|
||||||
|
if ((prog[narg++] = strdup(thisarg)) == NULL) \
|
||||||
|
goto no_memory; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
if (net == NULL)
|
||||||
|
return 0;
|
||||||
|
if (vpsid == NULL) {
|
||||||
|
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Container ID is not specified"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (narg = 0; narg < OPENVZ_MAX_ARG; narg++)
|
||||||
|
prog[narg] = NULL;
|
||||||
|
|
||||||
|
narg = 0;
|
||||||
|
|
||||||
|
if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
|
||||||
|
net->type == VIR_DOMAIN_NET_TYPE_ETHERNET) {
|
||||||
|
ADD_ARG_LIT(VZCTL);
|
||||||
|
ADD_ARG_LIT("--quiet");
|
||||||
|
ADD_ARG_LIT("set");
|
||||||
|
ADD_ARG_LIT(vpsid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (openvzCheckEmptyMac(net->mac) > 0)
|
||||||
|
mac = openvzMacToString(net->mac);
|
||||||
|
|
||||||
|
if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE &&
|
||||||
|
net->data.bridge.brname != NULL) {
|
||||||
|
char opt[1024];
|
||||||
|
//--netif_add ifname[,mac,host_ifname,host_mac]
|
||||||
|
ADD_ARG_LIT("--netif_add") ;
|
||||||
|
strncpy(opt, net->data.bridge.brname, 256);
|
||||||
|
if (mac != NULL) {
|
||||||
|
strcat(opt, ",");
|
||||||
|
strcat(opt, mac);
|
||||||
|
}
|
||||||
|
ADD_ARG_LIT(opt) ;
|
||||||
|
}else if (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
|
||||||
|
net->data.ethernet.ipaddr != NULL) {
|
||||||
|
//--ipadd ip
|
||||||
|
ADD_ARG_LIT("--ipadd") ;
|
||||||
|
ADD_ARG_LIT(net->data.ethernet.ipaddr) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: processing NAT and physical device
|
||||||
|
|
||||||
|
if (prog[0] != NULL){
|
||||||
|
ADD_ARG_LIT("--save");
|
||||||
|
if (virRun(conn, (char **)prog, NULL) < 0) {
|
||||||
|
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Could not exec %s"), VZCTL);
|
||||||
|
rc = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (net->next != NULL)
|
||||||
|
if (openvzDomainSetNetwork(conn, vpsid, net->next) < 0) {
|
||||||
|
rc = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
cmdExecFree(prog);
|
||||||
|
VIR_FREE(mac);
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
no_memory:
|
||||||
|
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Could not put argument to %s"), VZCTL);
|
||||||
|
cmdExecFree(prog);
|
||||||
|
VIR_FREE(mac);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
#undef ADD_ARG_LIT
|
||||||
|
}
|
||||||
|
|
||||||
static virDomainPtr
|
static virDomainPtr
|
||||||
openvzDomainDefineXML(virConnectPtr conn, const char *xml)
|
openvzDomainDefineXML(virConnectPtr conn, const char *xml)
|
||||||
{
|
{
|
||||||
@ -366,6 +450,9 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: set number virtual CPUs
|
||||||
|
//TODO: set quota
|
||||||
|
|
||||||
if (virRun(conn, (char **)prog, NULL) < 0) {
|
if (virRun(conn, (char **)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);
|
||||||
@ -375,7 +462,14 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
|
|||||||
dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid);
|
dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid);
|
||||||
if (dom)
|
if (dom)
|
||||||
dom->id = vm->vpsid;
|
dom->id = vm->vpsid;
|
||||||
exit:
|
|
||||||
|
if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->net) < 0) {
|
||||||
|
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Could not configure network"));
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
cmdExecFree(prog);
|
cmdExecFree(prog);
|
||||||
return dom;
|
return dom;
|
||||||
}
|
}
|
||||||
@ -420,6 +514,12 @@ openvzDomainCreateLinux(virConnectPtr conn, const char *xml,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->net) < 0) {
|
||||||
|
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Could not configure network"));
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
progstart[3] = vmdef->name;
|
progstart[3] = vmdef->name;
|
||||||
|
|
||||||
if (virRun(conn, (char **)progstart, NULL) < 0) {
|
if (virRun(conn, (char **)progstart, NULL) < 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user