[lxc-devel] [lxc/master] Improve the dhclient hook for OCI compat

3XX0 on Github lxc-bot at linuxcontainers.org
Fri Dec 8 09:31:11 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 1060 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20171208/165de649/attachment.bin>
-------------- next part --------------
From 706254dddffe8213c3db13e05f6ada1ebbb4c70a Mon Sep 17 00:00:00 2001
From: Jonathan Calmels <jcalmels at nvidia.com>
Date: Thu, 7 Dec 2017 22:04:36 -0800
Subject: [PATCH 1/3] hooks: dhclient hook improvements

- Merge dhclient-start and dhclient-stop into a single hook.
- Wait for a lease before returning from the hook.
- Generate a logfile when LXC log level is either DEBUG or TRACE.
- Rely on namespace file descriptors for the stop hook.
- Use settings from /<sysconf>/lxc/dhclient.conf if available.
- Attempt to cleanup if dhclient fails to shutdown properly.

Signed-off-by: Jonathan Calmels <jcalmels at nvidia.com>
---
 .gitignore              |  3 +--
 configure.ac            |  3 +--
 hooks/Makefile.am       |  3 +--
 hooks/dhclient-start.in | 13 ----------
 hooks/dhclient-stop.in  | 15 -----------
 hooks/dhclient.in       | 68 +++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 71 insertions(+), 34 deletions(-)
 delete mode 100755 hooks/dhclient-start.in
 delete mode 100755 hooks/dhclient-stop.in
 create mode 100755 hooks/dhclient.in

diff --git a/.gitignore b/.gitignore
index 8385ef793..f4b74c762 100644
--- a/.gitignore
+++ b/.gitignore
@@ -136,8 +136,7 @@ doc/manpage.refs
 doc/api/html/*
 
 hooks/unmount-namespace
-hooks/dhclient-start
-hooks/dhclient-stop
+hooks/dhclient
 
 m4/
 
diff --git a/configure.ac b/configure.ac
index 6bde154db..bf92f08db 100644
--- a/configure.ac
+++ b/configure.ac
@@ -889,8 +889,7 @@ AC_CONFIG_FILES([
 	doc/ko/see_also.sgml
 
 	hooks/Makefile
-	hooks/dhclient-start
-	hooks/dhclient-stop
+	hooks/dhclient
 
 	templates/Makefile
 	templates/lxc-alpine
diff --git a/hooks/Makefile.am b/hooks/Makefile.am
index b8b8f532d..98786ea8c 100644
--- a/hooks/Makefile.am
+++ b/hooks/Makefile.am
@@ -6,8 +6,7 @@ hooks_SCRIPTS = \
 	mountecryptfsroot \
 	ubuntu-cloud-prep \
 	dhclient-script \
-	dhclient-start \
-	dhclient-stop \
+	dhclient \
 	squid-deb-proxy-client
 
 binhooks_PROGRAMS = \
diff --git a/hooks/dhclient-start.in b/hooks/dhclient-start.in
deleted file mode 100755
index 29a33645d..000000000
--- a/hooks/dhclient-start.in
+++ /dev/null
@@ -1,13 +0,0 @@
-#! /bin/bash
-
-set -e
-
-LXC_HOOK_DIR="@LXCHOOKDIR@"
-
-rootfs="${LXC_ROOTFS_PATH##*:}"
-pidfile="${rootfs%/*}/dhclient.pid"
-
-mkdir -p "${rootfs}/var/lib/dhclient"
-
-nsenter -u -U -n -t "${LXC_PID}" -- \
-  /sbin/dhclient -nw -1 -pf ${pidfile} -lf ${rootfs}/var/lib/dhclient/dhclient.leases -e ROOTFS=${rootfs} -sf ${LXC_HOOK_DIR}/dhclient-script
diff --git a/hooks/dhclient-stop.in b/hooks/dhclient-stop.in
deleted file mode 100755
index 63998aee5..000000000
--- a/hooks/dhclient-stop.in
+++ /dev/null
@@ -1,15 +0,0 @@
-#! /bin/bash
-
-set -e
-
-LXC_HOOK_DIR="@LXCHOOKDIR@"
-
-rootfs="${LXC_ROOTFS_PATH##*:}"
-pidfile="${rootfs%/*}/dhclient.pid"
-
-# XXX Stop hook namespace arguments are wrong for some reason, those are the host namespaces not the container ones.
-# Retrieve the namespaces from the dhclient pidfile instead.
-nsenter -u -U -n -t $(< ${pidfile}) -- \
-  /sbin/dhclient -r -pf ${pidfile} -lf ${rootfs}/var/lib/dhclient/dhclient.leases -e ROOTFS=${rootfs} -sf ${LXC_HOOK_DIR}/dhclient-script
-
-rm -f ${pidfile}
diff --git a/hooks/dhclient.in b/hooks/dhclient.in
new file mode 100755
index 000000000..6845e79d4
--- /dev/null
+++ b/hooks/dhclient.in
@@ -0,0 +1,68 @@
+#! /bin/bash
+
+set -eu
+
+LXC_DHCP_SCRIPT="@LXCHOOKDIR@/dhclient-script"
+LXC_DHCP_CONFIG="@SYSCONFDIR@/lxc/dhclient.conf"
+
+rootfs_path="${LXC_ROOTFS_PATH#*:}"
+hookdir="${rootfs_path/%rootfs/hook}"
+
+conffile_arg=""
+if [ -e "${LXC_DHCP_CONFIG}" ]; then
+    conffile_arg="-cf ${LXC_DHCP_CONFIG}"
+fi
+
+debugfile="/dev/null"
+if [ "${LXC_LOG_LEVEL}" = "DEBUG" ] || [ "${LXC_LOG_LEVEL}" = "TRACE" ]; then
+    debugfile="${hookdir}/dhclient.log"
+    echo "Writing dhclient log at ${debugfile}." >&2
+fi
+
+pidfile="${hookdir}/dhclient.pid"
+leasefile="${hookdir}/dhclient.leases"
+
+usage() {
+    echo "Usage: ${0##*/} <name> lxc {start-host|stop}"
+}
+
+dhclient_start() {
+    mkdir -p "${hookdir}"
+
+    echo "Starting DHCP client and acquiring a lease..." >> "${debugfile}"
+    nsenter --uts --user --net --target "${LXC_PID}" -- \
+      /sbin/dhclient -1 ${conffile_arg} -pf "${pidfile}" -lf "${leasefile}" -e "ROOTFS=${rootfs_path}" -sf "${LXC_DHCP_SCRIPT}" -v >> "${debugfile}" 2>&1
+}
+
+dhclient_stop() {
+    # We can't use LXC_PID here since the container process has exited,
+    # use the namespace file descriptors in the hook arguments instead.
+    ns_args=("")
+    for arg in "$@"; do
+        case "${arg}" in
+            uts:* | user:* | net:*) ns_args+=("--${arg/:/=}") ;;
+            *) ;;
+        esac
+    done
+
+    echo "Stopping DHCP client and releasing leases..." >> "${debugfile}"
+    nsenter ${ns_args[@]} -- \
+      /sbin/dhclient -r ${conffile_arg} -pf "${pidfile}" -lf "${leasefile}" -e "ROOTFS=${rootfs_path}" -sf "${LXC_DHCP_SCRIPT}" -v >> "${debugfile}" 2>&1
+
+    # dhclient could fail to release the lease and shutdown, try to cleanup after ourselves just in case.
+    nsenter ${ns_args[@]} -- \
+      /bin/sh -c 'pkill --ns $$ --nslist net -f "^/sbin/dhclient"' || true
+    rm -f "${pidfile}"
+}
+
+if [ "$#" -lt 3 ] || [ "$2" != "lxc" ]; then
+    echo "Error: not running through LXC." >&2
+    exit 1
+fi
+case "$3" in
+    start-host) shift 3; dhclient_start $@;;
+    stop) shift 3; dhclient_stop $@;;
+    *) usage; exit 1;;
+esac
+
+exit 0

