]> git.proxmox.com Git - mirror_lxc.git/commitdiff
Added C++ compatibility, change to libtool, improve monitoring
authordlezcano <dlezcano>
Tue, 2 Sep 2008 09:48:12 +0000 (09:48 +0000)
committerdlezcano <dlezcano>
Tue, 2 Sep 2008 09:48:12 +0000 (09:48 +0000)
26 files changed:
configure.in
lxc.spec.in
src/liblxc/Makefile.am
src/liblxc/create.c
src/liblxc/destroy.c
src/liblxc/execute.c
src/liblxc/lock.c
src/liblxc/lxc.h
src/liblxc/lxc_cgroup.c
src/liblxc/lxc_list.h
src/liblxc/lxc_state.c
src/liblxc/lxc_state.h
src/liblxc/monitor.c
src/liblxc/start.c
src/lxc/Makefile.am
src/lxc/lxc_config.c [new file with mode: 0644]
src/lxc/lxc_config.h [new file with mode: 0644]
src/lxc/lxc_create.c
src/lxc/lxc_monitor.c
src/lxc/lxc_priority.c
src/lxc/lxc_state.c
test/Makefile.am
test/confile.c
test/lxc_low_monitor.c [new file with mode: 0644]
test/lxc_monitor.c
test/lxc_state.c

index f376a6455036c8a3a5704945f7be6f359c6de2d0..7b1322c4ca6566c449d2d9d2825e78e2d0554e58 100644 (file)
@@ -11,6 +11,7 @@ AC_CANONICAL_HOST
 AC_PROG_RANLIB
 AM_PROG_CC_C_O
 AC_GNU_SOURCE
+AC_PROG_LIBTOOL
 AC_CHECK_HEADERS([linux/netlink.h linux/genetlink.h],, AC_MSG_ERROR([netlink headers not found]), [[]])
 AC_PROG_GCC_TRADITIONAL
 
index ff340d097d444f2a0c021adb7c568ef79123dedf..773f731126a98cf64c7b5afe71e0be922fb6a6db 100644 (file)
@@ -82,6 +82,7 @@ rm -rf %{buildroot}
 %files
 %defattr(-,root,root)
 %{_sysconfdir}/%{name}/*
+%{_libdir}/*.so*
 %{_bindir}/*
 
 %files devel
@@ -89,6 +90,10 @@ rm -rf %{buildroot}
 %{_includedir}/%{name}/*
 %{_libdir}/*.a
 
+%post devel
+ln -sf %{_includedir}/%{name} %{_includedir}/liblxc
+
+
 %changelog
 * Sun Aug 3 2008 Daniel Lezcano <dlezcano@fr.ibm.com>
 - Initial RPM release.
index eeebd0864a5a89ddcffd6c16e75c0ee70f9745f4..bb548d56cbb6e4b5f1c4dcbe98ce4b8a28e8206e 100644 (file)
@@ -1,4 +1,4 @@
-lib_LIBRARIES = liblxc.a
+lib_LTLIBRARIES = liblxc.la
 pkginclude_HEADERS = \
                lxc.h \
                lxc_cgroup.h \
@@ -10,16 +10,15 @@ pkginclude_HEADERS = \
                lxc_state.h \
                lxc_utils.h
 
-liblxc_a_SOURCES = \
+liblxc_la_SOURCES = \
        create.c \
        destroy.c \
        start.c \
        stop.c \
        execute.c \
-       monitor.c \
+       monitor.c monitor.h \
        kill.c \
        freezer.c \
-       lxc_state.c lxc_state.h \
        lxc_cgroup.c lxc_cgroup.h \
        lxc.h \
        lxc_utils.h \
@@ -34,3 +33,5 @@ liblxc_a_SOURCES = \
         nl.c nl.h \
         rtnl.c rtnl.h \
         genl.c genl.h
+
+liblxc_la_LDFLAGS = -release @PACKAGE_VERSION@
\ No newline at end of file
index dc3b05faa3ff8322f8b3cd16bda3c5058e92e910..2891eba655f31eb88bd3af2f833cd820efe30dd6 100644 (file)
@@ -116,7 +116,7 @@ int lxc_create(const char *name, struct lxc_conf *conf)
                goto err;
        }
 
-       if (mkstate(name)) {
+       if (lxc_mkstate(name)) {
                lxc_log_error("failed to create the state file for %s", name);
                goto err;
        }
@@ -139,7 +139,7 @@ out:
 err_state:
        lxc_unconfigure(name);
 
-       if (rmstate(name))
+       if (lxc_rmstate(name))
                lxc_log_error("failed to remove state file for %s", name);
 err:
        if (remove_lxc_directory(name))
index fb08da29bfc7c1b325fc1279ce7c7f8b4f9913c4..266a5ae04ee86dd6c357a1a31d0ce93e01a60620 100644 (file)
@@ -94,10 +94,12 @@ int lxc_destroy(const char *name)
                goto out;
        }
 
-       if (rmstate(name)) {
+       if (lxc_rmstate(name)) {
                lxc_log_error("failed to remove state file for %s", name);
                goto out_lock;
        }
+       
+       lxc_monitor_cleanup(name);
 
        if (lxc_unconfigure(name)) {
                lxc_log_error("failed to cleanup %s", name);
index 207ad3005b064ec3945885b7b7dbd9794bb84e8a..4bfcbcc30eb337eba95f4afb9c57a5ecdbace3a5 100644 (file)
@@ -64,10 +64,8 @@ int lxc_execute(const char *name, int argc, char *argv[],
                return -1;
        }
 
-       fcntl(lock, F_SETFD, FD_CLOEXEC);
-
        if (lxc_setstate(name, STARTING)) {
-               lxc_log_error("failed to set state %s", state2str(STARTING));
+               lxc_log_error("failed to set state %s", lxc_state2str(STARTING));
                goto out;
        }
 
@@ -117,10 +115,12 @@ int lxc_execute(const char *name, int argc, char *argv[],
                                lxc_log_error("failed to setup the container");
                                goto error;
                        }
+
                        if (mount("proc", "/proc", "proc", 0, NULL)) {
-                               lxc_log_error("failed to mount '/proc'");
+                               lxc_log_syserror("failed to mount '/proc'");
                                goto error;
                        }
+
                        if (mount("sysfs", "/sys", "sysfs", 0, NULL)) {
                                lxc_log_syserror("failed to mount '/sys'");
                                /* continue: non fatal error until sysfs not per
@@ -213,7 +213,7 @@ int lxc_execute(const char *name, int argc, char *argv[],
                lxc_log_warning("cgroupfs not found: cgroup disabled");
 
        if (lxc_setstate(name, RUNNING)) {
-               lxc_log_error("failed to set state to %s", state2str(RUNNING));
+               lxc_log_error("failed to set state to %s", lxc_state2str(RUNNING));
                goto err_state_failed;
        }
 
@@ -226,7 +226,7 @@ wait_again:
        }
 
        if (lxc_setstate(name, STOPPING))
-               lxc_log_error("failed to set state %s", state2str(STOPPING));
+               lxc_log_error("failed to set state %s", lxc_state2str(STOPPING));
 
        if (clone_flags & CLONE_NEWNET && conf_destroy_network(name))
                lxc_log_error("failed to destroy the network");
@@ -234,7 +234,7 @@ wait_again:
        err = 0;
 out:
        if (lxc_setstate(name, STOPPED))
-               lxc_log_error("failed to set state %s", state2str(STOPPED));
+               lxc_log_error("failed to set state %s", lxc_state2str(STOPPED));
 
        lxc_unlink_nsgroup(name);
        unlink(init);
@@ -257,7 +257,7 @@ err_pipe_read:
 err_open:
 err_waitpid_failed:
        if (lxc_setstate(name, ABORTING))
-               lxc_log_error("failed to set state %s", state2str(STOPPED));
+               lxc_log_error("failed to set state %s", lxc_state2str(STOPPED));
 
        kill(pid, SIGKILL);
 err_fork_ns:
index 26b5c170bae652bd6bd9be70ced1643d3bfc068a..70bdcfc2331f6e908eab2901c41982ec637f2a49 100644 (file)
@@ -42,6 +42,8 @@ int lxc_get_lock(const char *name)
                goto out;
        }
 
+       fcntl(fd, F_SETFD, FD_CLOEXEC);
+
        if (flock(fd, LOCK_EX|LOCK_NB)) {
                ret = errno == EWOULDBLOCK ? 0 : -errno;
                close(fd);
index 0369a68330a47cfc74a70f3da696469a7de259b3..d1f027f661ab5628d332387ad2b5f2330b847ba7 100644 (file)
 #ifndef __lxc_h
 #define __lxc_h
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  Following code is for liblxc.
 
  liblxc/lxc.h will contain exports of liblxc
  **/
 
