[lxc-devel] [PATCH 3/4] Rename utmp.c/utmp.h to lxcutmp.c/lxcutmp.h

Stéphane Graber stgraber at ubuntu.com
Fri Jan 11 17:29:54 UTC 2013


This avoids conflict with the system header utmp.h.

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 src/lxc/Makefile.am |   2 +-
 src/lxc/lxcutmp.c   | 421 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/lxcutmp.h   |  37 +++++
 src/lxc/start.c     |   2 +-
 src/lxc/utmp.c      | 421 ----------------------------------------------------
 src/lxc/utmp.h      |  37 -----
 6 files changed, 460 insertions(+), 460 deletions(-)
 create mode 100644 src/lxc/lxcutmp.c
 create mode 100644 src/lxc/lxcutmp.h
 delete mode 100644 src/lxc/utmp.c
 delete mode 100644 src/lxc/utmp.h

diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
index 693167a..5a28af4 100644
--- a/src/lxc/Makefile.am
+++ b/src/lxc/Makefile.am
@@ -68,7 +68,7 @@ liblxc_so_SOURCES = \
 	mainloop.c mainloop.h \
 	af_unix.c af_unix.h \
 	\
-	utmp.c utmp.h \
+	lxcutmp.c lxcutmp.h \
 	apparmor.c apparmor.h \
 	lxclock.h lxclock.c \
 	lxccontainer.c lxccontainer.h