From 09fb08163d3626265dfaa2e7f25423abca99b15d Mon Sep 17 00:00:00 2001
From: Jonathan Calmels <jcalmels at nvidia.com>
Date: Thu, 7 Dec 2017 22:15:10 -0800
Subject: [PATCH 2/3] lxc-net: add LXC_DHCP_PING boolean option

Excerpt from dnsmasq(8):
By default, the DHCP server will attempt to ensure that an address in not
in use before allocating it to a host. It does this by sending an ICMP echo
request (aka "ping") to the address in question. If it gets a reply, then the
address must already be in use, and another is tried. This flag disables this check.

This is useful if one expects all the containers to get an IP address
from the LXC authoritative DHCP server and wants to speed up the process
of getting a lease.

Signed-off-by: Jonathan Calmels <jcalmels at nvidia.com>
---
 config/init/common/lxc-net.in | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/config/init/common/lxc-net.in b/config/init/common/lxc-net.in
index a9683f29d..ddbd4aaab 100644
--- a/config/init/common/lxc-net.in
+++ b/config/init/common/lxc-net.in
@@ -16,6 +16,7 @@ LXC_NETWORK="10.0.3.0/24"
 LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"
 LXC_DHCP_MAX="253"
 LXC_DHCP_CONFILE=""
+LXC_DHCP_PING="true"
 LXC_DOMAIN=""
 
 LXC_IPV6_ADDR=""
@@ -127,7 +128,12 @@ start() {
         fi
     done
 
-    dnsmasq $LXC_DHCP_CONFILE_ARG $LXC_DOMAIN_ARG -u ${DNSMASQ_USER} \
+    LXC_DHCP_PING_ARG=""
+    if [ "x$LXC_DHCP_PING" = "xfalse" ]; then
+        LXC_DHCP_PING_ARG="--no-ping"
+    fi
+
+    dnsmasq $LXC_DHCP_CONFILE_ARG $LXC_DOMAIN_ARG $LXC_DHCP_PING_ARG -u ${DNSMASQ_USER} \
             --strict-order --bind-interfaces --pid-file="${varrun}"/dnsmasq.pid \
             --listen-address ${LXC_ADDR} --dhcp-range ${LXC_DHCP_RANGE} \
             --dhcp-lease-max=${LXC_DHCP_MAX} --dhcp-no-override \

From e5a23c036ae4171fa70499a97d3ac4dcd86e86df Mon Sep 17 00:00:00 2001
From: Jonathan Calmels <jcalmels at nvidia.com>
Date: Thu, 7 Dec 2017 22:24:48 -0800
Subject: [PATCH 3/3] lxc-oci: read configuration from oci.common.conf if
 available

Signed-off-by: Jonathan Calmels <jcalmels at nvidia.com>
---
 templates/lxc-oci.in | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/templates/lxc-oci.in b/templates/lxc-oci.in
index 5bd8edbf4..a4c0097c3 100755
--- a/templates/lxc-oci.in
+++ b/templates/lxc-oci.in
@@ -279,6 +279,10 @@ if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ] && [ -e "${LXC_TEMP
     echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/userns.conf" >> "${LXC_CONF_FILE}"
 fi
 
+if [ -e "${LXC_TEMPLATE_CONFIG}/oci.common.conf" ]; then
+    echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/oci.common.conf" >> "${LXC_CONF_FILE}"
+fi
+
 echo "lxc.uts.name = ${LXC_NAME}" >> "${LXC_CONF_FILE}"
 # set the hostname
 cat <<EOF > ${LXC_ROOTFS}/etc/hostname


More information about the lxc-devel mailing list