-#include <lxc_state.h>
-#include <lxc_list.h>
-#include <lxc_conf.h>
-#include <lxc_log.h>
-#include <lxc_lock.h>
-#include <lxc_cgroup.h>
-#include <lxc_namespace.h>
-#include <lxc_utils.h>
+#include <liblxc/lxc_state.h>
+#include <liblxc/lxc_list.h>
+#include <liblxc/lxc_conf.h>
+#include <liblxc/lxc_log.h>
+#include <liblxc/lxc_lock.h>
+#include <liblxc/lxc_cgroup.h>
+#include <liblxc/lxc_namespace.h>
+#include <liblxc/lxc_utils.h>
 
 #define LXCPATH "/var/lxc"
 #define MAXPIDLEN 20
@@ -104,12 +108,37 @@ extern int lxc_stop(const char *name);
  * is changed, a state data is send through a file descriptor passed to
  * the function with output_fd.
  * The function will block until the container is destroyed.
- * @name : the name of the contaier
+ * @name : the name of the container
  * @output_fd : the file descriptor where to send the states
  * Returns 0 on success, < 0 otherwise
  */
 extern int lxc_monitor(const char *name, int output_fd);
 
+/*
+ * Open the monitoring mechanism for a specific container
+ * The function will return an fd corresponding to the events
+ * @name  : the name of the container
+ * Returns a file descriptor on success, < 0 otherwise
+ */
+extern int lxc_monitor_open(const char *name);
+
+/*
+ * Read the state of the container if this one has changed
+ * The function will block until there is an event available
+ * @fd : the file descriptor provided by lxc_monitor_open
+ * @state : the variable which will be filled with the state
+ * Returns 0 if the monitored container has exited, > 0 if
+ * data was readen, < 0 otherwise
+ */
+extern int lxc_monitor_read(int fd, lxc_state_t *state);
+
+/*
+ * Close the fd associated with the monitoring
+ * @fd : the file descriptor provided by lxc_monitor_open
+ * Returns 0 on success, < 0 otherwise
+ */
+extern int lxc_monitor_close(int fd);
+
 /*
  * Show the console of the container.
  * @name : the name of container
@@ -220,4 +249,8 @@ extern int lxc_cgroup_get_cpuset(const char *name, long *cpumask,
  */
 extern int lxc_cgroup_get_cpu_usage(const char *name, long long *usage);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
index dc185a08dc0706e9ae2a04aa177024ac911d1cb5..238f285237ffe03aba1a8e1c1bed4e13268738cd 100644 (file)
@@ -101,7 +101,7 @@ int lxc_unlink_nsgroup(const char *name)
        return ret;
 }
 
