mirror of https://gitee.com/openkylin/libvirt.git
Add bridged network to openvz driver & add some openvz docs
This commit is contained in:
parent
48f32d8033
commit
bfdac58c36
|
@ -1,3 +1,10 @@
|
|||
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 & 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>
|
||||
<domain type='openvz' id='104'>
|
||||
<name>104</name>
|
||||
<uuid>86c12009-e591-a159-6e9f-91d18b85ef78</uuid>
|
||||
<vcpu>3</vcpu>
|
||||
<os>
|
||||
<type>exe</type>
|
||||
<init>/sbin/init</init>
|
||||
</os>
|
||||
<devices>
|
||||
<filesystem type='template'>
|
||||
<source name='fedora-9-i386-minimal'/>
|
||||
<target dir='/'/>
|
||||
</filesystem>
|
||||
<interface type='bridge'>
|
||||
<mac address='00:18:51:5b:ea:bf'/>
|
||||
<source bridge='br0'/>
|
||||
<target dev='veth101.0'/>
|
||||
</interface>
|
||||
</devices>
|
||||
</domain>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
|
|
|
@ -1,5 +1,109 @@
|
|||
<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 & 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>
|
||||
<domain type='openvz' id='104'>
|
||||
<name>104</name>
|
||||
<uuid>86c12009-e591-a159-6e9f-91d18b85ef78</uuid>
|
||||
<vcpu>3</vcpu>
|
||||
<os>
|
||||
<type>exe</type>
|
||||
<init>/sbin/init</init>
|
||||
</os>
|
||||
<devices>
|
||||
<filesystem type='template'>
|
||||
<source name='fedora-9-i386-minimal'/>
|
||||
<target dir='/'/>
|
||||
</filesystem>
|
||||
<interface type='bridge'>
|
||||
<mac address='00:18:51:5b:ea:bf'/>
|
||||
<source bridge='br0'/>
|
||||
<target dev='veth101.0'/>
|
||||
</interface>
|
||||
</devices>
|
||||
</domain>
|
||||
</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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue