[lxc-devel] [lxcfs/master] lxcfs: allow users to switch between virtualization and non-virtualization mode

brauner on Github lxc-bot at linuxcontainers.org
Sat Mar 14 17:39:22 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 1118 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200314/702ee402/attachment.bin>
-------------- next part --------------
From a2a6f3f9c77ffd8920ed9de9fef9a0385d8a2863 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Sat, 14 Mar 2020 18:25:46 +0100
Subject: [PATCH 1/2] bindings: allow users to switch between virtualization
 and non-virtualization mode

When LXCFS has a bug and provides wrong or inconsistent values user
often want to turn off virtualization until we have figured out a fix
and rollout an upgrade to reload the shared library. Allow them to
toggle between virtualization mode and non-virtualization mode by
sending SIGUSR2 to lxcfs:

 Kernel supports pidfds
 api_extensions:
 - cgroups
 - sys_cpu_online
 - proc_cpuinfo
 - proc_diskstats
 - proc_loadavg
 - proc_meminfo
 - proc_stat
 - proc_swaps
 - proc_uptime
 - shared_pidns
 - cpuview_daemon
 - loadavg_daemon
 - pidfds
 Switched into non-virtualization mode
 Switched into virtualization mode
 Switched into non-virtualization mode
 Switched into virtualization mode
 Switched into non-virtualization mode

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/bindings.c | 45 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/src/bindings.c b/src/bindings.c
index fb3dcb7..80fb948 100644
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -50,11 +50,12 @@
 #include "utils.h"
 
 static bool can_use_pidfd;
-static bool reload_successful;
+
+static volatile sig_atomic_t reload_successful;
 
 bool liblxcfs_functional(void)
 {
-	return reload_successful;
+	return reload_successful != 0;
 }
 
 /* Define pivot_root() if missing from the C library */
@@ -721,6 +722,39 @@ static bool cgfs_setup_controllers(void)
 	return true;
 }
 
+static void sigusr2_handler(int signo, siginfo_t *info, void *extra)
+{
+	if (reload_successful) {
+		reload_successful = 0;
+
+		/* write() is async signal safe */
+		(void)write(STDERR_FILENO,
+			    "Switched into non-virtualization mode\n",
+			    STRLITERALLEN("Switched into non-virtualization mode\n"));
+	} else {
+		reload_successful = 1;
+
+		/* write() is async signal safe */
+		(void)write(STDERR_FILENO, "Switched into virtualization mode\n",
+			    STRLITERALLEN("Switched into virtualization mode\n"));
+	}
+}
+
+static int set_sigusr2_handler(void)
+{
+	int ret;
+	struct sigaction action = {
+		.sa_flags = SA_SIGINFO,
+		.sa_sigaction = sigusr2_handler,
+	};
+
+	ret = sigaction(SIGUSR2, &action, NULL);
+	if (ret)
+		return log_error_errno(-1, errno, "Failed to set SIGUSR2 signal handler");
+
+	return 0;
+}
+
 static void __attribute__((constructor)) lxcfs_init(void)
 {
 	__do_close_prot_errno int init_ns = -EBADF, root_fd = -EBADF,
@@ -788,11 +822,14 @@ static void __attribute__((constructor)) lxcfs_init(void)
 	else if (fchdir(root_fd) < 0)
 		lxcfs_info("%s - Failed to change to root directory", strerror(errno));
 
-	reload_successful = true;
+	if (set_sigusr2_handler())
+		goto broken_upgrade;
+
+	reload_successful = 1;
 	return;
 
 broken_upgrade:
-	reload_successful = false;
+	reload_successful = 0;
 	lxcfs_info("Failed to run constructor %s to reload liblxcfs", __func__);
 }
 

From 3860bd92afbe11282e8b12ba02117e2c4f81678b Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Sat, 14 Mar 2020 18:35:45 +0100
Subject: [PATCH 2/2] test_proc: add SIGUSR2 virtualization switch tests

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 tests/main.sh   | 6 +++---
 tests/test_proc | 6 ++++++
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/tests/main.sh b/tests/main.sh
index 2b49510..944f610 100755
--- a/tests/main.sh
+++ b/tests/main.sh
@@ -8,7 +8,7 @@ set -eu
 
 # Run lxcfs testsuite
 export LXCFSDIR=$(mktemp -d)
-pidfile=$(mktemp)
+export PIDFILE=$(mktemp)
 
 cmdline=$(realpath $0)
 dirname=$(dirname ${cmdline})
@@ -26,7 +26,7 @@ cleanup() {
 		umount -l ${LXCFSDIR}
 		rmdir ${LXCFSDIR}
 	fi
-	rm -f ${pidfile}
+	rm -f ${PIDFILE}
 	if [ ${FAILED} -eq 1 ]; then
 		echo "=> FAILED at $TESTCASE"
 		exit 1
@@ -45,7 +45,7 @@ if [ -x ${lxcfs} ]; then
 		export LD_LIBRARY_PATH="${topdir}/src/.libs/"
 	fi
 	echo "=> Spawning ${lxcfs} ${LXCFSDIR}"
-	${lxcfs} -p ${pidfile} ${LXCFSDIR} &
+	${lxcfs} -p ${PIDFILE} ${LXCFSDIR} &
 	p=$!
 else
 	pidof lxcfs
diff --git a/tests/test_proc b/tests/test_proc
index fbb38d4..97ed1dd 100755
--- a/tests/test_proc
+++ b/tests/test_proc
@@ -49,6 +49,12 @@ echo "==> Testing /proc/cpuinfo"
 [ "$(grep "^processor" ${LXCFSDIR}/proc/cpuinfo | wc -l)" = "1" ]
 grep -q "^processor.*0$" ${LXCFSDIR}/proc/cpuinfo || grep -q "^processor 0:.*" ${LXCFSDIR}/proc/cpuinfo
 
+echo "==> Switching to non-virtualization mode"
+kill -USR2 $(cat ${PIDFILE})
+[ "$(grep "^processor" ${LXCFSDIR}/proc/cpuinfo | wc -l)" = "$(grep "^processor" /proc/cpuinfo | wc -l)" ]
+echo "==> Switching to virtualization mode"
+kill -USR2 $(cat ${PIDFILE})
+
 # Test stat
 echo "==> Testing /proc/stat"
 [ "$(grep "^cpu" ${LXCFSDIR}/proc/stat | wc -l)" = "2" ]


More information about the lxc-devel mailing list