-int lxc_set_priority(const char *name, int priority)
+int lxc_cgroup_set_priority(const char *name, int priority)
 {
        int fd;
        char *path = NULL, *prio = NULL;
@@ -129,7 +129,7 @@ out:
        return 0;
 }
 
-int lxc_get_priority(const char *name, int *priority)
+int lxc_cgroup_get_priority(const char *name, int *priority)
 {
        int fd, ret = -1;
        char *path, prio[MAXPRIOLEN];
index c6727e95bb2410cb0c6c0d9e0eaf630a96e76dee..45c04fb1f5b8ecd81f48f11de1da544e69516b41 100644 (file)
@@ -35,13 +35,13 @@ static inline int lxc_list_empty(struct lxc_list *list)
        return list == list->next;
 }
 
-static inline void lxc_list_add(struct lxc_list *list, struct lxc_list *new)
+static inline void lxc_list_add(struct lxc_list *head, struct lxc_list *list)
 {
-       struct lxc_list *next = list->next;
-       next->prev = new;
-       new->next = next;
-       new->prev = list;
-       list->next = new;
+       struct lxc_list *next = head->next;
+       next->prev = list;
+       list->next = next;
+       list->prev = head;
+       head->next = list;
 }
 
 static inline void lxc_list_del(struct lxc_list *list)
index 86e4d9f6ba68014f9bfa00c59af547fe970ecafc..462298dc1a8a4195df7b7c35f907b29d2b2555f3 100644 (file)
 #include <sys/file.h>
 
 #include <lxc.h>
+#include "monitor.h"
 
 static char *strstate[] = {
        "STOPPED", "STARTING", "RUNNING", "STOPPING",
        "ABORTING", "FREEZING", "FROZEN",
 };
 
-const char *state2str(lxc_state_t state)
+const char *lxc_state2str(lxc_state_t state)
 {
        if (state < STOPPED || state > MAX_STATE - 1)
                return NULL;
        return strstate[state];
 }
 