diff --git a/src/lxc/lxcutmp.c b/src/lxc/lxcutmp.c
new file mode 100644
index 0000000..f32ed63
--- /dev/null
+++ b/src/lxc/lxcutmp.c
@@ -0,0 +1,421 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <dlezcano at fr.ibm.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#ifdef HAVE_UTMPX_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/inotify.h>
+#include <sys/ioctl.h>
+#include <sys/timerfd.h>
+
+#include "conf.h"
+#include "cgroup.h"
+#include "start.h"
+#include "mainloop.h"
+#include "lxc.h"
+#include "log.h"
+
+#ifndef __USE_GNU
+#define __USE_GNU
+#endif
+#include <utmpx.h>
+#undef __USE_GNU
+
+/* This file watches the /var/run/utmp file in the container
+ * (that should probably be configurable)
+ * We use inotify to put a watch on the /var/run directory for
+ * create and modify events. These can trigger a read of the
+ * utmp file looking for runlevel changes. If a runlevel change
+ * to reboot or halt states is detected, we set up an itimer to
+ * regularly check for the container shutdown, and reboot or halt
+ * as appropriate when we get down to 1 task remaining.
+ */
+
+lxc_log_define(lxc_utmp, lxc);
+
+struct lxc_utmp {
+	struct lxc_handler *handler;
+#define CONTAINER_STARTING  0
+#define CONTAINER_REBOOTING 1
+#define CONTAINER_HALTING   2
+#define CONTAINER_RUNNING   4
+	char container_state;
+	int timer_fd;
+	int prev_runlevel, curr_runlevel;
+};
+
+typedef void (*lxc_mainloop_timer_t) (void *data);
+
+static int utmp_get_runlevel(struct lxc_utmp *utmp_data);
+static int utmp_get_ntasks(struct lxc_handler *handler);
+static int utmp_shutdown_handler(int fd, void *data,
+				 struct lxc_epoll_descr *descr);
+static int lxc_utmp_add_timer(struct lxc_epoll_descr *descr,
+			      lxc_mainloop_callback_t callback, void *data);
+static int lxc_utmp_del_timer(struct lxc_epoll_descr *descr,
+			      struct lxc_utmp *utmp_data);
+
+static int utmp_handler(int fd, void *data, struct lxc_epoll_descr *descr)
+{
+	struct inotify_event *ie;
+	int size, ret, length;
+
+	struct lxc_utmp *utmp_data = (struct lxc_utmp *)data;
+
+	/*
+	 * we're monitoring a directory. ie->name is not included in
+	 * sizeof(struct inotify_event) if we don't read it all at once,
+	 * read gives us EINVAL, so we read and cast to struct ie
+	 */
+	char buffer[MAXPATHLEN];
+
+	if (ioctl(fd, FIONREAD, &size) < 0) {
+		SYSERROR("cannot determine the size of this notification");
+		return -1;
+	}
+
+	if (read(fd, buffer, size) < 0) {
+		SYSERROR("failed to read notification");
+		return -1;
+	}
+
+	ie = (struct inotify_event *)buffer;
+
+	if (ie->len <= 0) {
+
+		if (ie->mask & IN_UNMOUNT) {
+			DEBUG("watched directory removed");
+			goto out;
+		}
+
+		SYSERROR("inotify event with no name (mask %d)", ie->mask);
+		return -1;
+	}
+
+	ret = 0;
+
+	DEBUG("got inotify event %d for %s", ie->mask, ie->name);
+
+	length = (4 < ie->len) ? 4 : ie->len;
+
+	/* only care about utmp */
+
+	if (strncmp(ie->name, "utmp", length))
+		return 0;
+
+	if (ie->mask & (IN_MODIFY | IN_CREATE))
+		ret = utmp_get_runlevel(utmp_data);
+
+	if (ret < 0)
+		goto out;
+
+	/* container halting, from running or starting state */
+	if (utmp_data->curr_runlevel == '0'
+	    && ((utmp_data->container_state == CONTAINER_RUNNING)
+		|| (utmp_data->container_state == CONTAINER_STARTING))) {
+		utmp_data->container_state = CONTAINER_HALTING;
+		if (utmp_data->timer_fd == -1)
+			lxc_utmp_add_timer(descr, utmp_shutdown_handler, data);
+		DEBUG("Container halting");
+		goto out;
+	}
+
+	/* container rebooting, from running or starting state */
+	if (utmp_data->curr_runlevel == '6'
+	    && ((utmp_data->container_state == CONTAINER_RUNNING)
+		|| (utmp_data->container_state == CONTAINER_STARTING))) {
+		utmp_data->container_state = CONTAINER_REBOOTING;
+		if (utmp_data->timer_fd == -1)
+			lxc_utmp_add_timer(descr, utmp_shutdown_handler, data);
+		DEBUG("Container rebooting");
+		goto out;
+	}
+
+	/* normal operation, running, from starting state. */
+	if (utmp_data->curr_runlevel > '0' && utmp_data->curr_runlevel < '6') {
+		utmp_data->container_state = CONTAINER_RUNNING;
+		if (utmp_data->timer_fd > 0)
+			lxc_utmp_del_timer(descr, utmp_data);
+		DEBUG("Container running");
+		goto out;
+	}
+
+out:
+	return 0;
+}
+
+static int utmp_get_runlevel(struct lxc_utmp *utmp_data)
+{
+	struct utmpx *utmpx;
+	char path[MAXPATHLEN];
+	struct lxc_handler *handler = utmp_data->handler;
+
+	if (snprintf(path, MAXPATHLEN, "/proc/%d/root/run/utmp",
+		     handler->pid) > MAXPATHLEN) {
+		ERROR("path is too long");
+		return -1;
+	}
+
+	if (!access(path, F_OK) && !utmpxname(path))
+		goto utmp_ok;
+
+	if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run/utmp",
+		     handler->pid) > MAXPATHLEN) {
+		ERROR("path is too long");
+		return -1;
+	}
+
+	if (utmpxname(path)) {
+		SYSERROR("failed to 'utmpxname'");
+		return -1;
+	}
+
+utmp_ok:
+
+	setutxent();
+
+	while ((utmpx = getutxent())) {
+
+		if (utmpx->ut_type == RUN_LVL) {
+			utmp_data->prev_runlevel = utmpx->ut_pid / 256;
+			utmp_data->curr_runlevel = utmpx->ut_pid % 256;
+			DEBUG("utmp handler - run level is %c/%c",
+			      utmp_data->prev_runlevel,
+			      utmp_data->curr_runlevel);
+		}
+	}
+
+	endutxent();
+
+	return 0;
+}
+
+static int utmp_get_ntasks(struct lxc_handler *handler)
+{
+	int ntasks;
+
+	ntasks = lxc_cgroup_nrtasks(handler->name);
+
+	if (ntasks < 0) {
+		ERROR("failed to get the number of tasks");
+		return -1;
+	}
+
+	DEBUG("there are %d tasks running", ntasks);
+
+	return ntasks;
+}
+
+int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
+			  struct lxc_handler *handler)
+{
+	char path[MAXPATHLEN];
+	char path2[MAXPATHLEN];
+	int fd, wd;
+	struct lxc_utmp *utmp_data;
+
+	/* We set up a watch for the /var/run directory. We're only interested
+	 * in utmp at the moment, but want to watch for delete and create
+	 * events as well.
+	 */
+	if (snprintf(path, MAXPATHLEN, "/proc/%d/root/run",
+		     handler->pid) > MAXPATHLEN) {
+		ERROR("path is too long");
+		return -1;
+	}
+	if (snprintf(path2, MAXPATHLEN, "/proc/%d/root/run/utmp",
+		     handler->pid) > MAXPATHLEN) {
+		ERROR("path is too long");
+		return -1;
+	}
+	if (!access(path2, F_OK))
+		goto run_ok;
+
+	if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run",
+		     handler->pid) > MAXPATHLEN) {
+		ERROR("path is too long");
+		return -1;
+	}
+
+	if (access(path, F_OK)) {
+		WARN("'%s' not found", path);
+		return 0;
+	}
+
+run_ok:
+
+	utmp_data = (struct lxc_utmp *)malloc(sizeof(struct lxc_utmp));
+
+	if (NULL == utmp_data) {
+		SYSERROR("failed to malloc handler utmp_data");
+		return -1;
+	}
+
+	memset(utmp_data, 0, sizeof(struct lxc_utmp));
+
+	fd = inotify_init();
+	if (fd < 0) {
+		SYSERROR("failed to inotify_init");
+		goto out;
+	}
+
+	if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
+		SYSERROR("failed to set inotify fd to close-on-exec");
+		goto out_close;
+
+	}
+
+	wd = inotify_add_watch(fd, path, IN_MODIFY | IN_CREATE);
+	if (wd < 0) {
+		SYSERROR("failed to add watch for '%s'", path);
+		goto out_close;
+	}
+
+	utmp_data->handler = handler;
+	utmp_data->container_state = CONTAINER_STARTING;
+	utmp_data->timer_fd = -1;
+	utmp_data->prev_runlevel = 'N';
+	utmp_data->curr_runlevel = 'N';
+
+	if (lxc_mainloop_add_handler
+	    (descr, fd, utmp_handler, (void *)utmp_data)) {
+		SYSERROR("failed to add mainloop");
+		goto out_close;
+	}
+
+	DEBUG("Added '%s' to inotifywatch", path);
+
+	return 0;
+out_close:
+	close(fd);
+out:
+	free(utmp_data);
+	return -1;
+}
+
+static int utmp_shutdown_handler(int fd, void *data,
+				 struct lxc_epoll_descr *descr)
+{
+	int ntasks;
+	ssize_t nread;
+	struct lxc_utmp *utmp_data = (struct lxc_utmp *)data;
+	struct lxc_handler *handler = utmp_data->handler;
+	struct lxc_conf *conf = handler->conf;
+	uint64_t expirations;
+
+	/* read and clear notifications */
+	nread = read(fd, &expirations, sizeof(expirations));
+	if (nread < 0)
+		SYSERROR("Failed to read timer notification");
+
+	ntasks = utmp_get_ntasks(handler);
+
+	if (ntasks == 1 && (utmp_data->container_state == CONTAINER_HALTING)) {
+		INFO("container has shutdown");
+		/* shutdown timer */
+		lxc_utmp_del_timer(descr, utmp_data);
+
+		kill(handler->pid, SIGKILL);
+	}
+
+	if (ntasks == 1 && (utmp_data->container_state == CONTAINER_REBOOTING)) {
+		INFO("container has rebooted");
+		conf->reboot = 1;
+		/* shutdown timer */
+		lxc_utmp_del_timer(descr, utmp_data);
+		/* this seems a bit rough. */
+		kill(handler->pid, SIGKILL);
+	}
+	return 0;
+
+}
+
+int lxc_utmp_add_timer(struct lxc_epoll_descr *descr,
+		       lxc_mainloop_callback_t callback, void *data)
+{
+	int fd, result;
+	struct itimerspec timeout;
+	struct lxc_utmp *utmp_data = (struct lxc_utmp *)data;
+
+	fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
+	if (fd < 0) {
+		SYSERROR("failed to create timer");
+		return -1;
+	}
+
+	DEBUG("Setting up utmp shutdown timer");
+
+	/* set a one second timeout. Repeated. */
+	timeout.it_value.tv_sec = 1;
+	timeout.it_value.tv_nsec = 0;
+
+	timeout.it_interval.tv_sec = 1;
+	timeout.it_interval.tv_nsec = 0;
+
+	result = timerfd_settime(fd, 0, &timeout, NULL);
+
+	if (result < 0) {
+		SYSERROR("timerfd_settime:");
+		return -1;
+	}
+
+	if (lxc_mainloop_add_handler(descr, fd, callback, utmp_data)) {
+		SYSERROR("failed to add utmp timer to mainloop");
+		close(fd);
+		return -1;
+	}
+
+	utmp_data->timer_fd = fd;
+
+	return 0;
+}
+
+int lxc_utmp_del_timer(struct lxc_epoll_descr *descr,
+		       struct lxc_utmp *utmp_data)
+{
+	int result;
+
+	DEBUG("Clearing utmp shutdown timer");
+
+	result = lxc_mainloop_del_handler(descr, utmp_data->timer_fd);
+	if (result < 0)
+		SYSERROR("failed to del utmp timer from mainloop");
+
+	/* shutdown timer_fd */
+	close(utmp_data->timer_fd);
+	utmp_data->timer_fd = -1;
+
+	if (result < 0)
+		return -1;
+	else
+		return 0;
+}
+
+#endif
diff --git a/src/lxc/lxcutmp.h b/src/lxc/lxcutmp.h
new file mode 100644
index 0000000..ad4a8ab
--- /dev/null
+++ b/src/lxc/lxcutmp.h
@@ -0,0 +1,37 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <dlezcano at fr.ibm.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+struct lxc_handler;
+struct lxc_epoll_descr;
+
+#ifdef HAVE_UTMPX_H
+int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
+			  struct lxc_handler *handler);
+#else
+static inline int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
+			  struct lxc_handler *handler) {
+		return 0;
+}
+#endif
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 427cc70..a539703 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -125,7 +125,7 @@ int signalfd(int fd, const sigset_t *mask, int flags)
 #include "af_unix.h"
 #include "mainloop.h"
 #include "utils.h"
