mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-06-13 16:08:21 +00:00
These modifications improve the monitoring support of the container. Now
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).
This commit is contained in:
parent
848e89275f
commit
80f412985e
@ -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;
|
||||
|
@ -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
|
||||
|
@ -21,8 +21,10 @@
|
||||
* 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>
|
||||
@ -30,14 +32,16 @@
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -31,9 +31,10 @@
|
||||
#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>
|
||||
|
||||
@ -41,6 +42,15 @@
|
||||
#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));
|
||||
|
||||
lxc_monitor_send(&msg);
|
||||
}
|
||||
|
||||
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 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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user