-lxc_state_t str2state(const char *state)
+lxc_state_t lxc_str2state(const char *state)
 {
        int i, len;
        len = sizeof(strstate)/sizeof(strstate[0]);
@@ -59,7 +60,7 @@ int lxc_setstate(const char *name, lxc_state_t state)
 {
        int fd, err;
        char file[MAXPATHLEN];
-       const char *str = state2str(state);
+       const char *str = lxc_state2str(state);
 
        if (!str)
                return -1;
@@ -91,6 +92,8 @@ int lxc_setstate(const char *name, lxc_state_t state)
 out:
        close(fd);
 
+       lxc_monitor_send_state(name, state);
+
        /* let the event to be propagated, crappy but that works,
         * otherwise the events will be folded into only one event,
         * and I want to have them to be one by one in order
@@ -101,7 +104,7 @@ out:
        return -err;
 }
 
-int mkstate(const char *name)
+int lxc_mkstate(const char *name)
 {
        int fd;
        char file[MAXPATHLEN];
@@ -116,7 +119,7 @@ int mkstate(const char *name)
        return 0;
 }
 
-int rmstate(const char *name)
+int lxc_rmstate(const char *name)
 {
        char file[MAXPATHLEN];
        snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name);
@@ -152,7 +155,7 @@ lxc_state_t lxc_getstate(const char *name)
        file[err] = '\0';
 
        close(fd);
-       return str2state(file);
+       return lxc_str2state(file);
 }
 
 static int freezer_state(const char *name)
@@ -166,7 +169,7 @@ static int freezer_state(const char *name)
                 LXCPATH "/%s/freezer.freeze", name);
 
        file = fopen(freezer, "r");
-       if (file < 0) {
+       if (!file) {
                lxc_log_syserror("failed to open %s", freezer);
                return -1;
        }
@@ -179,7 +182,7 @@ static int freezer_state(const char *name)
                return -1;
        }
 
-       return str2state(status);
+       return lxc_str2state(status);
 }
 
 lxc_state_t lxc_state(const char *name)
index 27f4f5e0288875fbb77f19027f12f9ff0c5458dc..871d1a8d58c12556a73c3eda30ea97982c26cc6e 100644 (file)
@@ -28,11 +28,12 @@ typedef enum {
        ABORTING, FREEZING, FROZEN, MAX_STATE,
 } lxc_state_t;
 
-extern const char *state2str(lxc_state_t state);
-extern lxc_state_t str2state(const char *state);
-extern int mkstate(const char *name);
-extern int rmstate(const char *name);
+extern int lxc_mkstate(const char *name);
+extern int lxc_rmstate(const char *name);
 extern int lxc_setstate(const char *name, lxc_state_t state);
 extern lxc_state_t lxc_getstate(const char *name);
 
+extern lxc_state_t lxc_str2state(const char *state);
+extern const char *lxc_state2str(lxc_state_t state);
+
 #endif
index ce5fd19d2d683014cb1e8aa5277198905d261d0a..3f247dd1968f0b6f32f4513bbfe186ee92a8a351 100644 (file)
 #include <errno.h>
 #include <unistd.h>
 #include <string.h>
+#include <stdlib.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/param.h>
 #include <sys/inotify.h>
+#include <sys/socket.h>
+#include <sys/un.h>
 #include <netinet/in.h>
 #include <net/if.h>
-
 #include <lxc.h>
 
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX 108
+#endif
+
 int lxc_monitor(const char *name, int output_fd)
 {
        char path[MAXPATHLEN];
@@ -93,3 +99,72 @@ out:
        close(nfd);
        return err;
 }
+
+void lxc_monitor_send_state(const char *name, lxc_state_t state)
+{
+       int fd;
+       struct sockaddr_un addr;
+
+       fd = socket(PF_UNIX, SOCK_DGRAM, 0);
+       if (fd < 0)
+               lxc_log_syserror("failed to create notification socket");
+
+       memset(&addr, 0, sizeof(addr));
+       addr.sun_family = AF_UNIX;
+       snprintf(addr.sun_path, UNIX_PATH_MAX, LXCPATH "/%s/notification", name);
+
+       sendto(fd, &state, sizeof(state), 0, 
+              (const struct sockaddr *)&addr, sizeof(addr));
+
+       close(fd);
+}
+
+void lxc_monitor_cleanup(const char *name)
+{
+       char path[UNIX_PATH_MAX];
+       snprintf(path, UNIX_PATH_MAX, LXCPATH "/%s/notification", name);
+       unlink(path);
+}
+
+int lxc_monitor_open(const char *name)
+{
+       int fd;
+       struct sockaddr_un addr;
+
+       fd = socket(PF_UNIX, SOCK_DGRAM, 0);
+       if (fd < 0) {
+               lxc_log_syserror("failed to create notification socket");
+               return -1;
+       }
+
+       memset(&addr, 0, sizeof(addr));
+
+       addr.sun_family = AF_UNIX;
+       snprintf(addr.sun_path, UNIX_PATH_MAX, LXCPATH "/%s/notification", name);
+       unlink(addr.sun_path);
+
+       if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr))) {
+               lxc_log_syserror("failed to bind to '%s'", addr.sun_path);
+               return -1;
+       }
+
+       return fd;
+}
+
+int lxc_monitor_read(int fd, lxc_state_t *state)
+{
+       int ret;
+
+       ret = recv(fd, state, sizeof(*state), 0);
+       if (ret < 0) {
+               lxc_log_syserror("failed to received state");
+               return -1;
+       }
+
+       return ret;
+}
+
+int lxc_monitor_close(int fd)
+{
+       return close(fd);
+}
index 55526645c19776b32218998b02fca1cc96c85fb5..d0252c587d546e4f107f254af13889b59bd7acd6 100644 (file)
@@ -69,7 +69,7 @@ int lxc_start(const char *name, int argc, char *argv[],
 
        /* Begin the set the state to STARTING*/
        if (lxc_setstate(name, STARTING)) {
-               lxc_log_error("failed to set state %s", state2str(STARTING));
+               lxc_log_error("failed to set state %s", lxc_state2str(STARTING));
                goto out;
        }
 
@@ -195,7 +195,7 @@ int lxc_start(const char *name, int argc, char *argv[],
                lxc_log_warning("cgroupfs not found: cgroup disabled");
 
        if (lxc_setstate(name, RUNNING)) {
-               lxc_log_error("failed to set state to %s", state2str(RUNNING));
+               lxc_log_error("failed to set state to %s", lxc_state2str(RUNNING));
                goto err_state_failed;
        }
 
@@ -208,7 +208,7 @@ wait_again:
        }
 
        if (lxc_setstate(name, STOPPING))
-               lxc_log_error("failed to set state %s", state2str(STOPPING));
+               lxc_log_error("failed to set state %s", lxc_state2str(STOPPING));
 
        if (clone_flags & CLONE_NEWNET && conf_destroy_network(name))
                lxc_log_error("failed to destroy the network");
@@ -216,7 +216,7 @@ wait_again:
        err = 0;
 out:
        if (lxc_setstate(name, STOPPED))
-               lxc_log_error("failed to set state %s", state2str(STOPPED));
+               lxc_log_error("failed to set state %s", lxc_state2str(STOPPED));
 
        lxc_unlink_nsgroup(name);
        unlink(init);
@@ -239,7 +239,7 @@ err_create_network:
 err_pipe_read:
 err_waitpid_failed:
        if (lxc_setstate(name, ABORTING))
-               lxc_log_error("failed to set state %s", state2str(STOPPED));
+               lxc_log_error("failed to set state %s", lxc_state2str(STOPPED));
 
        kill(pid, SIGKILL);
 err_fork_ns:
index c57e76c89c038d0199372ae106427cbb651dc083..259ae9d114695d23fbd9b7c66c28a7f935a3e793 100644 (file)
@@ -17,50 +17,50 @@ bin_PROGRAMS = \
        lxc-unfreeze \
        lxc-priority
 
-lxc_create_SOURCES = lxc_create.c config.c config.h
+lxc_create_SOURCES = lxc_create.c lxc_config.c lxc_config.h
 lxc_create_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_destroy_SOURCES = lxc_destroy.c
 lxc_destroy_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_start_SOURCES = lxc_start.c
 lxc_start_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_stop_SOURCES = lxc_stop.c
 lxc_stop_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
-lxc_execute_SOURCES = lxc_execute.c config.c
+lxc_execute_SOURCES = lxc_execute.c
 lxc_execute_LDADD = \
-        $(top_builddir)/src/liblxc/liblxc.a
+        $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_monitor_SOURCES = lxc_monitor.c
 lxc_monitor_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_console_SOURCES = lxc_console.c
 lxc_console_LDADD = \
-        $(top_builddir)/src/liblxc/liblxc.a
+        $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_state_SOURCES = lxc_state.c
 lxc_state_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_kill_SOURCES = lxc_kill.c
 lxc_kill_LDADD = \
-        $(top_builddir)/src/liblxc/liblxc.a
+        $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_freeze_SOURCES = lxc_freeze.c
 lxc_freeze_LDADD = \
-        $(top_builddir)/src/liblxc/liblxc.a
+        $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_unfreeze_SOURCES = lxc_unfreeze.c
 lxc_unfreeze_LDADD = \
-        $(top_builddir)/src/liblxc/liblxc.a
+        $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_priority_SOURCES = lxc_priority.c
 lxc_priority_LDADD = \
-        $(top_builddir)/src/liblxc/liblxc.a
+        $(top_builddir)/src/liblxc/liblxc.la
diff --git a/src/lxc/lxc_config.c b/src/lxc/lxc_config.c
new file mode 100644 (file)
index 0000000..ae1338b
--- /dev/null
@@ -0,0 +1,546 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/utsname.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <net/if.h>
+
+#include <lxc.h>
+
+typedef int (*file_cb)(char* buffer, void *data);
+typedef int (*config_cb)(char *value, struct lxc_conf *lxc_conf);
+
+static int config_mount(char *, struct lxc_conf *);
+static int config_chroot(char *, struct lxc_conf *);
+static int config_utsname(char *, struct lxc_conf *);
+static int config_network_type(char *, struct lxc_conf *);
+static int config_network_flags(char *, struct lxc_conf *);
+static int config_network_link(char *, struct lxc_conf *);
+static int config_network_name(char *, struct lxc_conf *);
+static int config_network_hwaddr(char *, struct lxc_conf *);
+static int config_network_ipv4(char *, struct lxc_conf *);
+static int config_network_ipv6(char *, struct lxc_conf *);
+
+struct config {
+       char *name;
+       int type;
+       config_cb cb;
+};
+
+enum { MOUNT, CHROOT, UTSNAME, NETTYPE, NETFLAGS, NETLINK, 
+       NETNAME, NETHWADDR, NETIPV4, NETIPV6 };
+
+struct config config[] = {
+       { "lxc.mount",             MOUNT,     config_mount           },
+       { "lxc.chroot",            CHROOT,    config_chroot          },
+       { "lxc.utsname",           UTSNAME,   config_utsname         },
+       { "lxc.network.type",      NETTYPE,   config_network_type    },
+       { "lxc.network.flags",     NETFLAGS,  config_network_flags   },
+       { "lxc.network.link",      NETLINK,   config_network_link    },
+       { "lxc.network.name",      NETNAME,   config_network_name    },
+       { "lxc.network.hwaddr",    NETHWADDR, config_network_hwaddr  },
+       { "lxc.network.ipv4",      NETIPV4,   config_network_ipv4    },
+       { "lxc.network.ipv6",      NETIPV6,   config_network_ipv6    },
+};
+
+static const size_t config_size = sizeof(config)/sizeof(struct config);
+
+static struct config *getconfig(const char *key)
+{
+       int i;
+
+       for (i = 0; i < config_size; i++)
+               if (!strncmp(config[i].name, key, 
+                            strlen(config[i].name)))
+                       return &config[i];
+       return NULL;
+}
+
+static int is_line_empty(char *line)
+{
+       int i;
+       size_t len = strlen(line);
+
+       for (i = 0; i < len; i++)
+               if (line[i] != ' ' && line[i] != '\t' && 
+                   line[i] != '\n' && line[i] != '\r' &&
+                   line[i] != '\f' && line[i] != '\0')
+                       return 0;
+       return 1;
+}
+
+static int char_left_gc(char *buffer, size_t len)
+{
+       int i;
+       for (i = 0; i < len; i++) {
+               if (buffer[i] == ' ' ||
+                   buffer[i] == '\t')
+                       continue;
+               return i;
+       }
+       return 0;
+}
+
+static int char_right_gc(char *buffer, size_t len)
+{
+       int i;
+       for (i = len - 1; i >= 0; i--) {
+               if (buffer[i] == ' '  ||
+                   buffer[i] == '\t' ||
+                   buffer[i] == '\n' ||
+                   buffer[i] == '\0')
+                       continue;
+               return i + 1;
+       }
+       return 0;
+}
+
+static int config_network_type(char *value, struct lxc_conf *lxc_conf)
+{
+       struct lxc_list *networks = &lxc_conf->networks;
+       struct lxc_network *network;
+       struct lxc_netdev *netdev;
+       struct lxc_list *list;
+       struct lxc_list *ndlist;
+
+       network = malloc(sizeof(*network));
+       if (!network) {
+               lxc_log_syserror("failed to allocate memory");
+               return -1;
+       }
+       
+       lxc_list_init(&network->netdev);
+
+       netdev = malloc(sizeof(*netdev));
+       if (!netdev) {
+               lxc_log_syserror("failed to allocate memory");
+               return -1;
+       }
+
+       lxc_list_init(&netdev->ipv4);
+       lxc_list_init(&netdev->ipv6);
+       lxc_list_init(&netdev->route4);
+       lxc_list_init(&netdev->route6);
+
+       ndlist = malloc(sizeof(*ndlist));
+       if (!ndlist) {
+               lxc_log_syserror("failed to allocate memory");
+               return -1;
+       }
+
+       ndlist->elem = netdev;
+
+       lxc_list_add(&network->netdev, ndlist);
+
+       list = malloc(sizeof(*list));
+       if (!list) {
+               lxc_log_syserror("failed to allocate memory");
+               return -1;
+       }
+
+       lxc_list_init(list);
+       list->elem = network;
+
+       lxc_list_add(networks, list);
+       
+       if (!strcmp(value, "veth"))
+               network->type = VETH;
+       else if (!strcmp(value, "macvlan"))
+               network->type = MACVLAN;
+       else if (!strcmp(value, "phys"))
+               network->type = PHYS;
+       else {
+               lxc_log_error("invalid network type %s", value);
+               return -1;
+       }
+       return 0;
+}
+
+static int config_network_flags(char *value, struct lxc_conf *lxc_conf)
+{
+       struct lxc_list *networks = &lxc_conf->networks;
+       struct lxc_network *network;
+       struct lxc_netdev *netdev;
+
+       if (lxc_list_empty(networks)) {
+               lxc_log_error("network is not created for '%s' option", value);
+               return -1;
+       }
+
+       network = lxc_list_first_elem(networks);
+       if (!network) {
+               lxc_log_error("no network defined for '%s' option", value);
+               return -1;
+       }
+
+       netdev = lxc_list_first_elem(&network->netdev);
+       netdev->flags |= IFF_UP;
+       return 0;
+}
+
+static int config_network_link(char *value, struct lxc_conf *lxc_conf)
+{
+       struct lxc_list *networks = &lxc_conf->networks;
+       struct lxc_network *network;
+       struct lxc_netdev *netdev;
+
+       if (lxc_list_empty(networks)) {
+               lxc_log_error("network is not created for %s", value);
+               return -1;
+       }
+
+       network = lxc_list_first_elem(networks);
+       if (!network) {
+               lxc_log_error("no network defined for %s", value);
+               return -1;
+       }
+
+       if (strlen(value) > IFNAMSIZ) {
+               lxc_log_error("invalid interface name: %s", value);
+               return -1;
+       }
+
+       netdev = lxc_list_first_elem(&network->netdev);
+       netdev->ifname = strdup(value);
+       return 0;
+}
+
+static int config_network_name(char *value, struct lxc_conf *lxc_conf)
+{
+       struct lxc_list *networks = &lxc_conf->networks;
+       struct lxc_network *network;
+       struct lxc_netdev *netdev;
+
+       if (lxc_list_empty(networks)) {
+               lxc_log_error("network is not created for %s", value);
+               return -1;
+       }
+
+       network = lxc_list_first_elem(networks);
+       if (!network) {
+               lxc_log_error("no network defined for %s", value);
+               return -1;
+       }
+
+       if (strlen(value) > IFNAMSIZ) {
+               lxc_log_error("invalid interface name: %s", value);
+               return -1;
+       }
+
+       netdev = lxc_list_first_elem(&network->netdev);
+       netdev->newname = strdup(value);
+       return 0;
+}
+
+static int config_network_hwaddr(char *value, struct lxc_conf *lxc_conf)
+{
+       struct lxc_list *networks = &lxc_conf->networks;
+       struct lxc_network *network;
+       struct lxc_netdev *netdev;
+
+       if (lxc_list_empty(networks)) {
+               lxc_log_error("network is not created for %s", value);
+               return -1;
+       }
+
+       network = lxc_list_first_elem(networks);
+       if (!network) {
+               lxc_log_error("no network defined for %s", value);
+               return -1;
+       }
+
+       netdev = lxc_list_first_elem(&network->netdev);
+       netdev->hwaddr = strdup(value);
+       return 0;
+}
+
+static int config_network_ipv4(char *value, struct lxc_conf *lxc_conf)
+{
+       struct lxc_list *networks = &lxc_conf->networks;
+       struct lxc_network *network;
+       struct lxc_inetdev *inetdev;
+       struct lxc_netdev *netdev;
+       struct lxc_list *list;
+       char *cursor, *slash, *addr = NULL, *bcast = NULL, *prefix = NULL;
+
+       if (lxc_list_empty(networks)) {
+               lxc_log_error("network is not created for '%s'", value);
+               return -1;
+       }
+
+       network = lxc_list_first_elem(networks);
+       if (!network) {
+               lxc_log_error("no network defined for '%s'", value);
+               return -1;
+       }
+
+       netdev = lxc_list_first_elem(&network->netdev);
+       if (!netdev) {
+               lxc_log_error("no netdev defined for '%s'", value);
+       }
+
+       inetdev = malloc(sizeof(*inetdev));
+       if (!inetdev) {
+               lxc_log_syserror("failed to allocate ipv4 address");
+               return -1;
+       }
+       memset(inetdev, 0, sizeof(*inetdev));
+
+       list = malloc(sizeof(*list));
+       if (!list) {
+               lxc_log_syserror("failed to allocate memory");
+               return -1;
+       }
+
+       lxc_list_init(list);
+       list->elem = inetdev;
+
+       addr = value;
+
+       cursor = strstr(addr, " ");
+       if (cursor) {
+               *cursor = '\0';
+               bcast = cursor + 1;
+       }
+
+       slash = strstr(addr, "/");
+       if (slash) {
+               *slash = '\0';
+               prefix = slash + 1;
+       }
+
+       if (!addr) {
+               lxc_log_error("no address specified");
+               return -1;
+       }
+
+       if (!inet_pton(AF_INET, addr, &inetdev->addr)) {
+               lxc_log_syserror("invalid ipv4 address: %s", value);
+               return -1;
+       }
+
+       if (bcast)
+               if (!inet_pton(AF_INET, bcast, &inetdev->bcast)) {
+                       lxc_log_syserror("invalid ipv4 address: %s", value);
+                       return -1;
+               }
+
+       if (prefix)
+               inetdev->prefix = atoi(prefix);
+
+       lxc_list_add(&netdev->ipv4, list);
+
+       return 0;
+}
+
+static int config_network_ipv6(char *value, struct lxc_conf *lxc_conf)
+{
+       struct lxc_list *networks = &lxc_conf->networks;
+       struct lxc_network *network;
+       struct lxc_netdev *netdev;
+       struct lxc_inet6dev *inet6dev;
+       struct lxc_list *list;
+       char *slash;
+       char *netmask;
+
+       if (lxc_list_empty(networks)) {
+               lxc_log_error("network is not created for %s", value);
+               return -1;
+       }
+
+       network = lxc_list_first_elem(networks);
+       if (!network) {
+               lxc_log_error("no network defined for %s", value);
+               return -1;
+       }
+
+       inet6dev = malloc(sizeof(*inet6dev));
+       if (!inet6dev) {
+               lxc_log_syserror("failed to allocate ipv6 address");
+               return -1;
+       }
+       memset(inet6dev, 0, sizeof(*inet6dev));
+
+       list = malloc(sizeof(*list));
+       if (!list) {
+               lxc_log_syserror("failed to allocate memory");
+               return -1;
+       }
+
+       lxc_list_init(list);
+       list->elem = inet6dev;
+
+       slash = strstr(value, "/");
+       if (slash) {
+               *slash = '\0';
+               netmask = slash + 1;
+               inet6dev->prefix = atoi(netmask);
+       }
+
+       if (!inet_pton(AF_INET6, value, &inet6dev->addr)) {
+               lxc_log_syserror("invalid ipv6 address: %s", value);
+               return -1;
+       }
+
+
+       netdev = lxc_list_first_elem(&network->netdev);
+       lxc_list_add(&netdev->ipv6, list);
+
+       return 0;
+}
+
+static int config_mount(char *value, struct lxc_conf *lxc_conf)
+{
+       if (strlen(value) >= MAXPATHLEN) {
+               lxc_log_error("%s path is too long", value);
+               return -1;
+       }
+
+       lxc_conf->fstab = strdup(value);
+       if (!lxc_conf->fstab) {
+               lxc_log_syserror("failed to duplicate string %s", value);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int config_chroot(char *value, struct lxc_conf *lxc_conf)
+{
+       if (strlen(value) >= MAXPATHLEN) {
+               lxc_log_error("%s path is too long", value);
+               return -1;
+       }
+
+       lxc_conf->chroot = strdup(value);
+       if (!lxc_conf->chroot) {
+               lxc_log_syserror("failed to duplicate string %s", value);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int config_utsname(char *value, struct lxc_conf *lxc_conf)
+{
+       struct utsname *utsname;
+
+       utsname = malloc(sizeof(*utsname));
+       if (!utsname) {
+               lxc_log_syserror("failed to allocate memory");
+               return -1;
+       }
+
+       if (strlen(value) >= sizeof(utsname->nodename)) {
+               lxc_log_error("node name '%s' is too long", 
+                             utsname->nodename);
+               return -1;
+       }
+
+       strcpy(utsname->nodename, value);
+       lxc_conf->utsname = utsname;
+
+       return 0;
+}
+
+static int parse_line(char *buffer, void *data)
+{
+       struct config *config;
+       char *dot;
+       char *key;
+       char *value;
+
+       if (is_line_empty(buffer))
+               return 0;
+
+       buffer += char_left_gc(buffer, strlen(buffer));
+       if (buffer[0] == '#')
+               return 0;
+
+       dot = strstr(buffer, "=");
+       if (!dot) {
+               lxc_log_error("invalid configuration line: %s", buffer);
+               return -1;
+       }
+       
+       *dot = '\0';
+       value = dot + 1;
+
+       key = buffer;
+       key[char_right_gc(key, strlen(key))] = '\0';
+
+       value += char_left_gc(value, strlen(value));
+       value[char_right_gc(value, strlen(value))] = '\0';
+
+       config = getconfig(key);
+       if (!config) {
+               lxc_log_error("unknow key %s", key);
+               return -1;
+       }
+
+       return config->cb(value, data);
+}
+
+static int file_for_each_line(const char *file, file_cb callback, void *data)
+{
+       char buffer[MAXPATHLEN];
+       size_t len = sizeof(buffer);
+       FILE *f;
+       int err = -1;
+
+       f = fopen(file, "r");
+       if (!f) {
+               lxc_log_syserror("failed to open %s", file);
+               return -1;
+       }
+       
+       while (fgets(buffer, len, f))
+               if (callback(buffer, data))
+                       goto out;
+       err = 0;
+out:
+       fclose(f);      
+       return err;
+}
+
+int lxc_config_read(const char *file, struct lxc_conf *conf)
+{
+       return file_for_each_line(file, parse_line, conf);
+}
+
+int lxc_config_init(struct lxc_conf *conf)
+{
+       conf->chroot = NULL;
+       conf->fstab = NULL;
+       conf->utsname = NULL;
+       conf->cgroup = NULL;
+       lxc_list_init(&conf->networks);
+       return 0;
+}
diff --git a/src/lxc/lxc_config.h b/src/lxc/lxc_config.h
new file mode 100644 (file)
index 0000000..f81217b
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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
+ */
+
+extern int lxc_config_init(struct lxc_conf *conf);
+extern int lxc_config_read(const char *file, struct lxc_conf *conf);
+
+
+
index 5f9f7205bd23f0bf84c58bbf33d67088078a62f6..c34b4897da4a269b487fe872d858ce2a23fad8f6 100644 (file)
@@ -32,8 +32,7 @@
 #include <net/if.h>
 
 #include <lxc.h>
-
-#include "config.h"
+#include "lxc_config.h"
 
 void usage(char *cmd)
 {
@@ -63,12 +62,12 @@ int main(int argc, char *argv[])
        if (!name || !file)
                usage(argv[0]);
 
-       if (config_init(&lxc_conf)) {
+       if (lxc_config_init(&lxc_conf)) {
                fprintf(stderr, "failed to initialize the configuration\n");
                return 1;
        }
 
-       if (config_read(file, &lxc_conf)) {
+       if (lxc_config_read(file, &lxc_conf)) {
                fprintf(stderr, "invalid configuration file\n");
                return 1;
        }
index b844f61240b2c3d80d991f489cb53064171d0b67..3e1066c18406c9f9ed5a97b9c46f3b80f9212d13 100644 (file)
@@ -90,7 +90,7 @@ int main(int argc, char *argv[])
                }
 
                printf("container has changed the state to %d - %s\n", 
-                      state, state2str(state));
+                      state, lxc_state2str(state));
        }
        return 0;
 }
index 9b1c5cceecedc171acf9272f92972e5e29d51329..a1efe5fdb4fb3e02595d891a6fd608b92fe309bd 100644 (file)
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <libgen.h>
+#include <stdlib.h>
 #include <sys/types.h>
 
 #include <lxc.h>
@@ -58,7 +59,7 @@ int main(int argc, char *argv[])
                usage(argv[0]);
 
        if (!priority) {
-               if (lxc_get_priority(name, &prio)) {
+               if (lxc_cgroup_get_priority(name, &prio)) {
                        fprintf(stderr, "failed to retrieve the priority of '%s'\n", name);
                        return 1;
                }
@@ -68,7 +69,7 @@ int main(int argc, char *argv[])
        }
 
        prio = atoi(priority);
-       if (lxc_set_priority(name, prio)) {
+       if (lxc_cgroup_set_priority(name, prio)) {
                fprintf(stderr, "failed to assign priority  %d to of '%s'", 
                        prio, name);
                return 1;
index abb6b3c92ce6a41d3e2108590514bc9fb5227505..8939405fe17e5393d5f63941d149853eb9d9f041 100644 (file)
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
                return 1;
        }
 
-       printf("'%s' is %s\n", name, state2str(state));
+       printf("'%s' is %s\n", name, lxc_state2str(state));
 
        return 0;
 }
index cc6faaaf2a682b5a03df35625b76a5f8b88ee14f..01b9866db99978207d8b13ab009798ad8b6a6b93 100644 (file)
@@ -18,74 +18,79 @@ noinst_PROGRAMS = \
        lxc_start \
        lxc_stop \
        lxc_monitor \
+       lxc_low_monitor \
        lxc_state
 
 
 tst_list_SOURCES = tst_list.c
 tst_list_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 confile_SOURCES = confile.c
 confile_LDADD = \
-       $(top_builddir)/src/lxc/config.o \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/lxc/lxc_config.o \
+       $(top_builddir)/src/liblxc/liblxc.la
 
 conf_SOURCES = conf.c
 conf_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 movedev_SOURCES = movedev.c
 movedev_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 dev_SOURCES = dev.c
 dev_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 forward_SOURCES = forward.c
 forward_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 proxy_SOURCES = proxy.c
 proxy_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 veth_SOURCES = veth.c
 veth_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 macvlan_SOURCES = macvlan.c
 macvlan_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 ipv4_add_SOURCES = ipv4_add.c
 ipv4_add_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 ipv6_add_SOURCES = ipv6_add.c
 ipv6_add_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_create_SOURCES = lxc_create.c
 lxc_create_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_destroy_SOURCES = lxc_destroy.c
 lxc_destroy_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_start_SOURCES = lxc_start.c
 lxc_start_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_stop_SOURCES = lxc_stop.c
 lxc_stop_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_monitor_SOURCES = lxc_monitor.c
 lxc_monitor_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
+
+lxc_low_monitor_SOURCES = lxc_low_monitor.c
+lxc_low_monitor_LDADD = \
+       $(top_builddir)/src/liblxc/liblxc.la
 
 lxc_state_SOURCES = lxc_state.c
 lxc_state_LDADD = \
-       $(top_builddir)/src/liblxc/liblxc.a
+       $(top_builddir)/src/liblxc/liblxc.la
index 53a6f08ecc89ac4e2d59bd6f904d50185bd525e4..34f597b0dfc7811f27658f280a7df71eb3574dc4 100644 (file)
@@ -32,7 +32,7 @@
 
 #include <lxc.h>
 
-#include "../src/lxc/config.h"
+#include "../src/lxc/lxc_config.h"
 
 static void usage(const char *cmd)
 {
@@ -60,12 +60,12 @@ int main(int argc, char *argv[])
        if (!file || !name)
                usage(argv[0]);
 
-       if (config_init(&lxc_conf)) {
+       if (lxc_config_init(&lxc_conf)) {
                fprintf(stderr, "failed to initialize configuration structure\n");
                return 1;
        }
 
-       if (config_read(file, &lxc_conf)) {
+       if (lxc_config_read(file, &lxc_conf)) {
                fprintf(stderr, "failed to read configuration\n");
                return 1;
        }
diff --git a/test/lxc_low_monitor.c b/test/lxc_low_monitor.c
new file mode 100644 (file)
index 0000000..41db553
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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 <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <libgen.h>
+
+#include <lxc.h>
+
+void usage(char *cmd)
+{
+       fprintf(stderr, "%s <command>\n", basename(cmd));
+       fprintf(stderr, "\t -n <name>   : name of the container\n");
+       _exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+       char opt;
+       char *name = NULL;
+       int fd;
+
+       while ((opt = getopt(argc, argv, "n:")) != -1) {
+               switch (opt) {
+               case 'n':
+                       name = optarg;
+                       break;
+               }
+       }
+
+       if (!name)
+               usage(argv[0]);
+
+       fd = lxc_monitor_open(name);
+       if (fd < 0) {
+               fprintf(stderr, "failed to open monitor\n");
+               return -1;
+       }
+       
+       for (;;) {
+               lxc_state_t state;
+               lxc_monitor_read(fd, &state);
+               printf("received changing state '%s'\n", lxc_state2str(state));
+       }
+}
index cd297af53000ad4f7a2cf87a2196f1b75fd769a5..41e35b8327ab15b28db3e325a998802368ceb48b 100644 (file)
@@ -92,7 +92,7 @@ int main(int argc, char *argv[])
                }
 
                printf("container has changed the state to %d - %s\n", 
-                      state, state2str(state));
+                      state, lxc_state2str(state));
        }
 
        return 0;
index 2b440913037a2ff706a1bb1855e3df00e3020f87..a412bc9c1db06d44e69847ba5d9a1d9636b0373e 100644 (file)
@@ -58,7 +58,7 @@ int main(int argc, char *argv[])
        }
 
        printf("container has the state to %d - %s\n",
-              state, state2str(state));
+              state, lxc_state2str(state));
 
 
        return 0;