提交 e060f864 编写于 作者: R Richa Marwaha 提交者: Michal Privoznik

Add -netdev bridge support

This patch adds the support to run the QEMU network helper
under unprivileged user. It also adds the support for
attach-interface option in virsh to run under unprivileged
user.
Signed-off-by: NRicha Marwaha <rmarwah@linux.vnet.ibm.com>
Signed-off-by: Corey Bryant<coreyb@linux.vnet.ibm.com>
上级 756fe786
...@@ -2964,6 +2964,8 @@ error: ...@@ -2964,6 +2964,8 @@ error:
char * char *
qemuBuildHostNetStr(virDomainNetDefPtr net, qemuBuildHostNetStr(virDomainNetDefPtr net,
struct qemud_driver *driver,
virBitmapPtr qemuCaps,
char type_sep, char type_sep,
int vlan, int vlan,
const char *tapfd, const char *tapfd,
...@@ -2972,6 +2974,7 @@ qemuBuildHostNetStr(virDomainNetDefPtr net, ...@@ -2972,6 +2974,7 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
bool is_tap = false; bool is_tap = false;
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
enum virDomainNetType netType = virDomainNetGetActualType(net); enum virDomainNetType netType = virDomainNetGetActualType(net);
const char *brname = NULL;
if (net->script && netType != VIR_DOMAIN_NET_TYPE_ETHERNET) { if (net->script && netType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
...@@ -2981,8 +2984,21 @@ qemuBuildHostNetStr(virDomainNetDefPtr net, ...@@ -2981,8 +2984,21 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
} }
switch (netType) { switch (netType) {
case VIR_DOMAIN_NET_TYPE_NETWORK: /*
* If type='bridge', and we're running as privileged user
* or -netdev bridge is not supported then it will fall
* through, -net tap,fd
*/
case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_BRIDGE:
if (!driver->privileged &&
qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE)) {
brname = virDomainNetGetActualBridgeName(net);
virBufferAsprintf(&buf, "bridge%cbr=%s", type_sep, brname);
type_sep = ',';
is_tap = true;
break;
}
case VIR_DOMAIN_NET_TYPE_NETWORK:
case VIR_DOMAIN_NET_TYPE_DIRECT: case VIR_DOMAIN_NET_TYPE_DIRECT:
virBufferAsprintf(&buf, "tap%cfd=%s", type_sep, tapfd); virBufferAsprintf(&buf, "tap%cfd=%s", type_sep, tapfd);
type_sep = ','; type_sep = ',';
...@@ -5125,7 +5141,7 @@ qemuBuildCommandLine(virConnectPtr conn, ...@@ -5125,7 +5141,7 @@ qemuBuildCommandLine(virConnectPtr conn,
for (i = 0 ; i < def->nnets ; i++) { for (i = 0 ; i < def->nnets ; i++) {
virDomainNetDefPtr net = def->nets[i]; virDomainNetDefPtr net = def->nets[i];
char *nic, *host; char *nic, *host;
char tapfd_name[50]; char tapfd_name[50] = "";
char vhostfd_name[50] = ""; char vhostfd_name[50] = "";
int vlan; int vlan;
int bootindex = bootNet; int bootindex = bootNet;
...@@ -5162,17 +5178,26 @@ qemuBuildCommandLine(virConnectPtr conn, ...@@ -5162,17 +5178,26 @@ qemuBuildCommandLine(virConnectPtr conn,
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK || if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) { actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
int tapfd = qemuNetworkIfaceConnect(def, conn, driver, net, /*
qemuCaps); * If type='bridge' then we attempt to allocate the tap fd here only if
if (tapfd < 0) * running under a privilged user or -netdev bridge option is not
goto error; * supported.
*/
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
driver->privileged ||
(!qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE))) {
int tapfd = qemuNetworkIfaceConnect(def, conn, driver, net,
qemuCaps);
if (tapfd < 0)
goto error;
last_good_net = i; last_good_net = i;
virCommandTransferFD(cmd, tapfd); virCommandTransferFD(cmd, tapfd);
if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", if (snprintf(tapfd_name, sizeof(tapfd_name), "%d",
tapfd) >= sizeof(tapfd_name)) tapfd) >= sizeof(tapfd_name))
goto no_memory; goto no_memory;
}
} else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) { } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
int tapfd = qemuPhysIfaceConnect(def, driver, net, int tapfd = qemuPhysIfaceConnect(def, driver, net,
qemuCaps, vmop); qemuCaps, vmop);
...@@ -5215,8 +5240,9 @@ qemuBuildCommandLine(virConnectPtr conn, ...@@ -5215,8 +5240,9 @@ qemuBuildCommandLine(virConnectPtr conn,
if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
virCommandAddArg(cmd, "-netdev"); virCommandAddArg(cmd, "-netdev");
if (!(host = qemuBuildHostNetStr(net, ',', vlan, if (!(host = qemuBuildHostNetStr(net, driver, qemuCaps,
tapfd_name, vhostfd_name))) ',', vlan, tapfd_name,
vhostfd_name)))
goto error; goto error;
virCommandAddArg(cmd, host); virCommandAddArg(cmd, host);
VIR_FREE(host); VIR_FREE(host);
...@@ -5238,8 +5264,9 @@ qemuBuildCommandLine(virConnectPtr conn, ...@@ -5238,8 +5264,9 @@ qemuBuildCommandLine(virConnectPtr conn,
if (!(qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && if (!(qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) { qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) {
virCommandAddArg(cmd, "-net"); virCommandAddArg(cmd, "-net");
if (!(host = qemuBuildHostNetStr(net, ',', vlan, if (!(host = qemuBuildHostNetStr(net, driver, qemuCaps,
tapfd_name, vhostfd_name))) ',', vlan, tapfd_name,
vhostfd_name)))
goto error; goto error;
virCommandAddArg(cmd, host); virCommandAddArg(cmd, host);
VIR_FREE(host); VIR_FREE(host);
......
...@@ -62,6 +62,8 @@ qemuBuildChrDeviceStr (virDomainChrDefPtr serial, ...@@ -62,6 +62,8 @@ qemuBuildChrDeviceStr (virDomainChrDefPtr serial,
/* With vlan == -1, use netdev syntax, else old hostnet */ /* With vlan == -1, use netdev syntax, else old hostnet */
char * qemuBuildHostNetStr(virDomainNetDefPtr net, char * qemuBuildHostNetStr(virDomainNetDefPtr net,
struct qemud_driver *driver,
virBitmapPtr qemuCaps,
char type_sep, char type_sep,
int vlan, int vlan,
const char *tapfd, const char *tapfd,
......
...@@ -695,12 +695,21 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, ...@@ -695,12 +695,21 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE || if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
actualType == VIR_DOMAIN_NET_TYPE_NETWORK) { actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn, driver, net, /*
priv->qemuCaps)) < 0) * If type=bridge then we attempt to allocate the tap fd here only if
goto cleanup; * running under a privilged user or -netdev bridge option is not
iface_connected = true; * supported.
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0) */
goto cleanup; if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
driver->privileged ||
(!qemuCapsGet (priv->qemuCaps, QEMU_CAPS_NETDEV_BRIDGE))) {
if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn, driver, net,
priv->qemuCaps)) < 0)
goto cleanup;
iface_connected = true;
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0)
goto cleanup;
}
} else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) { } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
if ((tapfd = qemuPhysIfaceConnect(vm->def, driver, net, if ((tapfd = qemuPhysIfaceConnect(vm->def, driver, net,
priv->qemuCaps, priv->qemuCaps,
...@@ -748,12 +757,14 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, ...@@ -748,12 +757,14 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (!(netstr = qemuBuildHostNetStr(net, ',', if (!(netstr = qemuBuildHostNetStr(net, driver, priv->qemuCaps,
-1, tapfd_name, vhostfd_name))) ',', -1, tapfd_name,
vhostfd_name)))
goto cleanup; goto cleanup;
} else { } else {
if (!(netstr = qemuBuildHostNetStr(net, ' ', if (!(netstr = qemuBuildHostNetStr(net, driver, priv->qemuCaps,
vlan, tapfd_name, vhostfd_name))) ' ', vlan, tapfd_name,
vhostfd_name)))
goto cleanup; goto cleanup;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册