]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
These modifications improve the monitoring support of the container. Now
authordlezcano <dlezcano>
Sat, 18 Oct 2008 21:07:39 +0000 (21:07 +0000)
committerdlezcano <dlezcano>
Sat, 18 Oct 2008 21:07:39 +0000 (21:07 +0000)
several readers can attend the events from one or several containers.
The syntax of the command has been enhanced to interpret regular expressions.
If you want to monitor foo, lxc-monitor -n foo is the right command. If you
want to monitor foo and bar, you should specify lxc-monitor -n "foo|bar",
if you want to monitor all containers with the name beginning with 'foo',
you have to specify lxc-monitor -n "foo.*". More complex regexp can be specified
in accordance with the POSIX definitions, man regex (7).

src/lxc/destroy.c
src/lxc/lxc.h
src/lxc/lxc_monitor.c
src/lxc/lxc_wait.c
src/lxc/monitor.c
src/lxc/monitor.h

index 8311d3d85fa9dcedf19432d59524a9a649af4af1..e879a9cd5f754a782489de2e18582ab59f90f350 100644 (file)
@@ -96,8 +96,6 @@ int lxc_destroy(const char *name)
        snprintf(path, MAXPATHLEN, LXCPATH "/%s/init", name);
        unlink(path);
 
-       lxc_monitor_cleanup(name);
-
        if (lxc_unconfigure(name)) {
                lxc_log_error("failed to cleanup %s", name);
                goto out_lock;
index efe922176d42e667db5cd6b252bf9aa3c5ec30f1..601dfa202c6380001fe361e73cdd1b1d10b26b52 100644 (file)
@@ -118,10 +118,9 @@ 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);
+extern int lxc_monitor_open();
 
 /*
  * Read the state of the container if this one has changed
index 85ad25f800e0a88ef0b329253c05004a2523147d..daae4807086fcc5ec2e323386ae221a53471c460 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #include <stdio.h>
+#include <string.h>
 #include <libgen.h>
 #include <unistd.h>
+#include <regex.h>
 #include <sys/types.h>
 
 #include <lxc/lxc.h>
 void usage(char *cmd)
 {
        fprintf(stderr, "%s <command>\n", basename(cmd));
-       fprintf(stderr, "\t -n <name>   : name of the container\n");
+       fprintf(stderr, "\t -n <name>   : name of the container or regular expression\n");
        _exit(1);
 }
 
 int main(int argc, char *argv[])
 {
        char opt, *name = NULL;
+       char *regexp;
        struct lxc_msg msg;
+       regex_t preg;
        int fd;
 
        while ((opt = getopt(argc, argv, "n:")) != -1) {
@@ -51,7 +55,16 @@ int main(int argc, char *argv[])
        if (!name)
                usage(argv[0]);
 
-       fd = lxc_monitor_open(name);
+       regexp = malloc(strlen(name) + 3);
+       sprintf(regexp, "^%s$", name);
+
+       if (regcomp(&preg, regexp, REG_NOSUB|REG_EXTENDED)) {
+               fprintf(stderr, "failed to compile the regex '%s'\n",
+                       name);
+               return 1;
+       }
+
+       fd = lxc_monitor_open();
        if (fd < 0) {
                fprintf(stderr, "failed to open monitor for '%s'\n", name);
                return -1;
@@ -65,21 +78,22 @@ int main(int argc, char *argv[])
                        return -1;
                }
 
+               if (regexec(&preg, msg.name, 0, NULL, 0))
+                       continue;
+
                switch (msg.type) {
                case lxc_msg_state:
                        printf("'%s' changed state to [%s]\n", 
-                              name, lxc_state2str(msg.value));
-                       break;
-               case lxc_msg_priority:
-                       printf("'%s' changed priority to [%d]\n", 
-                              name, msg.value);
+                              msg.name, lxc_state2str(msg.value));
                        break;
                default:
-                       printf("invalid msg format\n");
+                       /* ignore garbage */
                        break;
                }
        }
 
+       regfree(&preg);
+
        return 0;
 }
 
index f7d49b2b3df78e0ac4217f22f38e457bfbf404d9..b5ea2f3fc7e1683785ddb0a441bceb22cd5ba5f0 100644 (file)
@@ -82,7 +82,7 @@ int main(int argc, char *argv[])
        }
 
        
-       fd = lxc_monitor_open(name);
+       fd = lxc_monitor_open();
        if (fd < 0) {
                fprintf(stderr, "failed to open monitor for '%s'\n", name);
                return -1;
@@ -96,10 +96,14 @@ int main(int argc, char *argv[])
                        return -1;
                }
 
