]>
Commit | Line | Data |
---|---|---|
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 | |
44 | lxc_log_define(lxc_monitor, lxc); | |
0ad19a3f | 45 | |
46 | #ifndef UNIX_PATH_MAX | |
47 | #define UNIX_PATH_MAX 108 | |
48 | #endif | |
49 | ||
9123e471 | 50 | static 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 | 78 | void 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 | 88 | int 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 */ |
122 | int 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 |
154 | int lxc_monitor_read(int fd, struct lxc_msg *msg) |
155 | { | |
156 | return lxc_monitor_read_timeout(fd, msg, -1); | |
157 | } | |
158 | ||
0ad19a3f | 159 | int lxc_monitor_close(int fd) |
160 | { | |
161 | return close(fd); | |
162 | } |