]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/monitor.c
choose a default network interface name
[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>
31c53c2e 34#include <sys/un.h>
0ad19a3f 35#include <netinet/in.h>
36#include <net/if.h>
b113348e 37
e2bcd7db 38#include "error.h"
31c53c2e 39#include "af_unix.h"
b113348e 40#include <lxc/lxc.h>
36eb9bde
CLG
41#include <lxc/log.h>
42
43lxc_log_define(lxc_monitor, lxc);
0ad19a3f 44
45#ifndef UNIX_PATH_MAX
46#define UNIX_PATH_MAX 108
47#endif
48
49int lxc_monitor(const char *name, int output_fd)
50{
51 char path[MAXPATHLEN];
52 int err = -1, nfd, wfd, state;
53
54 nfd = inotify_init();
55 if (nfd < 0) {
36eb9bde 56 SYSERROR("failed to initialize inotify");
0ad19a3f 57 return -1;
58 }
59
60 snprintf(path, MAXPATHLEN, LXCPATH "/%s/state", name);
61
62 wfd = inotify_add_watch(nfd, path, IN_DELETE_SELF|IN_CLOSE_WRITE);
63 if (wfd < 0) {
36eb9bde 64 SYSERROR("failed to add a watch on %s", path);
0ad19a3f 65 goto out;
66 }
67
68 for(;;) {
69 struct inotify_event evt;
70
71 if (read(nfd, &evt, sizeof(evt)) < 0) {
36eb9bde 72 SYSERROR("failed to read inotify event");
0ad19a3f 73 goto out;
74 }
75
76 if (evt.mask & IN_CLOSE_WRITE) {
77
78 state = lxc_getstate(name);
79 if (state < 0) {
36eb9bde 80 ERROR("failed to get the state for %s",
0ad19a3f 81 name);
82 goto out;
83 }
84
85 if (write(output_fd, &state, sizeof(state)) < 0) {
36eb9bde 86 SYSERROR("failed to send state to %d",
0ad19a3f 87 output_fd);
88 goto out;
89 }
90 continue;
91 }
92
93 if (evt.mask & IN_DELETE_SELF) {
94 close(output_fd);
95 err = 0;
96 goto out;
97 }
98
36eb9bde 99 ERROR("unknown evt for inotity (%d)", evt.mask);
0ad19a3f 100 goto out;
101 }
102
103out:
104 inotify_rm_watch(nfd, wfd);
105 close(nfd);
106 return err;
107}
108
80f41298 109static void lxc_monitor_send(struct lxc_msg *msg)
0ad19a3f 110{
111 int fd;
31c53c2e
DL
112 struct sockaddr_un addr = { .sun_family = AF_UNIX };
113 char *offset = &addr.sun_path[1];
0ad19a3f 114
31c53c2e 115 strcpy(offset, "lxc-monitor");
80f41298 116
31c53c2e
DL
117 fd = socket(PF_UNIX, SOCK_DGRAM, 0);
118 if (fd < 0)
119 return;
0ad19a3f 120
eae6543d 121 sendto(fd, msg, sizeof(*msg), 0,
0ad19a3f 122 (const struct sockaddr *)&addr, sizeof(addr));
123
124 close(fd);
125}
126
eae6543d 127void lxc_monitor_send_state(const char *name, lxc_state_t state)
128{
129 struct lxc_msg msg = { .type = lxc_msg_state,
130 .value = state };
80f41298 131 strncpy(msg.name, name, sizeof(msg.name));
eae6543d 132
80f41298 133 lxc_monitor_send(&msg);
0ad19a3f 134}
135
80f41298 136int lxc_monitor_open(void)
0ad19a3f 137{
31c53c2e
DL
138 struct sockaddr_un addr = { .sun_family = AF_UNIX };
139 char *offset = &addr.sun_path[1];
0ad19a3f 140 int fd;
0ad19a3f 141
31c53c2e 142 strcpy(offset, "lxc-monitor");
0ad19a3f 143
31c53c2e
DL
144 fd = socket(PF_UNIX, SOCK_DGRAM, 0);
145 if (fd < 0)
146 return -1;
0ad19a3f 147
31c53c2e 148 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr))) {
0ad19a3f 149 close(fd);
150 return -1;
151 }
152
153 return fd;
154}
155
eae6543d 156int lxc_monitor_read(int fd, struct lxc_msg *msg)
0ad19a3f 157{
31c53c2e 158 struct sockaddr_un from;
80f41298 159 socklen_t len = sizeof(from);
0ad19a3f 160 int ret;
161
80f41298 162 ret = recvfrom(fd, msg, sizeof(*msg), 0,
163 (struct sockaddr *)&from, &len);
0ad19a3f 164 if (ret < 0) {
3ab87b66 165 SYSERROR("failed to receive state");
75b1e198 166 return -1;
0ad19a3f 167 }
168
169 return ret;
170}
171
172int lxc_monitor_close(int fd)
173{
174 return close(fd);
175}