2
* lxc: linux Container library
4
* (C) Copyright IBM Corp. 2007, 2008
7
* Daniel Lezcano <dlezcano at fr.ibm.com>
9
* This library is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU Lesser General Public
11
* License as published by the Free Software Foundation; either
12
* version 2.1 of the License, or (at your option) any later version.
14
* This library is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
* Lesser General Public License for more details.
19
* You should have received a copy of the GNU Lesser General Public
20
* License along with this library; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29
#include <sys/types.h>
31
#include <sys/param.h>
32
#include <sys/inotify.h>
33
#include <sys/socket.h>
34
#include <netinet/in.h>
36
#include <linux/netlink.h>
37
#include <linux/rtnetlink.h>
43
lxc_log_define(lxc_monitor, lxc);
46
#define UNIX_PATH_MAX 108
50
#define SOL_NETLINK 270
53
/* assuming this multicast group is not used by anyone else :/
54
* otherwise a new genetlink family should be defined to own
55
* its multicast groups */
56
#define MONITOR_MCGROUP RTNLGRP_MAX
58
int lxc_monitor(const char *name, int output_fd)
60
char path[MAXPATHLEN];
61
int err = -1, nfd, wfd, state;
65
SYSERROR("failed to initialize inotify");
69
snprintf(path, MAXPATHLEN, LXCPATH "/%s/state", name);
71
wfd = inotify_add_watch(nfd, path, IN_DELETE_SELF|IN_CLOSE_WRITE);
73
SYSERROR("failed to add a watch on %s", path);
78
struct inotify_event evt;
80
if (read(nfd, &evt, sizeof(evt)) < 0) {
81
SYSERROR("failed to read inotify event");
85
if (evt.mask & IN_CLOSE_WRITE) {
87
state = lxc_getstate(name);
89
ERROR("failed to get the state for %s",
94
if (write(output_fd, &state, sizeof(state)) < 0) {
95
SYSERROR("failed to send state to %d",
102
if (evt.mask & IN_DELETE_SELF) {
108
ERROR("unknown evt for inotity (%d)", evt.mask);
113
inotify_rm_watch(nfd, wfd);
118
static void lxc_monitor_send(struct lxc_msg *msg)
121
struct sockaddr_nl addr;
123
fd = socket(PF_NETLINK, SOCK_RAW, 0);
125
SYSERROR("failed to create notification socket");
129
memset(&addr, 0, sizeof(addr));
131
addr.nl_family = AF_NETLINK;
133
addr.nl_groups = MONITOR_MCGROUP;
135
sendto(fd, msg, sizeof(*msg), 0,
136
(const struct sockaddr *)&addr, sizeof(addr));
141
void lxc_monitor_send_state(const char *name, lxc_state_t state)
143
struct lxc_msg msg = { .type = lxc_msg_state,
145
strncpy(msg.name, name, sizeof(msg.name));
147
lxc_monitor_send(&msg);
150
int lxc_monitor_open(void)
153
struct sockaddr_nl addr;
155
fd = socket(PF_NETLINK, SOCK_RAW, 0);
157
SYSERROR("failed to create notification socket");
158
return -LXC_ERROR_INTERNAL;
161
memset(&addr, 0, sizeof(addr));
163
addr.nl_family = AF_NETLINK;
165
addr.nl_groups = MONITOR_MCGROUP;
167
if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr))) {
168
SYSERROR("failed to bind to multicast group '%d'",
177
int lxc_monitor_read(int fd, struct lxc_msg *msg)
179
struct sockaddr_nl from;
180
socklen_t len = sizeof(from);
183
ret = recvfrom(fd, msg, sizeof(*msg), 0,
184
(struct sockaddr *)&from, &len);
186
SYSERROR("failed to received state");
187
return -LXC_ERROR_INTERNAL;
193
int lxc_monitor_close(int fd)