[libvirt] [PATCH] build: disable vbox on cygwin
by Eric Blake
Cygwin cannot build the vbox driver yet:
CC vbox/libvirt_driver_vbox_impl_la-vbox_glue.lo
In file included from vbox/vbox_glue.c:27:0:
vblox/vbox_XPCOMCGlue.c:63:3: error: #error "Port me"
# error "Port me"
^
In file included from vbox/vbox_XPCOMCGlue.c:45:0,
from vbox/vbox_glue.c:27:
vbox/vbox_XPCOMCGlue.c: In function 'tryLoadOne':
vbox/vbox_XPCOMCGlue.c:98:46: error: 'DYNLIB_NAME' undeclared (first use in this function)
if (virAsprintf(&name, "%s/%s", dir, DYNLIB_NAME) < 0)
^
./util/virstring.h:245:31: note: in definition of macro 'virAsprintf'
strp, __VA_ARGS__)
^
Rather than trying to figure out how to get dynamic loading of
vbox to work under cygwin (since I don't even have a working vbox
setup to test whether it works), I'm going to be lazy and just
default to not even trying vbox on cygwin.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Not technically a build-breaker, since I can './configure --without-vbox'
to work around it, so I'll wait for a review.
configure.ac | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index 75e95b7..2c34333 100644
--- a/configure.ac
+++ b/configure.ac
@@ -175,12 +175,13 @@ dnl are also linux specific. The "network" and storage_fs drivers are known
dnl to not work on MacOS X presently, so we also make a note if compiling
dnl for that
-with_linux=no with_osx=no with_freebsd=no
+with_linux=no with_osx=no with_freebsd=no with_win=no with_cygwin=no
case $host in
*-*-linux*) with_linux=yes ;;
*-*-darwin*) with_osx=yes ;;
*-*-freebsd*) with_freebsd=yes ;;
*-*-mingw* | *-*-msvc* ) with_win=yes ;;
+ *-*-cygwin*) with_cygwin=yes ;;
esac
if test $with_linux = no; then
@@ -192,9 +193,12 @@ if test $with_linux = no; then
fi
if test $with_freebsd = yes; then
- want_ifconfig=yes
+ want_ifconfig=yes
+ with_firewalld=no
+fi
- with_firewalld=no
+if test $with_cygwin = yes; then
+ with_vbox=no
fi
AM_CONDITIONAL([WITH_LINUX], [test "$with_linux" = "yes"])
--
2.4.3
8 years, 11 months
[libvirt] [PATCH] qemu_agent: fix deadlock in qemuProcessHandleAgentEOF
by Wang Yufei
We shutdown a VM A by qemu agent,meanwhile an agent EOF
of VM A happened, there's a chance that deadlock occurred:
qemuProcessHandleAgentEOF in main thread
A) priv->agent = NULL; //A happened before B
//deadlock when we get agent lock which's held by worker thread
qemuAgentClose(agent);
qemuDomainObjExitAgent called by qemuDomainShutdownFlags in worker thread
B) hasRefs = virObjectUnref(priv->agent); //priv->agent is NULL, return false
if (hasRefs)
virObjectUnlock(priv->agent); //agent lock will not be released here
So I close agent first, then set priv->agent NULL to fix the deadlock.
Signed-off-by: Wang Yufei <james.wangyufei(a)huawei.com>
Reviewed-by: Ren Guannan <renguannan(a)huawei.com>
---
src/qemu/qemu_process.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index f2586a1..8c9622e 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -150,11 +150,10 @@ qemuProcessHandleAgentEOF(qemuAgentPtr agent,
goto unlock;
}
+ qemuAgentClose(agent);
priv->agent = NULL;
virObjectUnlock(vm);
-
- qemuAgentClose(agent);
return;
unlock:
--
1.8.3.4
8 years, 11 months
[libvirt] [PATCH] storage: Ignore block devices that fail format detection
by John Ferlan
https://bugzilla.redhat.com/show_bug.cgi?id=1276198
Prior to commit id '98322052' failure to saferead the block device would
cause an error to be logged and the device to be skipped while attempting
to discover/create a stable target path for a new LUN (NPIV).
This was because virStorageBackendSCSIFindLUs ignored errors from
processLU and virStorageBackendSCSINewLun.
Ignoring the failure allowed a multipath device with an "active" and
"ghost" to be present on the host with the "ghost" block device being
ignored. This patch will return a -2 to the caller indicating the desire
to ignore the block device since it cannot be used directly rather than
fail the pool startup.
Additionally, it was found during some debugging that it was possible
for the virStorageBackendDetectBlockVolFormatFD to not detect a format,
which while not a probably - we probably should at least add some sort
of warning message.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/storage/storage_backend.c | 4 ++++
src/storage/storage_backend_scsi.c | 7 ++++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index a375fe0..2de606f 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -1393,6 +1393,10 @@ virStorageBackendDetectBlockVolFormatFD(virStorageSourcePtr target,
}
}
+ if (target->format == VIR_STORAGE_POOL_DISK_UNKNOWN)
+ VIR_WARN("cannot determine the target format for '%s'",
+ target->path);
+
return 0;
}
diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c
index a593a2b..d60473d 100644
--- a/src/storage/storage_backend_scsi.c
+++ b/src/storage/storage_backend_scsi.c
@@ -224,9 +224,14 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr pool,
goto cleanup;
}
+ /* Failing to process the format is not fatal - we'll just skip
+ * this volume.
+ */
if (virStorageBackendUpdateVolInfo(vol, true,
- VIR_STORAGE_VOL_OPEN_DEFAULT) < 0)
+ VIR_STORAGE_VOL_OPEN_DEFAULT) < 0) {
+ retval = -2;
goto cleanup;
+ }
if (!(vol->key = virStorageBackendSCSISerial(vol->target.path)))
goto cleanup;
--
2.1.0
9 years
[libvirt] [PATCH] Use correct pci addresses during device-detach
by Nitesh_Konkar
From: Nitesh_Konkar <niteshkonkar(a)in.ibm.com>
The attach-device on live and persistent copies can be done independently.
Thus devices can end up having different pci addresses in live and persistent
copies. The detach device should try to detach the device from their respective
addresses instead of using the same from live/persistent.
Signed-off-by:nitkon12@linux.vnet.ibm.com
---
src/driver-nodedev.h | 1 +
src/qemu/qemu_driver.c | 25 ++++++++++---------------
2 files changed, 11 insertions(+), 15 deletions(-)
diff --git a/src/driver-nodedev.h b/src/driver-nodedev.h
index e846612..dea79bd 100644
--- a/src/driver-nodedev.h
+++ b/src/driver-nodedev.h
@@ -59,6 +59,7 @@ typedef char *
typedef char *
(*virDrvNodeDeviceGetParent)(virNodeDevicePtr dev);
+
typedef int
(*virDrvNodeDeviceNumOfCaps)(virNodeDevicePtr dev);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f133b45..6fd58c2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8708,23 +8708,12 @@ static int qemuDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
!(flags & VIR_DOMAIN_AFFECT_LIVE))
parse_flags |= VIR_DOMAIN_DEF_PARSE_INACTIVE;
- dev = dev_copy = virDomainDeviceDefParse(xml, vm->def,
+ dev_copy = virDomainDeviceDefParse(xml, vm->def,
caps, driver->xmlopt,
parse_flags);
- if (dev == NULL)
+ if (dev_copy == NULL)
goto endjob;
- if (flags & VIR_DOMAIN_AFFECT_CONFIG &&
- flags & VIR_DOMAIN_AFFECT_LIVE) {
- /* If we are affecting both CONFIG and LIVE
- * create a deep copy of device as adding
- * to CONFIG takes one instance.
- */
- dev_copy = virDomainDeviceDefCopy(dev, vm->def, caps, driver->xmlopt);
- if (!dev_copy)
- goto endjob;
- }
-
if (priv->qemuCaps)
qemuCaps = virObjectRef(priv->qemuCaps);
else if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, vm->def->emulator)))
@@ -8736,6 +8725,13 @@ static int qemuDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
if (!vmdef)
goto endjob;
+ dev = virDomainDeviceDefParse(xml, vmdef,
+ caps, driver->xmlopt,
+ parse_flags);
+ if (!dev)
+ goto endjob;
+
+
if (virDomainDefCompatibleDevice(vmdef, dev,
VIR_DOMAIN_DEVICE_ACTION_DETACH) < 0)
goto endjob;
@@ -8777,8 +8773,7 @@ static int qemuDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
cleanup:
virObjectUnref(qemuCaps);
virDomainDefFree(vmdef);
- if (dev != dev_copy)
- virDomainDeviceDefFree(dev_copy);
+ virDomainDeviceDefFree(dev_copy);
virDomainDeviceDefFree(dev);
virDomainObjEndAPI(&vm);
virObjectUnref(caps);
--
2.4.0
9 years
[libvirt] [[PATCH v6] autocreate tap device for VIR_DOMAIN_NET_TYPE_ETHERNET] autocreate tap device for VIR_DOMAIN_NET_TYPE_ETHERNET
by Vasiliy Tolstov
If a user specify ehernet device create it via libvirt and run
script if it provided. After this commit user does not need to
run external script to create tap device or add root to qemu
process.
Signed-off-by: Vasiliy Tolstov <v.tolstov(a)selfip.ru>
---
src/qemu/qemu_command.c | 142 +++++++++++++++++++++++++++++++-----------------
src/qemu/qemu_hotplug.c | 13 ++---
src/qemu/qemu_process.c | 6 ++
3 files changed, 101 insertions(+), 60 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3886b4f..6d26d28 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -332,10 +332,39 @@ static int qemuCreateInBridgePortWithHelper(virQEMUDriverConfigPtr cfg,
return *tapfd < 0 ? -1 : 0;
}
+/**
+ * qemuExecuteEthernetScript:
+ * @ifname: the interface name
+ * @script: the script name
+ *
+ * This function executes script for new tap device created by libvirt.
+ * Returns 0 in case of success or -1 on failure
+ */
+static int
+qemuExecuteEthernetScript(const char *ifname, const char *script)
+{
+ virCommandPtr cmd;
+ int ret;
+
+ cmd = virCommandNew(script);
+ virCommandAddArgFormat(cmd, "%s", ifname);
+ virCommandClearCaps(cmd);
+#ifdef CAP_NET_ADMIN
+ virCommandAllowCap(cmd, CAP_NET_ADMIN);
+#endif
+ virCommandAddEnvPassCommon(cmd);
+
+ ret = virCommandRun(cmd, NULL);
+
+ virCommandFree(cmd);
+ return ret;
+}
+
/* qemuNetworkIfaceConnect - *only* called if actualType is
- * VIR_DOMAIN_NET_TYPE_NETWORK or VIR_DOMAIN_NET_TYPE_BRIDGE (i.e. if
- * the connection is made with a tap device connecting to a bridge
- * device)
+ * VIR_DOMAIN_NET_TYPE_NETWORK, VIR_DOMAIN_NET_TYPE_BRIDGE
+ * VIR_DOMAIN_NET_TYPE_ETHERNET (i.e. if the connection is
+ * made with a tap device connecting to a bridge device or
+ * use plain tap device)
*/
int
qemuNetworkIfaceConnect(virDomainDefPtr def,
@@ -351,6 +380,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
bool template_ifname = false;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
const char *tunpath = "/dev/net/tun";
+ virMacAddr tapmac;
if (net->backend.tap) {
tunpath = net->backend.tap;
@@ -361,11 +391,6 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
}
}
- if (!(brname = virDomainNetGetActualBridgeName(net))) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing bridge name"));
- goto cleanup;
- }
-
if (!net->ifname ||
STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) ||
strchr(net->ifname, '%')) {
@@ -381,40 +406,65 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
tap_create_flags |= VIR_NETDEV_TAP_CREATE_VNET_HDR;
}
- if (cfg->privileged) {
- if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac,
- def->uuid, tunpath, tapfd, *tapfdSize,
- virDomainNetGetActualVirtPortProfile(net),
- virDomainNetGetActualVlan(net),
- tap_create_flags) < 0) {
+ if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_ETHERNET) {
+ if (virNetDevTapCreate(&net->ifname, tunpath, tapfd, *tapfdSize,
+ tap_create_flags) < 0) {
virDomainAuditNetDevice(def, net, tunpath, false);
goto cleanup;
}
- if (virDomainNetGetActualBridgeMACTableManager(net)
- == VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LIBVIRT) {
- /* libvirt is managing the FDB of the bridge this device
- * is attaching to, so we need to turn off learning and
- * unicast_flood on the device to prevent the kernel from
- * adding any FDB entries for it. We will add add an fdb
- * entry ourselves (during qemuInterfaceStartDevices(),
- * using the MAC address from the interface config.
- */
- if (virNetDevBridgePortSetLearning(brname, net->ifname, false) < 0)
- goto cleanup;
- if (virNetDevBridgePortSetUnicastFlood(brname, net->ifname, false) < 0)
+ virMacAddrSet(&tapmac, &net->mac);
+
+ if (virNetDevSetMAC(net->ifname, &tapmac) < 0)
+ goto cleanup;
+
+ if (virNetDevSetOnline(net->ifname, true) < 0)
+ goto cleanup;
+
+ if (net->script) {
+ if (qemuExecuteEthernetScript(net->ifname, net->script) < 0)
goto cleanup;
}
} else {
- if (qemuCreateInBridgePortWithHelper(cfg, brname,
- &net->ifname,
- tapfd, tap_create_flags) < 0) {
- virDomainAuditNetDevice(def, net, tunpath, false);
+ if (!(brname = virDomainNetGetActualBridgeName(net))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing bridge name"));
goto cleanup;
}
- /* qemuCreateInBridgePortWithHelper can only create a single FD */
- if (*tapfdSize > 1) {
- VIR_WARN("Ignoring multiqueue network request");
- *tapfdSize = 1;
+
+ if (cfg->privileged) {
+ if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac,
+ def->uuid, tunpath, tapfd, *tapfdSize,
+ virDomainNetGetActualVirtPortProfile(net),
+ virDomainNetGetActualVlan(net),
+ tap_create_flags) < 0) {
+ virDomainAuditNetDevice(def, net, tunpath, false);
+ goto cleanup;
+ }
+ if (virDomainNetGetActualBridgeMACTableManager(net)
+ == VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LIBVIRT) {
+ /* libvirt is managing the FDB of the bridge this device
+ * is attaching to, so we need to turn off learning and
+ * unicast_flood on the device to prevent the kernel from
+ * adding any FDB entries for it. We will add add an fdb
+ * entry ourselves (during qemuInterfaceStartDevices(),
+ * using the MAC address from the interface config.
+ */
+ if (virNetDevBridgePortSetLearning(brname, net->ifname, false) < 0)
+ goto cleanup;
+ if (virNetDevBridgePortSetUnicastFlood(brname, net->ifname, false) < 0)
+ goto cleanup;
+ }
+ } else {
+ if (qemuCreateInBridgePortWithHelper(cfg, brname,
+ &net->ifname,
+ tapfd, tap_create_flags) < 0) {
+ virDomainAuditNetDevice(def, net, tunpath, false);
+ goto cleanup;
+ }
+ /* qemuCreateInBridgePortWithHelper can only create a single FD */
+ if (*tapfdSize > 1) {
+ VIR_WARN("Ignoring multiqueue network request");
+ *tapfdSize = 1;
+ }
}
}
@@ -5221,6 +5271,7 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_NETWORK:
case VIR_DOMAIN_NET_TYPE_DIRECT:
+ case VIR_DOMAIN_NET_TYPE_ETHERNET:
virBufferAsprintf(&buf, "tap%c", type_sep);
/* for one tapfd 'fd=' shall be used,
* for more than one 'fds=' is the right choice */
@@ -5238,20 +5289,6 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
is_tap = true;
break;
- case VIR_DOMAIN_NET_TYPE_ETHERNET:
- virBufferAddLit(&buf, "tap");
- if (net->ifname) {
- virBufferAsprintf(&buf, "%cifname=%s", type_sep, net->ifname);
- type_sep = ',';
- }
- if (net->script) {
- virBufferAsprintf(&buf, "%cscript=%s", type_sep,
- net->script);
- type_sep = ',';
- }
- is_tap = true;
- break;
-
case VIR_DOMAIN_NET_TYPE_CLIENT:
virBufferAsprintf(&buf, "socket%cconnect=%s:%d",
type_sep,
@@ -8226,7 +8263,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
/* Currently nothing besides TAP devices supports multiqueue. */
if (net->driver.virtio.queues > 0 &&
!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
- actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
+ actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Multiqueue network is not supported for: %s"),
virDomainNetTypeToString(actualType));
@@ -8235,7 +8273,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
if (net->backend.tap &&
!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
- actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
+ actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Custom tap device path is not supported for: %s"),
virDomainNetTypeToString(actualType));
@@ -8245,7 +8284,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
cfg = virQEMUDriverGetConfig(driver);
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
- actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
+ actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
tapfdSize = net->driver.virtio.queues;
if (!tapfdSize)
tapfdSize = 1;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index cc86a3b..21ea3fd 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -908,7 +908,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
/* Currently nothing besides TAP devices supports multiqueue. */
if (net->driver.virtio.queues > 0 &&
!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
- actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
+ actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Multiqueue network is not supported for: %s"),
virDomainNetTypeToString(actualType));
@@ -916,7 +917,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
}
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
- actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
+ actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
tapfdSize = vhostfdSize = net->driver.virtio.queues;
if (!tapfdSize)
tapfdSize = vhostfdSize = 1;
@@ -947,13 +949,6 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
iface_connected = true;
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
goto cleanup;
- } else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
- vhostfdSize = 1;
- if (VIR_ALLOC(vhostfd) < 0)
- goto cleanup;
- *vhostfd = -1;
- if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
- goto cleanup;
}
/* Set device online immediately */
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 64ee049..d866e44 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5205,6 +5205,12 @@ void qemuProcessStop(virQEMUDriverPtr driver,
cfg->stateDir));
VIR_FREE(net->ifname);
break;
+ case VIR_DOMAIN_NET_TYPE_ETHERNET:
+ if (net->ifname) {
+ ignore_value(virNetDevTapDelete(net->ifname, net->backend.tap));
+ VIR_FREE(net->ifname);
+ }
+ break;
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_NETWORK:
#ifdef VIR_NETDEV_TAP_REQUIRE_MANUAL_CLEANUP
--
2.3.3
9 years
[libvirt] [PATCH] [RFC] virSetUIDGID: Don't leak supplementary groups
by Richard Weinberger
The LXC driver uses virSetUIDGID() to become UID/GID 0.
It passes an empty groups list to virSetUIDGID()
to get rid of all supplementary groups from the host side.
But virSetUIDGID() calls setgroups() only if the supplied list
is larger than 0.
This leads to a container root with unrelated supplementary groups.
In most cases this issue is unoticed as libvirtd runs as UID/GID 0
without any supplementary groups.
Signed-off-by: Richard Weinberger <richard(a)nod.at>
---
I've marked that patch as RFC as I'm not sure if all users of virSetUIDGID()
expect this behavior too.
Thanks,
//richard
---
src/util/virutil.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/util/virutil.c b/src/util/virutil.c
index cddc78a..ea697a3 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -1103,7 +1103,7 @@ virSetUIDGID(uid_t uid, gid_t gid, gid_t *groups ATTRIBUTE_UNUSED,
}
# if HAVE_SETGROUPS
- if (ngroups && setgroups(ngroups, groups) < 0) {
+ if (setgroups(ngroups, groups) < 0) {
virReportSystemError(errno, "%s",
_("cannot set supplemental groups"));
return -1;
--
2.4.2
9 years
[libvirt] [PATCH] lxc: Bind mount container TTYs
by Richard Weinberger
Instead of creating symlinks, bind mount the devices to
/dev/pts/XY.
Using bind mounts it is no longer needed to add pts devices
to files like /dev/securetty.
Signed-off-by: Richard Weinberger <richard(a)nod.at>
---
src/lxc/lxc_container.c | 38 +++++++++++++++++++++-----------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 7d531e2..ea76370 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -1141,6 +1141,20 @@ static int lxcContainerMountFSDevPTS(virDomainDefPtr def,
return ret;
}
+static int lxcContainerBindMountDevice(const char *src, const char *dst)
+{
+ if (virFileTouch(dst, 0666) < 0)
+ return -1;
+
+ if (mount(src, dst, "none", MS_BIND, NULL) < 0) {
+ virReportSystemError(errno, _("Failed to bind %s on to %s"), src,
+ dst);
+ return -1;
+ }
+
+ return 0;
+}
+
static int lxcContainerSetupDevices(char **ttyPaths, size_t nttyPaths)
{
size_t i;
@@ -1164,34 +1178,24 @@ static int lxcContainerSetupDevices(char **ttyPaths, size_t nttyPaths)
}
/* We have private devpts capability, so bind that */
- if (virFileTouch("/dev/ptmx", 0666) < 0)
+ if (lxcContainerBindMountDevice("/dev/pts/ptmx", "/dev/ptmx") < 0)
return -1;
- if (mount("/dev/pts/ptmx", "/dev/ptmx", "ptmx", MS_BIND, NULL) < 0) {
- virReportSystemError(errno, "%s",
- _("Failed to bind /dev/pts/ptmx on to /dev/ptmx"));
- return -1;
- }
-
for (i = 0; i < nttyPaths; i++) {
char *tty;
if (virAsprintf(&tty, "/dev/tty%zu", i+1) < 0)
return -1;
- if (symlink(ttyPaths[i], tty) < 0) {
- virReportSystemError(errno,
- _("Failed to symlink %s to %s"),
- ttyPaths[i], tty);
- VIR_FREE(tty);
+
+ if (lxcContainerBindMountDevice(ttyPaths[i], tty) < 0) {
return -1;
+ VIR_FREE(tty);
}
+
VIR_FREE(tty);
+
if (i == 0 &&
- symlink(ttyPaths[i], "/dev/console") < 0) {
- virReportSystemError(errno,
- _("Failed to symlink %s to /dev/console"),
- ttyPaths[i]);
+ lxcContainerBindMountDevice(ttyPaths[i], "/dev/console") < 0)
return -1;
- }
}
return 0;
}
--
2.4.2
9 years
[libvirt] [PATCH] lxc: Don't make container's TTY a controlling TTY
by Richard Weinberger
Userspace does not expect that the initial console
is a controlling TTY. systemd can deal with that, others not.
On sysv init distros getty will fail to spawn a controlling on
/dev/console or /dev/tty1. Which will cause to whole container
to reboot upon ctrl-c.
This patch changes the behavior of libvirt to match the kernel
behavior where the initial TTY is also not controlling.
The only user visible change should be that a container with
bash as PID 1 would complain. But this matches exactly the kernel
be behavior with intit=/bin/bash.
To get a controlling TTY for bash just run "setsid /bin/bash".
Signed-off-by: Richard Weinberger <richard(a)nod.at>
---
src/lxc/lxc_container.c | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 11e9514..7d531e2 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -278,18 +278,6 @@ static int lxcContainerSetupFDs(int *ttyfd,
"as the FDs are about to be closed for exec of "
"the container init process");
- if (setsid() < 0) {
- virReportSystemError(errno, "%s",
- _("setsid failed"));
- goto cleanup;
- }
-
- if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) {
- virReportSystemError(errno, "%s",
- _("ioctl(TIOCSCTTY) failed"));
- goto cleanup;
- }
-
if (dup2(*ttyfd, STDIN_FILENO) < 0) {
virReportSystemError(errno, "%s",
_("dup2(stdin) failed"));
@@ -2210,7 +2198,7 @@ static int lxcContainerChild(void *data)
VIR_DEBUG("Container TTY path: %s", ttyPath);
- ttyfd = open(ttyPath, O_RDWR|O_NOCTTY);
+ ttyfd = open(ttyPath, O_RDWR);
if (ttyfd < 0) {
virReportSystemError(errno,
_("Failed to open tty %s"),
--
2.4.2
9 years
[libvirt] [PATCH v2] locking: Add io_timeout to sanlock
by Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1251190
So, if domain loses access to storage, sanlock tries to kill it
after some timeout. So far, the default is 80 seconds. But for
some scenarios this might not be enough. We should allow users to
adjust the timeout according to their needs.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
diff to v2:
- Check if the new sanlock API is accessible. If not, forbid setting timeout in
the config file.
m4/virt-sanlock.m4 | 7 +++++++
src/locking/libvirt_sanlock.aug | 1 +
src/locking/lock_driver_sanlock.c | 15 +++++++++++++++
src/locking/sanlock.conf | 7 +++++++
src/locking/test_libvirt_sanlock.aug.in | 1 +
5 files changed, 31 insertions(+)
diff --git a/m4/virt-sanlock.m4 b/m4/virt-sanlock.m4
index c7c0186..d2a607d 100644
--- a/m4/virt-sanlock.m4
+++ b/m4/virt-sanlock.m4
@@ -46,6 +46,13 @@ AC_DEFUN([LIBVIRT_CHECK_SANLOCK],[
[whether sanlock supports sanlock_inq_lockspace])
fi
+ AC_CHECK_LIB([sanlock_client], [sanlock_add_lockspace_timeout],
+ [sanlock_add_lockspace_timeout=yes], [sanlock_add_lockspace_timeout=no])
+ if test "x$sanlock_add_lockspace_timeout" = "xyes" ; then
+ AC_DEFINE_UNQUOTED([HAVE_SANLOCK_ADD_LOCKSPACE_TIMEOUT], 1,
+ [whether Sanlock supports sanlock_add_lockspace_timeout])
+ fi
+
CPPFLAGS="$old_cppflags"
LIBS="$old_libs"
fi
diff --git a/src/locking/libvirt_sanlock.aug b/src/locking/libvirt_sanlock.aug
index a78a444..8843590 100644
--- a/src/locking/libvirt_sanlock.aug
+++ b/src/locking/libvirt_sanlock.aug
@@ -22,6 +22,7 @@ module Libvirt_sanlock =
| int_entry "host_id"
| bool_entry "require_lease_for_disks"
| bool_entry "ignore_readonly_and_shared_disks"
+ | int_entry "io_timeout"
| str_entry "user"
| str_entry "group"
let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
diff --git a/src/locking/lock_driver_sanlock.c b/src/locking/lock_driver_sanlock.c
index e052875..dbda915 100644
--- a/src/locking/lock_driver_sanlock.c
+++ b/src/locking/lock_driver_sanlock.c
@@ -73,6 +73,7 @@ struct _virLockManagerSanlockDriver {
int hostID;
bool autoDiskLease;
char *autoDiskLeasePath;
+ unsigned int io_timeout;
/* under which permissions does sanlock run */
uid_t user;
@@ -151,6 +152,10 @@ static int virLockManagerSanlockLoadConfig(const char *configFile)
else
driver->requireLeaseForDisks = !driver->autoDiskLease;
+ p = virConfGetValue(conf, "io_timeout");
+ CHECK_TYPE("io_timeout", VIR_CONF_ULONG);
+ if (p) driver->io_timeout = p->l;
+
p = virConfGetValue(conf, "user");
CHECK_TYPE("user", VIR_CONF_STRING);
if (p) {
@@ -338,7 +343,16 @@ static int virLockManagerSanlockSetupLockspace(void)
* or we can fallback to polling.
*/
retry:
+#ifdef HAVE_SANLOCK_ADD_LOCKSPACE_TIMEOUT
+ if ((rv = sanlock_add_lockspace_timeout(&ls, 0, driver->io_timeout)) < 0) {
+#else
+ if (driver->io_timeout) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("unable to use io_timeout with this version of sanlock"));
+ goto error;
+ }
if ((rv = sanlock_add_lockspace(&ls, 0)) < 0) {
+#endif
if (-rv == EINPROGRESS && --retries) {
#ifdef HAVE_SANLOCK_INQ_LOCKSPACE
/* we have this function which blocks until lockspace change the
@@ -404,6 +418,7 @@ static int virLockManagerSanlockInit(unsigned int version,
driver->requireLeaseForDisks = true;
driver->hostID = 0;
driver->autoDiskLease = false;
+ driver->io_timeout = 0;
driver->user = (uid_t) -1;
driver->group = (gid_t) -1;
if (VIR_STRDUP(driver->autoDiskLeasePath, LOCALSTATEDIR "/lib/libvirt/sanlock") < 0) {
diff --git a/src/locking/sanlock.conf b/src/locking/sanlock.conf
index e5566ef..3a1a51c 100644
--- a/src/locking/sanlock.conf
+++ b/src/locking/sanlock.conf
@@ -54,6 +54,13 @@
#require_lease_for_disks = 1
#
+# Sanlock is able to kill qemu processes on IO timeout. By its internal
+# implementation, the current default is 80 seconds. If you need to adjust
+# the value change the following variable. Value of zero means use the
+# default sanlock timeout.
+#io_timeout = 0
+
+#
# The combination of user and group under which the sanlock
# daemon runs. Libvirt will chown created files (like
# content of disk_lease_dir) to make sure sanlock daemon can
diff --git a/src/locking/test_libvirt_sanlock.aug.in b/src/locking/test_libvirt_sanlock.aug.in
index ef98ea6..7f66f81 100644
--- a/src/locking/test_libvirt_sanlock.aug.in
+++ b/src/locking/test_libvirt_sanlock.aug.in
@@ -6,5 +6,6 @@ module Test_libvirt_sanlock =
{ "disk_lease_dir" = "/var/lib/libvirt/sanlock" }
{ "host_id" = "1" }
{ "require_lease_for_disks" = "1" }
+{ "io_timeout" = "0" }
{ "user" = "root" }
{ "group" = "root" }
--
2.4.10
9 years