]>
Commit | Line | Data |
---|---|---|
5e97c3fc | 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> | |
0ad19a3f | 24 | #include <string.h> |
25 | #include <fcntl.h> | |
26 | #include <errno.h> | |
5e97c3fc | 27 | #include <unistd.h> |
5e97c3fc | 28 | #include <sys/types.h> |
0ad19a3f | 29 | #include <sys/types.h> |
30 | #include <sys/param.h> | |
31 | #include <sys/stat.h> | |
32 | #include <sys/file.h> | |
5e97c3fc | 33 | |
36eb9bde | 34 | #include <lxc/log.h> |
00b3c2e2 | 35 | #include <lxc/start.h> |
108ed092 | 36 | #include <lxc/cgroup.h> |
e98fe68b | 37 | #include "commands.h" |
881450bb | 38 | #include "config.h" |
36eb9bde CLG |
39 | |
40 | lxc_log_define(lxc_state, lxc); | |
0ad19a3f | 41 | |
42 | static char *strstate[] = { | |
43 | "STOPPED", "STARTING", "RUNNING", "STOPPING", | |
fa082227 | 44 | "ABORTING", "FREEZING", "FROZEN", "THAWED", |
0ad19a3f | 45 | }; |
46 | ||
47 | const char *lxc_state2str(lxc_state_t state) | |
48 | { | |
49 | if (state < STOPPED || state > MAX_STATE - 1) | |
50 | return NULL; | |
51 | return strstate[state]; | |
52 | } | |
5e97c3fc | 53 | |
0ad19a3f | 54 | lxc_state_t lxc_str2state(const char *state) |
5e97c3fc | 55 | { |
0ad19a3f | 56 | int i, len; |
57 | len = sizeof(strstate)/sizeof(strstate[0]); | |
58 | for (i = 0; i < len; i++) | |
59 | if (!strcmp(strstate[i], state)) | |
60 | return i; | |
3ab87b66 | 61 | |
439358bf | 62 | ERROR("invalid state '%s'", state); |
0ad19a3f | 63 | return -1; |
5e97c3fc | 64 | } |
65 | ||
0ad19a3f | 66 | int lxc_rmstate(const char *name) |
67 | { | |
68 | char file[MAXPATHLEN]; | |
69 | snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name); | |
70 | unlink(file); | |
5e97c3fc | 71 | return 0; |
72 | } | |
73 | ||
0ad19a3f | 74 | static int freezer_state(const char *name) |
75 | { | |
fa082227 | 76 | char *nsgroup; |
0ad19a3f | 77 | char freezer[MAXPATHLEN]; |
78 | char status[MAXPATHLEN]; | |
79 | FILE *file; | |
80 | int err; | |
35d2c3e7 | 81 | |
fa082227 MN |
82 | err = lxc_cgroup_path_get(&nsgroup, name); |
83 | if (err) | |
84 | return -1; | |
85 | ||
86 | snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup); | |
0ad19a3f | 87 | |
88 | file = fopen(freezer, "r"); | |
89 | if (!file) | |
90 | return -1; | |
91 | ||
92 | err = fscanf(file, "%s", status); | |
93 | fclose(file); | |
94 | ||
95 | if (err == EOF) { | |
36eb9bde | 96 | SYSERROR("failed to read %s", freezer); |
0ad19a3f | 97 | return -1; |
98 | } | |
99 | ||
100 | return lxc_str2state(status); | |
101 | } | |
102 | ||
fa082227 | 103 | static lxc_state_t __lxc_getstate(const char *name) |
e98fe68b DL |
104 | { |
105 | struct lxc_command command = { | |
106 | .request = { .type = LXC_COMMAND_STATE }, | |
107 | }; | |
108 | ||
d97b36f8 DL |
109 | int ret, stopped = 0; |
110 | ||
111 | ret = lxc_command(name, &command, &stopped); | |
112 | if (ret < 0 && stopped) | |
113 | return STOPPED; | |
e98fe68b | 114 | |
e98fe68b DL |
115 | if (ret < 0) { |
116 | ERROR("failed to send command"); | |
117 | return -1; | |
118 | } | |
119 | ||
120 | if (!ret) { | |
121 | WARN("'%s' has stopped before sending its state", name); | |
122 | return -1; | |
123 | } | |
124 | ||
125 | if (command.answer.ret < 0) { | |
126 | ERROR("failed to get state for '%s': %s", | |
127 | name, strerror(-command.answer.ret)); | |
128 | return -1; | |
129 | } | |
130 | ||
131 | DEBUG("'%s' is in '%s' state", name, lxc_state2str(command.answer.ret)); | |
132 | ||
133 | return command.answer.ret; | |
134 | } | |
135 | ||
fa082227 | 136 | lxc_state_t lxc_getstate(const char *name) |
0ad19a3f | 137 | { |
138 | int state = freezer_state(name); | |
139 | if (state != FROZEN && state != FREEZING) | |
fa082227 | 140 | state = __lxc_getstate(name); |
0ad19a3f | 141 | return state; |
142 | } | |
e98fe68b DL |
143 | |
144 | /*---------------------------------------------------------------------------- | |
145 | * functions used by lxc-start mainloop | |
146 | * to handle above command request. | |
147 | *--------------------------------------------------------------------------*/ | |
148 | extern int lxc_state_callback(int fd, struct lxc_request *request, | |
149 | struct lxc_handler *handler) | |
150 | { | |
151 | struct lxc_answer answer; | |
152 | int ret; | |
153 | ||
154 | answer.ret = handler->state; | |
155 | ||
156 | ret = send(fd, &answer, sizeof(answer), 0); | |
157 | if (ret < 0) { | |
158 | WARN("failed to send answer to the peer"); | |
159 | goto out; | |
160 | } | |
161 | ||
162 | if (ret != sizeof(answer)) { | |
163 | ERROR("partial answer sent"); | |
164 | goto out; | |
165 | } | |
166 | ||
167 | out: | |
168 | return ret; | |
169 | } | |
170 |