~xnox/ubuntu/saucy/lxc/dep8

« back to all changes in this revision

Viewing changes to src/lxc/state.c

  • Committer: Stéphane Graber
  • Date: 2013-02-18 15:20:18 UTC
  • mto: This revision was merged to the branch mainline in revision 190.
  • Revision ID: stgraber@ubuntu.com-20130218152018-ls2gi9hkqs2kuhj8
Tags: upstream-0.9.0~alpha3
Import upstream version 0.9.0~alpha3

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
22
 */
23
23
#include <stdio.h>
 
24
#include <stdlib.h>
24
25
#include <string.h>
25
26
#include <fcntl.h>
26
27
#include <errno.h>
31
32
#include <sys/stat.h>
32
33
#include <sys/file.h>
33
34
 
 
35
#include <lxc/lxc.h>
34
36
#include <lxc/log.h>
35
37
#include <lxc/start.h>
36
38
#include <lxc/cgroup.h>
 
39
#include <lxc/monitor.h>
37
40
#include "commands.h"
38
41
#include "config.h"
39
42
 
75
78
        if (err)
76
79
                return -1;
77
80
 
78
 
        snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup);
 
81
        err = snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup);
 
82
        if (err < 0 || err >= MAXPATHLEN)
 
83
                return -1;
79
84
 
80
85
        file = fopen(freezer, "r");
81
86
        if (!file)
92
97
        return lxc_str2state(status);
93
98
}
94
99
 
95
 
static lxc_state_t __lxc_getstate(const char *name)
 
100
static lxc_state_t __lxc_getstate(const char *name, const char *lxcpath)
96
101
{
97
102
        struct lxc_command command = {
98
103
                .request = { .type = LXC_COMMAND_STATE },
100
105
 
101
106
        int ret, stopped = 0;
102
107
 
103
 
        ret = lxc_command(name, &command, &stopped);
 
108
        ret = lxc_command(name, &command, &stopped, lxcpath);
104
109
        if (ret < 0 && stopped)
105
110
                return STOPPED;
106
111
 
125
130
        return command.answer.ret;
126
131
}
127
132
 
128
 
lxc_state_t lxc_getstate(const char *name)
 
133
lxc_state_t lxc_getstate(const char *name, const char *lxcpath)
129
134
{
130
135
        int state = freezer_state(name);
131
136
        if (state != FROZEN && state != FREEZING)
132
 
                state = __lxc_getstate(name);
 
137
                state = __lxc_getstate(name, lxcpath);
133
138
        return state;
134
139
}
135
140
 
160
165
        return ret;
161
166
}
162
167
 
 
168
static int fillwaitedstates(const char *strstates, int *states)
 
169
{
 
170
        char *token, *saveptr = NULL;
 
171
        char *strstates_dup = strdup(strstates);
 
172
        int state;
 
173
 
 
174
        if (!strstates_dup)
 
175
                return -1;
 
176
 
 
177
        token = strtok_r(strstates_dup, "|", &saveptr);
 
178
        while (token) {
 
179
 
 
180
                state = lxc_str2state(token);
 
181
                if (state < 0) {
 
182
                        free(strstates_dup);
 
183
                        return -1;
 
184
                }
 
185
 
 
186
                states[state] = 1;
 
187
 
 
188
                token = strtok_r(NULL, "|", &saveptr);
 
189
        }
 
190
        free(strstates_dup);
 
191
        return 0;
 
192
}
 
193
 
 
194
extern int lxc_wait(const char *lxcname, const char *states, int timeout)
 
195
{
 
196
        struct lxc_msg msg;
 
197
        int state, ret;
 
198
        int s[MAX_STATE] = { }, fd;
 
199
        /* TODO: add cmdline arg to specify lxcpath */
 
200
        char *lxcpath = NULL;
 
201
 
 
202
        if (fillwaitedstates(states, s))
 
203
                return -1;
 
204
 
 
205
        fd = lxc_monitor_open();
 
206
        if (fd < 0)
 
207
                return -1;
 
208
 
 
209
        /*
 
210
         * if container present,
 
211
         * then check if already in requested state
 
212
         */
 
213
        ret = -1;
 
214
        state = lxc_getstate(lxcname, lxcpath);
 
215
        if (state < 0) {
 
216
                goto out_close;
 
217
        } else if ((state >= 0) && (s[state])) {
 
218
                ret = 0;
 
219
                goto out_close;
 
220
        }
 
221
 
 
222
        for (;;) {
 
223
                int elapsed_time, curtime = 0;
 
224
                struct timeval tv;
 
225
                int stop = 0;
 
226
                int retval;
 
227
 
 
228
                if (timeout != -1) {
 
229
                        retval = gettimeofday(&tv, NULL);
 
230
                        if (retval)
 
231
                                goto out_close;
 
232
                        curtime = tv.tv_sec;
 
233
                }
 
234
                if (lxc_monitor_read_timeout(fd, &msg, timeout) < 0)
 
235
                        goto out_close;
 
236
 
 
237
                if (timeout != -1) {
 
238
                        retval = gettimeofday(&tv, NULL);
 
239
                        if (retval)
 
240
                                goto out_close;
 
241
                        elapsed_time = tv.tv_sec - curtime;
 
242
                        if (timeout - elapsed_time <= 0)
 
243
                                stop = 1;
 
244
                        timeout -= elapsed_time;
 
245
                }
 
246
 
 
247
                if (strcmp(lxcname, msg.name)) {
 
248
                        if (stop) {
 
249
                                ret = -2;
 
250
                                goto out_close;
 
251
                        }
 
252
                        continue;
 
253
                }
 
254
 
 
255
                switch (msg.type) {
 
256
                case lxc_msg_state:
 
257
                        if (msg.value < 0 || msg.value >= MAX_STATE) {
 
258
                                ERROR("Receive an invalid state number '%d'",
 
259
                                        msg.value);
 
260
                                goto out_close;
 
261
                        }
 
262
 
 
263
                        if (s[msg.value]) {
 
264
                                ret = 0;
 
265
                                goto out_close;
 
266
                        }
 
267
                        break;
 
268
                default:
 
269
                        if (stop) {
 
270
                                ret = -2;
 
271
                                goto out_close;
 
272
                        }
 
273
                        /* just ignore garbage */
 
274
                        break;
 
275
                }
 
276
        }
 
277
 
 
278
out_close:
 
279
        lxc_monitor_close(fd);
 
280
        return ret;
 
281
}