]>
Commit | Line | Data |
---|---|---|
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> | |
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 | ||
80f41298 | 50 | static void lxc_monitor_send(struct lxc_msg *msg) |
0ad19a3f | 51 | { |
52 | int fd; | |
31c53c2e DL |
53 | struct sockaddr_un addr = { .sun_family = AF_UNIX }; |
54 | char *offset = &addr.sun_path[1]; | |
0ad19a3f | 55 | |
31c53c2e | 56 | strcpy(offset, "lxc-monitor"); |
80f41298 | 57 | |
31c53c2e DL |
58 | fd = socket(PF_UNIX, SOCK_DGRAM, 0); |
59 | if (fd < 0) | |
60 | return; | |
0ad19a3f | 61 | |
eae6543d | 62 | sendto(fd, msg, sizeof(*msg), 0, |
0ad19a3f | 63 | (const struct sockaddr *)&addr, sizeof(addr)); |
64 | ||
65 | close(fd); | |
66 | } | |
67 | ||
eae6543d | 68 | void lxc_monitor_send_state(const char *name, lxc_state_t state) |
69 | { | |
70 | struct lxc_msg msg = { .type = lxc_msg_state, | |
71 | .value = state }; | |
80f41298 | 72 | strncpy(msg.name, name, sizeof(msg.name)); |
f3bc28bd | 73 | msg.name[sizeof(msg.name) - 1] = 0; |
eae6543d | 74 | |
80f41298 | 75 | lxc_monitor_send(&msg); |
0ad19a3f | 76 | } |
77 | ||
80f41298 | 78 | int lxc_monitor_open(void) |
0ad19a3f | 79 | { |
31c53c2e DL |
80 | struct sockaddr_un addr = { .sun_family = AF_UNIX }; |
81 | char *offset = &addr.sun_path[1]; | |
0ad19a3f | 82 | int fd; |
0ad19a3f | 83 | |
31c53c2e | 84 | strcpy(offset, "lxc-monitor"); |
0ad19a3f | 85 | |
31c53c2e | 86 | fd = socket(PF_UNIX, SOCK_DGRAM, 0); |
2c396e12 MN |
87 | if (fd < 0) { |
88 | ERROR("socket : %s", strerror(errno)); | |
31c53c2e | 89 | return -1; |
2c396e12 | 90 | } |
0ad19a3f | 91 | |
31c53c2e | 92 | if (bind(fd, (struct sockaddr *)&addr, sizeof(addr))) { |
2c396e12 | 93 | ERROR("bind : %s", strerror(errno)); |
0ad19a3f | 94 | close(fd); |
95 | return -1; | |
96 | } | |
97 | ||
98 | return fd; | |
99 | } | |
100 | ||
72d0e1cb SG |
101 | /* timeout of 0 means return immediately; -1 means wait forever */ |
102 | int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout) | |
0ad19a3f | 103 | { |
31c53c2e | 104 | struct sockaddr_un from; |
80f41298 | 105 | socklen_t len = sizeof(from); |
0ad19a3f | 106 | int ret; |
72d0e1cb SG |
107 | fd_set rfds; |
108 | struct timeval tv; | |
109 | ||
110 | if (timeout != -1) { | |
111 | FD_ZERO(&rfds); | |
112 | FD_SET(fd, &rfds); | |
113 | ||
114 | tv.tv_sec = timeout; | |
115 | tv.tv_usec = 0; | |
116 | ||
117 | ret = select(fd+1, &rfds, NULL, NULL, &tv); | |
118 | if (ret == -1) | |
119 | return -1; | |
120 | else if (!ret) | |
121 | return -2; // timed out | |
122 | } | |
0ad19a3f | 123 | |
fa4b063c | 124 | ret = recvfrom(fd, msg, sizeof(*msg), 0, |
80f41298 | 125 | (struct sockaddr *)&from, &len); |
0ad19a3f | 126 | if (ret < 0) { |
3ab87b66 | 127 | SYSERROR("failed to receive state"); |
75b1e198 | 128 | return -1; |
0ad19a3f | 129 | } |
130 | ||
131 | return ret; | |
132 | } | |
133 | ||
72d0e1cb SG |
134 | int lxc_monitor_read(int fd, struct lxc_msg *msg) |
135 | { | |
136 | return lxc_monitor_read_timeout(fd, msg, -1); | |
137 | } | |
138 | ||
0ad19a3f | 139 | int lxc_monitor_close(int fd) |
140 | { | |
141 | return close(fd); | |
142 | } |