[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, 5 months
[libvirt] [PATCH] vz: implementation of domainReboot callback
by Mikhail Feoktistov
---
src/vz/vz_driver.c | 8 ++++++++
src/vz/vz_sdk.c | 8 ++++++++
src/vz/vz_sdk.h | 1 +
3 files changed, 17 insertions(+)
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index 0a968b9..5f56eaf 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -923,6 +923,13 @@ static int vzDomainShutdown(virDomainPtr domain)
return prlsdkDomainChangeState(domain, prlsdkStop);
}
+static int vzDomainReboot(virDomainPtr domain,
+ unsigned int flags)
+{
+ flags = flags;
+ return prlsdkDomainChangeState(domain, prlsdkRestart);
+}
+
static int vzDomainIsActive(virDomainPtr domain)
{
virDomainObjPtr dom = NULL;
@@ -1486,6 +1493,7 @@ static virHypervisorDriver vzDriver = {
.domainShutdown = vzDomainShutdown, /* 0.10.0 */
.domainCreate = vzDomainCreate, /* 0.10.0 */
.domainCreateWithFlags = vzDomainCreateWithFlags, /* 1.2.10 */
+ .domainReboot = vzDomainReboot, /* 1.2.22 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
index 89c9e89..bf71e96 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -1831,6 +1831,14 @@ PRL_RESULT prlsdkSuspend(PRL_HANDLE sdkdom)
return waitJob(job);
}
+PRL_RESULT prlsdkRestart(PRL_HANDLE sdkdom)
+{
+ PRL_HANDLE job = PRL_INVALID_HANDLE;
+
+ job = PrlVm_Restart(sdkdom);
+ return waitJob(job);
+}
+
int
prlsdkDomainChangeStateLocked(vzConnPtr privconn,
virDomainObjPtr dom,
diff --git a/src/vz/vz_sdk.h b/src/vz/vz_sdk.h
index ebe4591..88ee7d9 100644
--- a/src/vz/vz_sdk.h
+++ b/src/vz/vz_sdk.h
@@ -41,6 +41,7 @@ PRL_RESULT prlsdkStop(PRL_HANDLE sdkdom);
PRL_RESULT prlsdkPause(PRL_HANDLE sdkdom);
PRL_RESULT prlsdkResume(PRL_HANDLE sdkdom);
PRL_RESULT prlsdkSuspend(PRL_HANDLE sdkdom);
+PRL_RESULT prlsdkRestart(PRL_HANDLE sdkdom);
typedef PRL_RESULT (*prlsdkChangeStateFunc)(PRL_HANDLE sdkdom);
int
--
1.8.3.1
9 years, 5 months
[libvirt] [PATCH v2 00/13] Introduce a virtlogd daemon
by Daniel P. Berrange
This is a v2 of:
https://www.redhat.com/archives/libvir-list/2015-November/msg00085.html
Currently we have stdout + stderr of QEMU guests setup to write
to a log file (eg /var/log/libvirt/qemu/$GUEST.log). This is nice
and simple, but it in fact opens the possibility of a malicious or
accidental denial of service, whereby QEMU can write logs of data
to stdio and thus fill up the host filesystem holding the log.
Although we have logrotate policy in place, this is only processed
once a day, so there is still a window where disk usage is not
constrained.
The only way to solve this is to not let QEMU directly write to
the log file, instead connect its stdio to a pipe and copy data
from the pipe to the real log file, performing file rollover
when it reaches a certain size.
If we do this, we need something to keep open the pipe for as long
as QEMU is running. This can't be libvirtd since we expect libvirtd
to be able to be stopped while QEMU is running. Thus we introduce a
new single-purpose daemon virtlogd whose job is exclusively to deal
with log file writing. This daemon has support for SIGUSR1 to tell
it to re-exec itself while keeping open the pipe to QEMU so it can
be safely upgraded while QEMU is running.
This series switches QEMU to use virtlogd by default, but in case
of problems we can revert back to the old direct file access by
setting 'stdio_handler = "file"' in /etc/libvirt/qemu.conf
This series is only the first step. The same problem exists when
character devices are told to use the file backend. There is a
further use case from OpenStack which that they want to allow
the use of both a TCP backend and a file backend at the same
time. The idea is that the serial port is to be used for an
interactive console, so needs the TCP backend support, but we
also want to be able to record all output on that serial port to
a file for logging purposes.
Thus, in a followup I will work on creating a new character
device backend "logd" that will use virtlogd to provide this
combined tcp+logfile facility for QEMU guests.
Changed in v2:
- Expanded the virrotatingfile module to handle reading from
files and querying position / seeking
- Fixed rollover when no backups are enabled
- Rollover early if we see a \n in the last 80 bytes
- Totally refactor the QEMU code dealing with log files
to remove all direct use of file handles and hide it
in a qemuDomainLogContextPtr. This ensures we can fetch
startup errors from virtlogd when needed
Daniel P. Berrange (13):
util: add APIs for reading/writing from/to rotating files
Import stripped down virtlockd code as basis of virtlogd
logging: introduce log handling protocol
logging: add client for virtlogd daemon
qemu: remove writing to QEMU log file for rename operation
qemu: unify code for reporting errors from QEMU log files
qemu: introduce a qemuDomainLogContext object
qemu: convert log file creation to use qemuDomainLogContextPtr
qemu: change qemuDomainTaint APIs to accept qemuDomainLogContextPtr
qemu: convert qemuLogOperation to take a qemuDomainLogContextPtr
qemu: convert process stop/attach to use qemuDomainLogContextPtr
qemu: convert monitor to use qemuDomainLogContextPtr indirectly
qemu: add support for sending QEMU stdout/stderr to virtlogd
.gitignore | 7 +
cfg.mk | 6 +-
include/libvirt/virterror.h | 1 +
libvirt.spec.in | 24 +-
po/POTFILES.in | 6 +
src/Makefile.am | 178 +++++-
src/libvirt_private.syms | 21 +
src/logging/log_daemon.c | 1207 ++++++++++++++++++++++++++++++++++++
src/logging/log_daemon.h | 45 ++
src/logging/log_daemon_config.c | 203 ++++++
src/logging/log_daemon_config.h | 50 ++
src/logging/log_daemon_dispatch.c | 143 +++++
src/logging/log_daemon_dispatch.h | 31 +
src/logging/log_handler.c | 524 ++++++++++++++++
src/logging/log_handler.h | 63 ++
src/logging/log_manager.c | 283 +++++++++
src/logging/log_manager.h | 61 ++
src/logging/log_protocol.x | 115 ++++
src/logging/test_virtlogd.aug.in | 12 +
src/logging/virtlogd.aug | 45 ++
src/logging/virtlogd.conf | 67 ++
src/logging/virtlogd.init.in | 94 +++
src/logging/virtlogd.pod.in | 162 +++++
src/logging/virtlogd.service.in | 17 +
src/logging/virtlogd.socket.in | 8 +
src/logging/virtlogd.sysconf | 3 +
src/qemu/libvirtd_qemu.aug | 1 +
src/qemu/qemu.conf | 15 +
src/qemu/qemu_conf.c | 18 +
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_domain.c | 353 +++++++----
src/qemu/qemu_domain.h | 37 +-
src/qemu/qemu_driver.c | 38 +-
src/qemu/qemu_migration.c | 2 +-
src/qemu/qemu_monitor.c | 89 +--
src/qemu/qemu_monitor.h | 8 +-
src/qemu/qemu_process.c | 320 ++++------
src/qemu/qemu_process.h | 2 -
src/qemu/test_libvirtd_qemu.aug.in | 1 +
src/util/virerror.c | 1 +
src/util/virrotatingfile.c | 608 ++++++++++++++++++
src/util/virrotatingfile.h | 62 ++
tests/Makefile.am | 6 +
tests/virrotatingfiletest.c | 698 +++++++++++++++++++++
44 files changed, 5180 insertions(+), 456 deletions(-)
create mode 100644 src/logging/log_daemon.c
create mode 100644 src/logging/log_daemon.h
create mode 100644 src/logging/log_daemon_config.c
create mode 100644 src/logging/log_daemon_config.h
create mode 100644 src/logging/log_daemon_dispatch.c
create mode 100644 src/logging/log_daemon_dispatch.h
create mode 100644 src/logging/log_handler.c
create mode 100644 src/logging/log_handler.h
create mode 100644 src/logging/log_manager.c
create mode 100644 src/logging/log_manager.h
create mode 100644 src/logging/log_protocol.x
create mode 100644 src/logging/test_virtlogd.aug.in
create mode 100644 src/logging/virtlogd.aug
create mode 100644 src/logging/virtlogd.conf
create mode 100644 src/logging/virtlogd.init.in
create mode 100644 src/logging/virtlogd.pod.in
create mode 100644 src/logging/virtlogd.service.in
create mode 100644 src/logging/virtlogd.socket.in
create mode 100644 src/logging/virtlogd.sysconf
create mode 100644 src/util/virrotatingfile.c
create mode 100644 src/util/virrotatingfile.h
create mode 100644 tests/virrotatingfiletest.c
--
2.5.0
9 years, 5 months
[libvirt] [PATCH] libvirt-domain: Fix typo in debug message
by Cole Robinson
---
Pushed as trivial
src/libvirt-domain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index de7eb04..7cfbe58 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -2015,7 +2015,7 @@ virDomainSetMemoryStatsPeriod(virDomainPtr domain, int period,
{
virConnectPtr conn;
- VIR_DOMAIN_DEBUG(domain, "peroid=%d, flags=%x", period, flags);
+ VIR_DOMAIN_DEBUG(domain, "period=%d, flags=%x", period, flags);
virResetLastError();
--
2.5.0
9 years, 5 months
[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, 5 months
[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, 5 months
[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, 5 months
[libvirt] How to disable kvm_steal_time feature
by Piotr Rybicki
Hi.
I would like to workaround a bug, when after live-migration of KVM
guest, there is a 100% steal time shown in guest.
I've read, that disabling 'kvm_steal_time' feature should workarund this
bug, but i can't find a way to disable it in libvirt's domain xml file.
Tried in <cpu> section:
<feature policy='disable' name='kvm_steal_time'/>
but that doesn't work.
Also, couldn't find any related information in libvirt documentation.
Google helps neither.
How can I disable this feature?
Thanks in advance.
Piotr Rybicki
9 years, 5 months
[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, 5 months