+               if (strcmp(name, msg.name))
+                       continue;
+
                switch (msg.type) {
                case lxc_msg_state:
                        if (msg.value < 0 || msg.value >= MAX_STATE) {
-                               fprintf(stderr, "Receive an invalid state number '%d'\n", msg.value);
+                               fprintf(stderr, "Receive an invalid state number '%d'\n", 
+                                       msg.value);
                                return -1;
                        }
 
@@ -107,7 +111,7 @@ int main(int argc, char *argv[])
                                return 0;
                        break;
                default:
-                       printf("invalid msg format\n");
+                       /* just ignore garbage */
                        break;
                }
        }
index 8175baba483b58e31eadbd0948b0d4ebee0179b2..ff5e08ba5e0f9f02f59353b1a258766a73f58f53 100644 (file)
 #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 <linux/netlink.h>
+#include <linux/rtnetlink.h>
 
 #include <lxc/lxc.h>
 
 #define UNIX_PATH_MAX 108
 #endif
 
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
+
+/* assuming this multicast group is not used by anyone else :/
+ * otherwise a new genetlink family should be defined to own
+ * its multicast groups */
+#define MONITOR_MCGROUP RTNLGRP_MAX
+
 int lxc_monitor(const char *name, int output_fd)
 {
        char path[MAXPATHLEN];
@@ -101,21 +111,22 @@ out:
        return err;
 }
 
-static void lxc_monitor_send(const char *name, struct lxc_msg *msg)
+static void lxc_monitor_send(struct lxc_msg *msg)
 {
        int fd;
-       struct sockaddr_un addr;
+       struct sockaddr_nl addr;
 
-       fd = socket(PF_UNIX, SOCK_DGRAM, 0);
+       fd = socket(PF_NETLINK, SOCK_RAW, 0);
        if (fd < 0) {
                lxc_log_syserror("failed to create notification socket");
                return;
        }
 
        memset(&addr, 0, sizeof(addr));
-       addr.sun_family = AF_UNIX;
-       snprintf(addr.sun_path, UNIX_PATH_MAX, 
-                LXCPATH "/%s/notification", name);
+
+       addr.nl_family = AF_NETLINK;
+       addr.nl_pid = 0;
+       addr.nl_groups = MONITOR_MCGROUP;
 
        sendto(fd, msg, sizeof(*msg), 0,
               (const struct sockaddr *)&addr, sizeof(addr));
@@ -127,22 +138,17 @@ void lxc_monitor_send_state(const char *name, lxc_state_t state)
 {
        struct lxc_msg msg = { .type = lxc_msg_state,
                               .value = state };
-       lxc_monitor_send(name, &msg);
-}
+       strncpy(msg.name, name, sizeof(msg.name));
 
-void lxc_monitor_cleanup(const char *name)
-{
-       char path[UNIX_PATH_MAX];
-       snprintf(path, UNIX_PATH_MAX, LXCPATH "/%s/notification", name);
-       unlink(path);
+       lxc_monitor_send(&msg);
 }
 
-int lxc_monitor_open(const char *name)
+int lxc_monitor_open(void)
 {
        int fd;
-       struct sockaddr_un addr;
+       struct sockaddr_nl addr;
 
-       fd = socket(PF_UNIX, SOCK_DGRAM, 0);
+       fd = socket(PF_NETLINK, SOCK_RAW, 0);
        if (fd < 0) {
                lxc_log_syserror("failed to create notification socket");
                return -1;
@@ -150,12 +156,13 @@ int lxc_monitor_open(const char *name)
 
        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);
+       addr.nl_family = AF_NETLINK;
+       addr.nl_pid = 0;
+       addr.nl_groups = MONITOR_MCGROUP;
 
        if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr))) {
-               lxc_log_syserror("failed to bind to '%s'", addr.sun_path);
+               lxc_log_syserror("failed to bind to multicast group '%d'",
+                       addr.nl_groups);
                close(fd);
                return -1;
        }
@@ -165,9 +172,12 @@ int lxc_monitor_open(const char *name)
 
 int lxc_monitor_read(int fd, struct lxc_msg *msg)
 {
+       struct sockaddr_nl from;
+       socklen_t len = sizeof(from);
        int ret;
 
-       ret = recv(fd, msg, sizeof(*msg), 0);
+       ret = recvfrom(fd, msg, sizeof(*msg), 0, 
+                      (struct sockaddr *)&from, &len);
        if (ret < 0) {
                lxc_log_syserror("failed to received state");
                return -1;
index 304450e5aa69b745f2faddfd4b9d0ac2febb73fa..ab08f1060361d1bd4f655b5efee0fa14ec19727a 100644 (file)
@@ -23,6 +23,8 @@
 #ifndef __monitor_h
 #define __monitor_h
 
+#include <sys/param.h>
+
 typedef enum {
        lxc_msg_state,
        lxc_msg_priority,
@@ -30,6 +32,7 @@ typedef enum {
 
 struct lxc_msg {
        lxc_msg_type_t type;
+       char name[MAXPATHLEN];
        int value;
 };