提交 bfdac58c 编写于 作者: D Daniel P. Berrange

Add bridged network to openvz driver & add some openvz docs

上级 48f32d80
Wed Nov 12 16:33:42 GMT 2008 Daniel P. Berrange <berrange@redhat.com>
* docs/drvopenvz.html, docs/drvopenvz.html.in: Introductory
docs for openvz driver
* src/openvz_conf.c, src/openvz_conf.h, src/openvz_driver.c:
Support bridged network configuration for containers
Wed Nov 12 16:13:42 GMT 2008 Daniel P. Berrange <berrange@redhat.com>
* src/storage_backend.c, src/storage_backend.h, src/storage_driver.c:
......
......@@ -122,6 +122,93 @@
</div>
<div id="content">
<h1>OpenVZ container driver</h1>
<p>
The OpenVZ driver for libvirt allows use and management of container
based virtualization on a Linux host OS. Prior to using the OpenVZ
driver, the OpenVZ enabled kernel must be installed &amp; booted, and the
OpenVZ userspace tools installed. The libvirt driver has been tested
with OpenVZ 3.0.22, but other 3.0.x versions should also work without
undue trouble.
</p>
<h2>Connections to OpenVZ driver</h2>
<p>
The libvirt OpenVZ driver is a single-instance privileged driver,
with a driver name of 'openvz'. Some example conection URIs for
the libvirt driver are:
</p>
<pre>
openvz:///system (local access)
openvz://example.com/system (remote access, TLS/x509)
openvz+tcp://example.com/system (remote access, SASl/Kerberos)
openvz+ssh://root@example.com/system (remote access, SSH tunnelled)
</pre>
<h2>Notes on bridged networking</h2>
<p>
Bridged networking enables a guest domain (ie container) to have its
network interface connected directly to the host's physical LAN. Before
this can be used there are a couple of configuration pre-requisites for
the host OS.
</p>
<h3>Host network devices</h3>
<p>
One or more of the physical devices must be attached to a bridge. The
process for this varies according to the operating system in use, so
for up to date notes consult the <a href="http://wiki.libvirt.org">Wiki</a>
or your operating system's networking documentation. The basic idea is
that the host OS should end up with a bridge device "br0" containing a
physical device "eth0", or a bonding device "bond0".
</p>
<h3>OpenVZ tools configuration</h3>
<p>
OpenVZ releases later than 3.0.23 ship with a standard network device
setup script that is able to setup bridging, named
<code>/usr/sbin/vznetaddbr</code>. For releases prior to 3.0.23, this
script must be created manually by the host OS adminstrator. The
simplest way is to just download the latest version of this script
from a newer OpenVZ release, or upstream source repository. Then
a generic configuration file <code>/etc/vz/vznetctl.conf</code>
must be created containing
</p>
<pre>
#!/bin/bash
EXTERNAL_SCRIPT="/usr/sbin/vznetaddbr"
</pre>
<p>
The host OS is now ready to allow bridging of guest containers, which
will work whether the container is started with libvirt, or OpenVZ
tools.
</p>
<h2>Example guest domain XML configuration</h2>
<p>
The current libvirt OpenVZ driver has a restriction that the
domain names must match the OpenVZ container VEID, which by
convention start at 100, and are incremented from there. The
choice of OS template to use inside the container is determined
by the <code>filesystem</code> tag, and the template source name
matches the templates known to OpenVZ tools.
</p>
<pre>
&lt;domain type='openvz' id='104'&gt;
&lt;name&gt;104&lt;/name&gt;
&lt;uuid&gt;86c12009-e591-a159-6e9f-91d18b85ef78&lt;/uuid&gt;
&lt;vcpu&gt;3&lt;/vcpu&gt;
&lt;os&gt;
&lt;type&gt;exe&lt;/type&gt;
&lt;init&gt;/sbin/init&lt;/init&gt;
&lt;/os&gt;
&lt;devices&gt;
&lt;filesystem type='template'&gt;
&lt;source name='fedora-9-i386-minimal'/&gt;
&lt;target dir='/'/&gt;
&lt;/filesystem&gt;
&lt;interface type='bridge'&gt;
&lt;mac address='00:18:51:5b:ea:bf'/&gt;
&lt;source bridge='br0'/&gt;
&lt;target dev='veth101.0'/&gt;
&lt;/interface&gt;
&lt;/devices&gt;
&lt;/domain&gt;
</pre>
</div>
</div>
<div id="footer">
......
<html>
<html> <!-- -*- html -*- -->
<body>
<h1>OpenVZ container driver</h1>
<p>
The OpenVZ driver for libvirt allows use and management of container
based virtualization on a Linux host OS. Prior to using the OpenVZ
driver, the OpenVZ enabled kernel must be installed &amp; booted, and the
OpenVZ userspace tools installed. The libvirt driver has been tested
with OpenVZ 3.0.22, but other 3.0.x versions should also work without
undue trouble.
</p>
<h2>Connections to OpenVZ driver</h2>
<p>
The libvirt OpenVZ driver is a single-instance privileged driver,
with a driver name of 'openvz'. Some example conection URIs for
the libvirt driver are:
</p>
<pre>
openvz:///system (local access)
openvz://example.com/system (remote access, TLS/x509)
openvz+tcp://example.com/system (remote access, SASl/Kerberos)
openvz+ssh://root@example.com/system (remote access, SSH tunnelled)
</pre>
<h2>Notes on bridged networking</h2>
<p>
Bridged networking enables a guest domain (ie container) to have its
network interface connected directly to the host's physical LAN. Before
this can be used there are a couple of configuration pre-requisites for
the host OS.
</p>
<h3>Host network devices</h3>
<p>
One or more of the physical devices must be attached to a bridge. The
process for this varies according to the operating system in use, so
for up to date notes consult the <a href="http://wiki.libvirt.org">Wiki</a>
or your operating system's networking documentation. The basic idea is
that the host OS should end up with a bridge device "br0" containing a
physical device "eth0", or a bonding device "bond0".
</p>
<h3>OpenVZ tools configuration</h3>
<p>
OpenVZ releases later than 3.0.23 ship with a standard network device
setup script that is able to setup bridging, named
<code>/usr/sbin/vznetaddbr</code>. For releases prior to 3.0.23, this
script must be created manually by the host OS adminstrator. The
simplest way is to just download the latest version of this script
from a newer OpenVZ release, or upstream source repository. Then
a generic configuration file <code>/etc/vz/vznetctl.conf</code>
must be created containing
</p>
<pre>
#!/bin/bash
EXTERNAL_SCRIPT="/usr/sbin/vznetaddbr"
</pre>
<p>
The host OS is now ready to allow bridging of guest containers, which
will work whether the container is started with libvirt, or OpenVZ
tools.
</p>
<h2>Example guest domain XML configuration</h2>
<p>
The current libvirt OpenVZ driver has a restriction that the
domain names must match the OpenVZ container VEID, which by
convention start at 100, and are incremented from there. The
choice of OS template to use inside the container is determined
by the <code>filesystem</code> tag, and the template source name
matches the templates known to OpenVZ tools.
</p>
<pre>
&lt;domain type='openvz' id='104'&gt;
&lt;name&gt;104&lt;/name&gt;
&lt;uuid&gt;86c12009-e591-a159-6e9f-91d18b85ef78&lt;/uuid&gt;
&lt;vcpu&gt;3&lt;/vcpu&gt;
&lt;os&gt;
&lt;type&gt;exe&lt;/type&gt;
&lt;init&gt;/sbin/init&lt;/init&gt;
&lt;/os&gt;
&lt;devices&gt;
&lt;filesystem type='template'&gt;
&lt;source name='fedora-9-i386-minimal'/&gt;
&lt;target dir='/'/&gt;
&lt;/filesystem&gt;
&lt;interface type='bridge'&gt;
&lt;mac address='00:18:51:5b:ea:bf'/&gt;
&lt;source bridge='br0'/&gt;
&lt;target dev='veth101.0'/&gt;
&lt;/interface&gt;
&lt;/devices&gt;
&lt;/domain&gt;
</pre>
</body>
</html>
......@@ -52,7 +52,7 @@
static char *openvzLocateConfDir(void);
static int openvzGetVPSUUID(int vpsid, char *uuidstr);
static int openvzLocateConfFile(int vpsid, char *conffile, int maxlen);
static int openvzLocateConfFile(int vpsid, char *conffile, int maxlen, const char *ext);
static int openvzAssignUUIDs(void);
int
......@@ -145,6 +145,8 @@ virCapsPtr openvzCapsInit(void)
0, 0)) == NULL)
goto no_memory;
virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x52, 0x54, 0x00 });
if ((guest = virCapabilitiesAddGuest(caps,
"exe",
utsname.machine,
......@@ -170,54 +172,6 @@ no_memory:
}
/* function checks MAC address is empty
return 0 - empty
1 - not
*/
int openvzCheckEmptyMac(const unsigned char *mac)
{
int i;
for (i = 0; i < VIR_MAC_BUFLEN; 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);
}
/*parse MAC from view: 00:18:51:8F:D9:F3
return -1 - error
0 - OK
*/
static int openvzParseMac(const char *macaddr, unsigned char *mac)
{
int ret;
ret = sscanf((const char *)macaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
(unsigned int*)&mac[0],
(unsigned int*)&mac[1],
(unsigned int*)&mac[2],
(unsigned int*)&mac[3],
(unsigned int*)&mac[4],
(unsigned int*)&mac[5]) ;
if (ret == 6)
return 0;
return -1;
}
static int
openvzReadNetworkConf(virConnectPtr conn,
virDomainDefPtr def,
......@@ -288,6 +242,9 @@ openvzReadNetworkConf(virConnectPtr conn,
while (*next != '\0' && *next != ',') next++;
if (STRPREFIX(p, "ifname=")) {
p += 7;
/* skip in libvirt */
} else if (STRPREFIX(p, "host_ifname=")) {
p += 12;
len = next - p;
if (len > 16) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
......@@ -295,14 +252,25 @@ openvzReadNetworkConf(virConnectPtr conn,
goto error;
}
if (VIR_ALLOC_N(net->ifname, len+1) < 0)
goto no_memory;
strncpy(net->ifname, p, len);
net->ifname[len] = '\0';
} else if (STRPREFIX(p, "bridge=")) {
p += 7;
len = next - p;
if (len > 16) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("Too long bridge device name"));
goto error;
}
if (VIR_ALLOC_N(net->data.bridge.brname, len+1) < 0)
goto no_memory;
strncpy(net->data.bridge.brname, p, len);
net->data.bridge.brname[len] = '\0';
} else if (STRPREFIX(p, "host_ifname=")) {
p += 12;
//skip in libvirt
} else if (STRPREFIX(p, "mac=")) {
p += 4;
len = next - p;
......@@ -313,14 +281,11 @@ openvzReadNetworkConf(virConnectPtr conn,
}
strncpy(cpy_temp, p, len);
cpy_temp[len] = '\0';
if (openvzParseMac(cpy_temp, net->mac)<0) {
if (virParseMacAddr(cpy_temp, net->mac) < 0) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("Wrong MAC address"));
goto error;
}
} else if (STRPREFIX(p, "host_mac=")) {
p += 9;
//skip in libvirt
}
p = ++next;
} while (p < token + strlen(token));
......@@ -492,6 +457,68 @@ int openvzLoadDomains(struct openvz_driver *driver) {
return -1;
}
int
openvzWriteConfigParam(int vpsid, const char *param, const char *value)
{
char conf_file[PATH_MAX];
char temp_file[PATH_MAX];
char line[PATH_MAX] ;
int fd, temp_fd;
if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX, "conf")<0)
return -1;
if (openvzLocateConfFile(vpsid, temp_file, PATH_MAX, "tmp")<0)
return -1;
fd = open(conf_file, O_RDONLY);
if (fd == -1)
return -1;
temp_fd = open(temp_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (temp_fd == -1) {
close(fd);
return -1;
}
while(1) {
if (openvz_readline(fd, line, sizeof(line)) <= 0)
break;
if (!STRPREFIX(line, param) &&
line[strlen(param)] == '=') {
if (safewrite(temp_fd, line, strlen(line)) !=
strlen(line))
goto error;
}
}
if (safewrite(temp_fd, param, strlen(param)) < 0 ||
safewrite(temp_fd, "=\"", 2) < 0 ||
safewrite(temp_fd, value, strlen(value)) < 0 ||
safewrite(temp_fd, "\"\n", 2) < 0)
goto error;
if (close(fd) < 0)
goto error;
fd = -1;
if (close(temp_fd) < 0)
goto error;
temp_fd = -1;
if (rename(temp_file, conf_file) < 0)
goto error;
return 0;
error:
if (fd != -1)
close(fd);
if (temp_fd != -1)
close(temp_fd);
unlink(temp_file);
return -1;
}
/*
* Read parameter from container config
* sample: 133, "OSTEMPLATE", value, 1024
......@@ -509,7 +536,7 @@ openvzReadConfigParam(int vpsid ,const char * param, char *value, int maxlen)
char * sf, * token;
char *saveptr = NULL;
if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX)<0)
if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX, "conf")<0)
return -1;
value[0] = 0;
......@@ -549,7 +576,7 @@ openvzReadConfigParam(int vpsid ,const char * param, char *value, int maxlen)
* 0 - OK
*/
static int
openvzLocateConfFile(int vpsid, char *conffile, int maxlen)
openvzLocateConfFile(int vpsid, char *conffile, int maxlen, const char *ext)
{
char * confdir;
int ret = 0;
......@@ -558,7 +585,8 @@ openvzLocateConfFile(int vpsid, char *conffile, int maxlen)
if (confdir == NULL)
return -1;
if (snprintf(conffile, maxlen, "%s/%d.conf", confdir, vpsid) >= maxlen)
if (snprintf(conffile, maxlen, "%s/%d.%s",
confdir, vpsid, ext ? ext : "conf") >= maxlen)
ret = -1;
VIR_FREE(confdir);
......@@ -615,7 +643,7 @@ openvzGetVPSUUID(int vpsid, char *uuidstr)
char iden[1024];
int fd, ret;
if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX)<0)
if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX, "conf")<0)
return -1;
fd = open(conf_file, O_RDONLY);
......@@ -655,7 +683,7 @@ openvzSetDefinedUUID(int vpsid, unsigned char *uuid)
if (uuid == NULL)
return -1;
if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX)<0)
if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX, "conf")<0)
return -1;
if (openvzGetVPSUUID(vpsid, uuidstr))
......@@ -723,4 +751,3 @@ static int openvzAssignUUIDs(void)
VIR_FREE(conf_dir);
return 0;
}
......@@ -50,6 +50,8 @@ enum { OPENVZ_WARN, OPENVZ_ERR };
#define VZLIST "/usr/sbin/vzlist"
#define VZCTL "/usr/sbin/vzctl"
#define VZCTL_BRIDGE_MIN_VERSION ((3 * 1000 * 1000) + (0 * 1000) + 22 + 1)
struct openvz_driver {
virCapsPtr caps;
virDomainObjList domains;
......@@ -60,12 +62,11 @@ int openvz_readline(int fd, char *ptr, int maxlen);
int openvzExtractVersion(virConnectPtr conn,
struct openvz_driver *driver);
int openvzReadConfigParam(int vpsid ,const char * param, char *value, int maxlen);
int openvzWriteConfigParam(int vpsid, const char *param, const char *value);
virCapsPtr openvzCapsInit(void);
int openvzLoadDomains(struct openvz_driver *driver);
void openvzFreeDriver(struct openvz_driver *driver);
int strtoI(const char *str);
int openvzCheckEmptyMac(const unsigned char *mac);
char *openvzMacToString(const unsigned char *mac);
int openvzSetDefinedUUID(int vpsid, unsigned char *uuid);
#endif /* OPENVZ_CONF_H */
......@@ -56,6 +56,7 @@
#include "openvz_conf.h"
#include "nodeinfo.h"
#include "memory.h"
#include "bridge.h"
#define OPENVZ_MAX_ARG 28
#define CMDBUF_LEN 1488
......@@ -330,13 +331,56 @@ static int openvzDomainReboot(virDomainPtr dom,
return 0;
}
static char *
openvzGenerateVethName(int veid, char *dev_name_ve)
{
char dev_name[32];
int ifNo = 0;
if (sscanf(dev_name_ve, "%*[^0-9]%d", &ifNo) != 1)
return NULL;
if (snprintf(dev_name, sizeof(dev_name), "veth%d.%d", veid, ifNo) < 7)
return NULL;
return strdup(dev_name);
}
static char *
openvzGenerateContainerVethName(int veid)
{
int ret;
char temp[1024];
/* try to get line "^NETIF=..." from config */
if ( (ret = openvzReadConfigParam(veid, "NETIF", temp, sizeof(temp))) <= 0) {
snprintf(temp, sizeof(temp), "eth0");
} else {
char *s;
int max = 0;
/* get maximum interface number (actually, it is the last one) */
for (s=strtok(temp, ";"); s; s=strtok(NULL, ";")) {
int x;
if (sscanf(s, "ifname=eth%d", &x) != 1) return NULL;
if (x > max) max = x;
}
/* set new name */
snprintf(temp, sizeof(temp), "eth%d", max+1);
}
return strdup(temp);
}
static int
openvzDomainSetNetwork(virConnectPtr conn, const char *vpsid,
virDomainNetDefPtr net)
virDomainNetDefPtr net,
virBufferPtr configBuf)
{
int rc = 0, narg;
const char *prog[OPENVZ_MAX_ARG];
char *mac = NULL;
char macaddr[VIR_MAC_STRING_BUFLEN];
struct openvz_driver *driver = (struct openvz_driver *) conn->privateData;
char *opt = NULL;
#define ADD_ARG_LIT(thisarg) \
do { \
......@@ -368,21 +412,61 @@ openvzDomainSetNetwork(virConnectPtr conn, const char *vpsid,
ADD_ARG_LIT(vpsid);
}
if (openvzCheckEmptyMac(net->mac) > 0)
mac = openvzMacToString(net->mac);
virFormatMacAddr(net->mac, macaddr);
if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *dev_name_ve;
int veid = strtoI(vpsid);
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);
/* generate interface name in ve and copy it to options */
dev_name_ve = openvzGenerateContainerVethName(veid);
if (dev_name_ve == NULL) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("Could not generate eth name for container"));
rc = -1;
goto exit;
}
/* if user doesn't specified host interface name,
* than we need to generate it */
if (net->ifname == NULL) {
net->ifname = openvzGenerateVethName(veid, dev_name_ve);
if (net->ifname == NULL) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
_("Could not generate veth name"));
rc = -1;
VIR_FREE(dev_name_ve);
goto exit;
}
}
virBufferAdd(&buf, dev_name_ve, -1); /* Guest dev */
virBufferVSprintf(&buf, ",%s", macaddr); /* Guest dev mac */
virBufferVSprintf(&buf, ",%s", net->ifname); /* Host dev */
virBufferVSprintf(&buf, ",%s", macaddr); /* Host dev mac */
if (driver->version >= VZCTL_BRIDGE_MIN_VERSION) {
virBufferVSprintf(&buf, ",%s", net->data.bridge.brname); /* Host bridge */
} else {
virBufferVSprintf(configBuf, "ifname=%s", dev_name_ve);
virBufferVSprintf(configBuf, ",mac=%s", macaddr); /* Guest dev mac */
virBufferVSprintf(configBuf, ",host_ifname=%s", net->ifname); /* Host dev */
virBufferVSprintf(configBuf, ",host_mac=%s", macaddr); /* Host dev mac */
virBufferVSprintf(configBuf, ",bridge=%s", net->data.bridge.brname); /* Host bridge */
}
VIR_FREE(dev_name_ve);
if (!(opt = virBufferContentAndReset(&buf)))
goto no_memory;
ADD_ARG_LIT(opt) ;
}else if (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
VIR_FREE(opt);
} else if (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
net->data.ethernet.ipaddr != NULL) {
//--ipadd ip
ADD_ARG_LIT("--ipadd") ;
......@@ -403,19 +487,67 @@ openvzDomainSetNetwork(virConnectPtr conn, const char *vpsid,
exit:
cmdExecFree(prog);
VIR_FREE(mac);
return rc;
no_memory:
VIR_FREE(opt);
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 int
openvzDomainSetNetworkConfig(virConnectPtr conn,
virDomainDefPtr def)
{
unsigned int i;
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *param;
int first = 1;
struct openvz_driver *driver = (struct openvz_driver *) conn->privateData;
for (i = 0 ; i < def->nnets ; i++) {
if (driver->version < VZCTL_BRIDGE_MIN_VERSION &&
def->nets[i]->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
if (first)
first = 0;
else
virBufferAddLit(&buf, ";");
}
if (openvzDomainSetNetwork(conn, def->name, def->nets[i], &buf) < 0) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("Could not configure network"));
goto exit;
}
}
if (driver->version < VZCTL_BRIDGE_MIN_VERSION && def->nnets) {
param = virBufferContentAndReset(&buf);
if (param) {
if (openvzWriteConfigParam(strtoI(def->name), "NETIF", param) < 0) {
VIR_FREE(param);
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot replace NETIF config"));
return -1;
}
VIR_FREE(param);
}
}
return 0;
exit:
param = virBufferContentAndReset(&buf);
VIR_FREE(param);
return -1;
}
static virDomainPtr
openvzDomainDefineXML(virConnectPtr conn, const char *xml)
{
......@@ -423,7 +555,6 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
virDomainDefPtr vmdef = NULL;
virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL;
int i;
const char *prog[OPENVZ_MAX_ARG];
prog[0] = NULL;
......@@ -469,18 +600,13 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
goto exit;
}
if (openvzDomainSetNetworkConfig(conn, vmdef) < 0)
goto exit;
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom)
dom->id = -1;
for (i = 0 ; i < vmdef->nnets ; i++) {
if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets[i]) < 0) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("Could not configure network"));
goto exit;
}
}
if (vmdef->vcpus > 0) {
if (openvzDomainSetVcpus(dom, vmdef->vcpus) < 0) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
......@@ -501,7 +627,6 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
virDomainDefPtr vmdef = NULL;
virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL;
int i;
struct openvz_driver *driver = (struct openvz_driver *) conn->privateData;
const char *progstart[] = {VZCTL, "--quiet", "start", NULL, NULL};
const char *progcreate[OPENVZ_MAX_ARG];
......@@ -547,13 +672,8 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
goto exit;
}
for (i = 0 ; i < vmdef->nnets ; i++) {
if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets[i]) < 0) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("Could not configure network"));
goto exit;
}
}
if (openvzDomainSetNetworkConfig(conn, vmdef) < 0)
goto exit;
progstart[3] = vmdef->name;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册