-#include "utmp.h"
+#include "lxcutmp.h"
 #include "monitor.h"
 #include "commands.h"
 #include "console.h"
diff --git a/src/lxc/utmp.c b/src/lxc/utmp.c
deleted file mode 100644
index f32ed63..0000000
--- a/src/lxc/utmp.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * lxc: linux Container library
- *
- * (C) Copyright IBM Corp. 2007, 2008
- *
- * Authors:
- * Daniel Lezcano <dlezcano at fr.ibm.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "config.h"
-
-#ifdef HAVE_UTMPX_H
-
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/inotify.h>
-#include <sys/ioctl.h>
-#include <sys/timerfd.h>
-
-#include "conf.h"
-#include "cgroup.h"
-#include "start.h"
-#include "mainloop.h"
-#include "lxc.h"
-#include "log.h"
-
-#ifndef __USE_GNU
-#define __USE_GNU
-#endif
-#include <utmpx.h>
-#undef __USE_GNU
-
-/* This file watches the /var/run/utmp file in the container
- * (that should probably be configurable)
- * We use inotify to put a watch on the /var/run directory for
- * create and modify events. These can trigger a read of the
- * utmp file looking for runlevel changes. If a runlevel change
- * to reboot or halt states is detected, we set up an itimer to
- * regularly check for the container shutdown, and reboot or halt
- * as appropriate when we get down to 1 task remaining.
- */
-
-lxc_log_define(lxc_utmp, lxc);
-
-struct lxc_utmp {
-	struct lxc_handler *handler;
-#define CONTAINER_STARTING  0
-#define CONTAINER_REBOOTING 1
-#define CONTAINER_HALTING   2
-#define CONTAINER_RUNNING   4
-	char container_state;
-	int timer_fd;
-	int prev_runlevel, curr_runlevel;
-};
-
-typedef void (*lxc_mainloop_timer_t) (void *data);
-
-static int utmp_get_runlevel(struct lxc_utmp *utmp_data);
-static int utmp_get_ntasks(struct lxc_handler *handler);
-static int utmp_shutdown_handler(int fd, void *data,
-				 struct lxc_epoll_descr *descr);
-static int lxc_utmp_add_timer(struct lxc_epoll_descr *descr,
-			      lxc_mainloop_callback_t callback, void *data);
-static int lxc_utmp_del_timer(struct lxc_epoll_descr *descr,
-			      struct lxc_utmp *utmp_data);
-
-static int utmp_handler(int fd, void *data, struct lxc_epoll_descr *descr)
-{
-	struct inotify_event *ie;
-	int size, ret, length;
-
-	struct lxc_utmp *utmp_data = (struct lxc_utmp *)data;
-
-	/*
-	 * we're monitoring a directory. ie->name is not included in
-	 * sizeof(struct inotify_event) if we don't read it all at once,
-	 * read gives us EINVAL, so we read and cast to struct ie
-	 */
-	char buffer[MAXPATHLEN];
-
-	if (ioctl(fd, FIONREAD, &size) < 0) {
-		SYSERROR("cannot determine the size of this notification");
-		return -1;
-	}
-
-	if (read(fd, buffer, size) < 0) {
-		SYSERROR("failed to read notification");
-		return -1;
-	}
-
-	ie = (struct inotify_event *)buffer;
-
-	if (ie->len <= 0) {
-
-		if (ie->mask & IN_UNMOUNT) {
-			DEBUG("watched directory removed");
-			goto out;
-		}
-
-		SYSERROR("inotify event with no name (mask %d)", ie->mask);
-		return -1;
-	}
-
-	ret = 0;
-
-	DEBUG("got inotify event %d for %s", ie->mask, ie->name);
-
-	length = (4 < ie->len) ? 4 : ie->len;
-
-	/* only care about utmp */
-
-	if (strncmp(ie->name, "utmp", length))
-		return 0;
-
-	if (ie->mask & (IN_MODIFY | IN_CREATE))
-		ret = utmp_get_runlevel(utmp_data);
-
-	if (ret < 0)
-		goto out;
-
-	/* container halting, from running or starting state */
-	if (utmp_data->curr_runlevel == '0'
-	    && ((utmp_data->container_state == CONTAINER_RUNNING)
-		|| (utmp_data->container_state == CONTAINER_STARTING))) {
-		utmp_data->container_state = CONTAINER_HALTING;
-		if (utmp_data->timer_fd == -1)
-			lxc_utmp_add_timer(descr, utmp_shutdown_handler, data);
-		DEBUG("Container halting");
-		goto out;
-	}
-
-	/* container rebooting, from running or starting state */
-	if (utmp_data->curr_runlevel == '6'
-	    && ((utmp_data->container_state == CONTAINER_RUNNING)
-		|| (utmp_data->container_state == CONTAINER_STARTING))) {
-		utmp_data->container_state = CONTAINER_REBOOTING;
-		if (utmp_data->timer_fd == -1)
-			lxc_utmp_add_timer(descr, utmp_shutdown_handler, data);
-		DEBUG("Container rebooting");
-		goto out;
-	}
-
-	/* normal operation, running, from starting state. */
-	if (utmp_data->curr_runlevel > '0' && utmp_data->curr_runlevel < '6') {
-		utmp_data->container_state = CONTAINER_RUNNING;
-		if (utmp_data->timer_fd > 0)
-			lxc_utmp_del_timer(descr, utmp_data);
-		DEBUG("Container running");
-		goto out;
-	}
-
-out:
-	return 0;
-}
-
-static int utmp_get_runlevel(struct lxc_utmp *utmp_data)
-{
-	struct utmpx *utmpx;
-	char path[MAXPATHLEN];
-	struct lxc_handler *handler = utmp_data->handler;
-
-	if (snprintf(path, MAXPATHLEN, "/proc/%d/root/run/utmp",
-		     handler->pid) > MAXPATHLEN) {
-		ERROR("path is too long");
-		return -1;
-	}
-
-	if (!access(path, F_OK) && !utmpxname(path))
-		goto utmp_ok;
-
-	if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run/utmp",
-		     handler->pid) > MAXPATHLEN) {
-		ERROR("path is too long");
-		return -1;
-	}
-
-	if (utmpxname(path)) {
-		SYSERROR("failed to 'utmpxname'");
-		return -1;
-	}
-
-utmp_ok:
-
-	setutxent();
-
-	while ((utmpx = getutxent())) {
-
-		if (utmpx->ut_type == RUN_LVL) {
-			utmp_data->prev_runlevel = utmpx->ut_pid / 256;
-			utmp_data->curr_runlevel = utmpx->ut_pid % 256;
-			DEBUG("utmp handler - run level is %c/%c",
-			      utmp_data->prev_runlevel,
-			      utmp_data->curr_runlevel);
-		}
-	}
-
-	endutxent();
-
-	return 0;
-}
-
-static int utmp_get_ntasks(struct lxc_handler *handler)
-{
-	int ntasks;
-
-	ntasks = lxc_cgroup_nrtasks(handler->name);
-
-	if (ntasks < 0) {
-		ERROR("failed to get the number of tasks");
-		return -1;
-	}
-
-	DEBUG("there are %d tasks running", ntasks);
-
-	return ntasks;
-}
-
-int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
-			  struct lxc_handler *handler)
-{
-	char path[MAXPATHLEN];
-	char path2[MAXPATHLEN];
-	int fd, wd;
-	struct lxc_utmp *utmp_data;
-
-	/* We set up a watch for the /var/run directory. We're only interested
-	 * in utmp at the moment, but want to watch for delete and create
-	 * events as well.
-	 */
-	if (snprintf(path, MAXPATHLEN, "/proc/%d/root/run",
-		     handler->pid) > MAXPATHLEN) {
-		ERROR("path is too long");
-		return -1;
-	}
-	if (snprintf(path2, MAXPATHLEN, "/proc/%d/root/run/utmp",
-		     handler->pid) > MAXPATHLEN) {
-		ERROR("path is too long");
-		return -1;
-	}
-	if (!access(path2, F_OK))
-		goto run_ok;
-
-	if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run",
-		     handler->pid) > MAXPATHLEN) {
-		ERROR("path is too long");
-		return -1;
-	}
-
-	if (access(path, F_OK)) {
-		WARN("'%s' not found", path);
-		return 0;
-	}
-
-run_ok:
-
-	utmp_data = (struct lxc_utmp *)malloc(sizeof(struct lxc_utmp));
-
-	if (NULL == utmp_data) {
-		SYSERROR("failed to malloc handler utmp_data");
-		return -1;
-	}
-
-	memset(utmp_data, 0, sizeof(struct lxc_utmp));
-
-	fd = inotify_init();
-	if (fd < 0) {
-		SYSERROR("failed to inotify_init");
-		goto out;
-	}
-
-	if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
-		SYSERROR("failed to set inotify fd to close-on-exec");
-		goto out_close;
-
-	}
-
-	wd = inotify_add_watch(fd, path, IN_MODIFY | IN_CREATE);
-	if (wd < 0) {
-		SYSERROR("failed to add watch for '%s'", path);
-		goto out_close;
-	}
-
-	utmp_data->handler = handler;
-	utmp_data->container_state = CONTAINER_STARTING;
-	utmp_data->timer_fd = -1;
-	utmp_data->prev_runlevel = 'N';
-	utmp_data->curr_runlevel = 'N';
-
-	if (lxc_mainloop_add_handler
-	    (descr, fd, utmp_handler, (void *)utmp_data)) {
-		SYSERROR("failed to add mainloop");
-		goto out_close;
-	}
-
-	DEBUG("Added '%s' to inotifywatch", path);
-
-	return 0;
-out_close:
-	close(fd);
-out:
-	free(utmp_data);
-	return -1;
-}
-
-static int utmp_shutdown_handler(int fd, void *data,
-				 struct lxc_epoll_descr *descr)
-{
-	int ntasks;
-	ssize_t nread;
-	struct lxc_utmp *utmp_data = (struct lxc_utmp *)data;
-	struct lxc_handler *handler = utmp_data->handler;
-	struct lxc_conf *conf = handler->conf;
-	uint64_t expirations;
-
-	/* read and clear notifications */
-	nread = read(fd, &expirations, sizeof(expirations));
-	if (nread < 0)
-		SYSERROR("Failed to read timer notification");
-
-	ntasks = utmp_get_ntasks(handler);
-
-	if (ntasks == 1 && (utmp_data->container_state == CONTAINER_HALTING)) {
-		INFO("container has shutdown");
-		/* shutdown timer */
-		lxc_utmp_del_timer(descr, utmp_data);
-
-		kill(handler->pid, SIGKILL);
-	}
-
-	if (ntasks == 1 && (utmp_data->container_state == CONTAINER_REBOOTING)) {
-		INFO("container has rebooted");
-		conf->reboot = 1;
-		/* shutdown timer */
-		lxc_utmp_del_timer(descr, utmp_data);
-		/* this seems a bit rough. */
-		kill(handler->pid, SIGKILL);
-	}
-	return 0;
-
-}
-
-int lxc_utmp_add_timer(struct lxc_epoll_descr *descr,
-		       lxc_mainloop_callback_t callback, void *data)
-{
-	int fd, result;
-	struct itimerspec timeout;
-	struct lxc_utmp *utmp_data = (struct lxc_utmp *)data;
-
-	fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
-	if (fd < 0) {
-		SYSERROR("failed to create timer");
-		return -1;
-	}
-
-	DEBUG("Setting up utmp shutdown timer");
-
-	/* set a one second timeout. Repeated. */
-	timeout.it_value.tv_sec = 1;
-	timeout.it_value.tv_nsec = 0;
-
-	timeout.it_interval.tv_sec = 1;
-	timeout.it_interval.tv_nsec = 0;
-
-	result = timerfd_settime(fd, 0, &timeout, NULL);
-
-	if (result < 0) {
-		SYSERROR("timerfd_settime:");
-		return -1;
-	}
-
-	if (lxc_mainloop_add_handler(descr, fd, callback, utmp_data)) {
-		SYSERROR("failed to add utmp timer to mainloop");
-		close(fd);
-		return -1;
-	}
-
-	utmp_data->timer_fd = fd;
-
-	return 0;
-}
-
-int lxc_utmp_del_timer(struct lxc_epoll_descr *descr,
-		       struct lxc_utmp *utmp_data)
-{
-	int result;
-
-	DEBUG("Clearing utmp shutdown timer");
-
-	result = lxc_mainloop_del_handler(descr, utmp_data->timer_fd);
-	if (result < 0)
-		SYSERROR("failed to del utmp timer from mainloop");
-
-	/* shutdown timer_fd */
-	close(utmp_data->timer_fd);
-	utmp_data->timer_fd = -1;
-
-	if (result < 0)
-		return -1;
-	else
-		return 0;
-}
-
-#endif
diff --git a/src/lxc/utmp.h b/src/lxc/utmp.h
deleted file mode 100644
index ad4a8ab..0000000
--- a/src/lxc/utmp.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * lxc: linux Container library
- *
- * (C) Copyright IBM Corp. 2007, 2008
- *
- * Authors:
- * Daniel Lezcano <dlezcano at fr.ibm.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "config.h"
-
-struct lxc_handler;
-struct lxc_epoll_descr;
-
-#ifdef HAVE_UTMPX_H
-int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
-			  struct lxc_handler *handler);
-#else
-static inline int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
-			  struct lxc_handler *handler) {
-		return 0;
-}
-#endif
-- 
1.8.0





More information about the lxc-devel mailing list