]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/monitor.c
Add return error status in the different functions
[mirror_lxc.git] / src / lxc / monitor.c
CommitLineData
0ad19a3f 1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <dlezcano at fr.ibm.com>
8 *
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.
13 *
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.
18 *
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
22 */
23#include <stdio.h>
24#include <errno.h>
25#include <unistd.h>
26#include <string.h>
27#include <stdlib.h>
28#include <fcntl.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <sys/param.h>
32#include <sys/inotify.h>
33#include <sys/socket.h>
0ad19a3f 34#include <netinet/in.h>
35#include <net/if.h>
80f41298 36#include <linux/netlink.h>
37#include <linux/rtnetlink.h>
b113348e 38
e2bcd7db 39#include "error.h"
b113348e 40#include <lxc/lxc.h>
0ad19a3f 41
42#ifndef UNIX_PATH_MAX
43#define UNIX_PATH_MAX 108
44#endif
45
80f41298 46#ifndef SOL_NETLINK
47#define SOL_NETLINK 270
48#endif
49
50/* assuming this multicast group is not used by anyone else :/
51 * otherwise a new genetlink family should be defined to own
52 * its multicast groups */
53#define MONITOR_MCGROUP RTNLGRP_MAX
54
0ad19a3f 55int lxc_monitor(const char *name, int output_fd)
56{
57 char path[MAXPATHLEN];
58 int err = -1, nfd, wfd, state;
59
60 nfd = inotify_init();
61 if (nfd < 0) {
62 lxc_log_syserror("failed to initialize inotify");
63 return -1;
64 }
65
66 snprintf(path, MAXPATHLEN, LXCPATH "/%s/state", name);
67
68 wfd = inotify_add_watch(nfd, path, IN_DELETE_SELF|IN_CLOSE_WRITE);
69 if (wfd < 0) {
70 lxc_log_syserror("failed to add a watch on %s", path);
71 goto out;
72 }
73
74 for(;;) {
75 struct inotify_event evt;
76
77 if (read(nfd, &evt, sizeof(evt)) < 0) {
78 lxc_log_syserror("failed to read inotify event");
79 goto out;
80 }
81
82 if (evt.mask & IN_CLOSE_WRITE) {
83
84 state = lxc_getstate(name);
85 if (state < 0) {
86 lxc_log_error("failed to get the state for %s",
87 name);
88 goto out;
89 }
90
91 if (write(output_fd, &state, sizeof(state)) < 0) {
92 lxc_log_syserror("failed to send state to %d",
93 output_fd);
94 goto out;
95 }
96 continue;
97 }
98
99 if (evt.mask & IN_DELETE_SELF) {
100 close(output_fd);
101 err = 0;
102 goto out;
103 }
104
105 lxc_log_error("unknown evt for inotity (%d)", evt.mask);
106 goto out;
107 }
108
109out:
110 inotify_rm_watch(nfd, wfd);
111 close(nfd);
112 return err;
113}
114
80f41298 115static void lxc_monitor_send(struct lxc_msg *msg)
0ad19a3f 116{
117 int fd;
80f41298 118 struct sockaddr_nl addr;
0ad19a3f 119
80f41298 120 fd = socket(PF_NETLINK, SOCK_RAW, 0);
eae6543d 121 if (fd < 0) {
0ad19a3f 122 lxc_log_syserror("failed to create notification socket");
eae6543d 123 return;
124 }
0ad19a3f 125
126 memset(&addr, 0, sizeof(addr));
80f41298 127
128 addr.nl_family = AF_NETLINK;
129 addr.nl_pid = 0;
130 addr.nl_groups = MONITOR_MCGROUP;
0ad19a3f 131
eae6543d 132 sendto(fd, msg, sizeof(*msg), 0,
0ad19a3f 133 (const struct sockaddr *)&addr, sizeof(addr));
134
135 close(fd);
136}
137
eae6543d 138void lxc_monitor_send_state(const char *name, lxc_state_t state)
139{
140 struct lxc_msg msg = { .type = lxc_msg_state,
141 .value = state };
80f41298 142 strncpy(msg.name, name, sizeof(msg.name));
eae6543d 143
80f41298 144 lxc_monitor_send(&msg);
0ad19a3f 145}
146
80f41298 147int lxc_monitor_open(void)
0ad19a3f 148{
149 int fd;
80f41298 150 struct sockaddr_nl addr;
0ad19a3f 151
80f41298 152 fd = socket(PF_NETLINK, SOCK_RAW, 0);
0ad19a3f 153 if (fd < 0) {
154 lxc_log_syserror("failed to create notification socket");
e2bcd7db 155 return -LXC_ERROR_INTERNAL;
0ad19a3f 156 }
157
158 memset(&addr, 0, sizeof(addr));
159
80f41298 160 addr.nl_family = AF_NETLINK;
161 addr.nl_pid = 0;
162 addr.nl_groups = MONITOR_MCGROUP;
0ad19a3f 163
164 if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr))) {
80f41298 165 lxc_log_syserror("failed to bind to multicast group '%d'",
166 addr.nl_groups);
0ad19a3f 167 close(fd);
168 return -1;
169 }
170
171 return fd;
172}
173
eae6543d 174int lxc_monitor_read(int fd, struct lxc_msg *msg)
0ad19a3f 175{
80f41298 176 struct sockaddr_nl from;
177 socklen_t len = sizeof(from);
0ad19a3f 178 int ret;
179
80f41298 180 ret = recvfrom(fd, msg, sizeof(*msg), 0,
181 (struct sockaddr *)&from, &len);
0ad19a3f 182 if (ret < 0) {
183 lxc_log_syserror("failed to received state");
e2bcd7db 184 return -LXC_ERROR_INTERNAL;
0ad19a3f 185 }
186
187 return ret;
188}
189
190int lxc_monitor_close(int fd)
191{
192 return close(fd);
193}