]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/monitor.c
ubuntu: Don't break when the locale is C.*
[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:
9afe19d6 7 * Daniel Lezcano <daniel.lezcano at free.fr>
0ad19a3f 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>
0ad19a3f 32#include <sys/socket.h>
31c53c2e 33#include <sys/un.h>
0ad19a3f 34#include <netinet/in.h>
35#include <net/if.h>
b113348e 36
e2bcd7db 37#include "error.h"
31c53c2e 38#include "af_unix.h"
00b3c2e2 39
36eb9bde 40#include <lxc/log.h>
00b3c2e2
CLG
41#include <lxc/state.h>
42#include <lxc/monitor.h>
36eb9bde
CLG
43
44lxc_log_define(lxc_monitor, lxc);
0ad19a3f 45
46#ifndef UNIX_PATH_MAX
47#define UNIX_PATH_MAX 108
48#endif
49
9123e471 50static void lxc_monitor_send(struct lxc_msg *msg, const char *lxcpath)
0ad19a3f 51{
52 int fd;
31c53c2e
DL
53 struct sockaddr_un addr = { .sun_family = AF_UNIX };
54 char *offset = &addr.sun_path[1];
9123e471 55 size_t ret, len;
0ad19a3f 56
9123e471
SH
57 /*
58 * addr.sun_path is only 108 bytes.
59 * should we take a hash of lxcpath? a subset of it?
60 */
61 len = sizeof(addr.sun_path) - 1;
62 ret = snprintf(offset, len, "%s/lxc-monitor", lxcpath);
63 if (ret < 0 || ret >= len) {
64 ERROR("lxcpath too long to open monitor");
65 return;
66 }
80f41298 67
31c53c2e
DL
68 fd = socket(PF_UNIX, SOCK_DGRAM, 0);
69 if (fd < 0)
70 return;
0ad19a3f 71
eae6543d 72 sendto(fd, msg, sizeof(*msg), 0,
0ad19a3f 73 (const struct sockaddr *)&addr, sizeof(addr));
74
75 close(fd);
76}
77
9123e471 78void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxcpath)
eae6543d 79{
80 struct lxc_msg msg = { .type = lxc_msg_state,
81 .value = state };
80f41298 82 strncpy(msg.name, name, sizeof(msg.name));
f3bc28bd 83 msg.name[sizeof(msg.name) - 1] = 0;
eae6543d 84
9123e471 85 lxc_monitor_send(&msg, lxcpath);
0ad19a3f 86}
87
9123e471 88int lxc_monitor_open(const char *lxcpath)
0ad19a3f 89{
31c53c2e
DL
90 struct sockaddr_un addr = { .sun_family = AF_UNIX };
91 char *offset = &addr.sun_path[1];
0ad19a3f 92 int fd;
9123e471 93 size_t ret, len;
0ad19a3f 94
9123e471
SH
95 /*
96 * addr.sun_path is only 108 bytes.
97 * should we take a hash of lxcpath? a subset of it?
98 */
99 len = sizeof(addr.sun_path) - 1;
100 ret = snprintf(offset, len, "%s/lxc-monitor", lxcpath);
101 if (ret < 0 || ret >= len) {
102 ERROR("lxcpath too long to open monitor");
103 return -1;
104 }
0ad19a3f 105
31c53c2e 106 fd = socket(PF_UNIX, SOCK_DGRAM, 0);
2c396e12
MN
107 if (fd < 0) {
108 ERROR("socket : %s", strerror(errno));
31c53c2e 109 return -1;
2c396e12 110 }
0ad19a3f 111
31c53c2e 112 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr))) {
2c396e12 113 ERROR("bind : %s", strerror(errno));
0ad19a3f 114 close(fd);
115 return -1;
116 }
117
118 return fd;
119}
120
72d0e1cb
SG
121/* timeout of 0 means return immediately; -1 means wait forever */
122int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout)
0ad19a3f 123{
31c53c2e 124 struct sockaddr_un from;
80f41298 125 socklen_t len = sizeof(from);
0ad19a3f 126 int ret;
72d0e1cb
SG
127 fd_set rfds;
128 struct timeval tv;
129
130 if (timeout != -1) {
131 FD_ZERO(&rfds);
132 FD_SET(fd, &rfds);
133
134 tv.tv_sec = timeout;
135 tv.tv_usec = 0;
136
137 ret = select(fd+1, &rfds, NULL, NULL, &tv);
138 if (ret == -1)
139 return -1;
140 else if (!ret)
141 return -2; // timed out
142 }
0ad19a3f 143
fa4b063c 144 ret = recvfrom(fd, msg, sizeof(*msg), 0,
80f41298 145 (struct sockaddr *)&from, &len);
0ad19a3f 146 if (ret < 0) {
3ab87b66 147 SYSERROR("failed to receive state");
75b1e198 148 return -1;
0ad19a3f 149 }
150
151 return ret;
152}
153
72d0e1cb
SG
154int lxc_monitor_read(int fd, struct lxc_msg *msg)
155{
156 return lxc_monitor_read_timeout(fd, msg, -1);
157}
158
0ad19a3f 159int lxc_monitor_close(int fd)
160{
161 return close(fd);
162}