~serge-hallyn/ubuntu/saucy/lxc/lxc-dnsmasq

« back to all changes in this revision

Viewing changes to src/lxc/lxccontainer.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:
 
1
/* liblxcapi
 
2
 *
 
3
 * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>.
 
4
 * Copyright © 2012 Canonical Ltd.
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License version 2, as
 
8
 * published by the Free Software Foundation.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License along
 
16
 * with this program; if not, write to the Free Software Foundation, Inc.,
 
17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
18
 */
 
19
 
 
20
#include "lxc.h"
 
21
#include "state.h"
 
22
#include "lxccontainer.h"
 
23
#include "conf.h"
 
24
#include "config.h"
 
25
#include "confile.h"
 
26
#include "cgroup.h"
 
27
#include "commands.h"
 
28
#include "log.h"
 
29
#include <unistd.h>
 
30
#include <sys/types.h>
 
31
#include <sys/wait.h>
 
32
#include <errno.h>
 
33
#include <lxc/utils.h>
 
34
 
 
35
lxc_log_define(lxc_container, lxc);
 
36
 
 
37
/* LOCKING
 
38
 * c->privlock protects the struct lxc_container from multiple threads.
 
39
 * c->slock protects the on-disk container data
 
40
 * NOTHING mutexes two independent programs with their own struct
 
41
 * lxc_container for the same c->name, between API calls.  For instance,
 
42
 * c->config_read(); c->start();  Between those calls, data on disk
 
43
 * could change (which shouldn't bother the caller unless for instance
 
44
 * the rootfs get moved).  c->config_read(); update; c->config_write();
 
45
 * Two such updaters could race.  The callers should therefore check their
 
46
 * results.  Trying to prevent that would necessarily expose us to deadlocks
 
47
 * due to hung callers.  So I prefer to keep the locks only within our own
 
48
 * functions, not across functions.
 
49
 *
 
50
 * If you're going to fork while holding a lxccontainer, increment
 
51
 * c->numthreads (under privlock) before forking.  When deleting,
 
52
 * decrement numthreads under privlock, then if it hits 0 you can delete.
 
53
 * Do not ever use a lxccontainer whose numthreads you did not bump.
 
54
 */
 
55
 
 
56
static void lxc_container_free(struct lxc_container *c)
 
57
{
 
58
        if (!c)
 
59
                return;
 
60
 
 
61
        if (c->configfile) {
 
62
                free(c->configfile);
 
63
                c->configfile = NULL;
 
64
        }
 
65
        if (c->error_string) {
 
66
                free(c->error_string);
 
67
                c->error_string = NULL;
 
68
        }
 
69
        if (c->slock) {
 
70
                sem_close(c->slock);
 
71
                c->slock = NULL;
 
72
        }
 
73
        if (c->privlock) {
 
74
                sem_destroy(c->privlock);
 
75
                free(c->privlock);
 
76
                c->privlock = NULL;
 
77
        }
 
78
        if (c->name) {
 
79
                free(c->name);
 
80
                c->name = NULL;
 
81
        }
 
82
        if (c->lxc_conf) {
 
83
                lxc_conf_free(c->lxc_conf);
 
84
                c->lxc_conf = NULL;
 
85
        }
 
86
        if (c->config_path) {
 
87
                free(c->config_path);
 
88
                c->config_path = NULL;
 
89
        }
 
90
        free(c);
 
91
}
 
92
 
 
93
int lxc_container_get(struct lxc_container *c)
 
94
{
 
95
        if (!c)
 
96
                return 0;
 
97
 
 
98
        if (lxclock(c->privlock, 0))
 
99
                return 0;
 
100
        if (c->numthreads < 1) {
 
101
                // bail without trying to unlock, bc the privlock is now probably
 
102
                // in freed memory
 
103
                return 0;
 
104
        }
 
105
        c->numthreads++;
 
106
        lxcunlock(c->privlock);
 
107
        return 1;
 
108
}
 
109
 
 
110
int lxc_container_put(struct lxc_container *c)
 
111
{
 
112
        if (!c)
 
113
                return -1;
 
114
        if (lxclock(c->privlock, 0))
 
115
                return -1;
 
116
        if (--c->numthreads < 1) {
 
117
                lxcunlock(c->privlock);
 
118
                lxc_container_free(c);
 
119
                return 1;
 
120
        }
 
121
        lxcunlock(c->privlock);
 
122
        return 0;
 
123
}
 
124
 
 
125
static bool file_exists(char *f)
 
126
{
 
127
        struct stat statbuf;
 
128
 
 
129
        return stat(f, &statbuf) == 0;
 
130
}
 
131
 
 
132
static bool lxcapi_is_defined(struct lxc_container *c)
 
133
{
 
134
        struct stat statbuf;
 
135
        bool ret = false;
 
136
        int statret;
 
137
 
 
138
        if (!c)
 
139
                return false;
 
140
 
 
141
        if (lxclock(c->privlock, 0))
 
142
                return false;
 
143
        if (!c->configfile)
 
144
                goto out;
 
145
        statret = stat(c->configfile, &statbuf);
 
146
        if (statret != 0)
 
147
                goto out;
 
148
        ret = true;
 
149
 
 
150
out:
 
151
        lxcunlock(c->privlock);
 
152
        return ret;
 
153
}
 
154
 
 
155
static const char *lxcapi_state(struct lxc_container *c)
 
156
{
 
157
        const char *ret;
 
158
        lxc_state_t s;
 
159
 
 
160
        if (!c)
 
161
                return NULL;
 
162
        if (lxclock(c->slock, 0))
 
163
                return NULL;
 
164
        s = lxc_getstate(c->name, c->config_path);
 
165
        ret = lxc_state2str(s);
 
166
        lxcunlock(c->slock);
 
167
 
 
168
        return ret;
 
169
}
 
170
 
 
171
static bool is_stopped_nolock(struct lxc_container *c)
 
172
{
 
173
        lxc_state_t s;
 
174
        s = lxc_getstate(c->name, c->config_path);
 
175
        return (s == STOPPED);
 
176
}
 
177
 
 
178
static bool lxcapi_is_running(struct lxc_container *c)
 
179
{
 
180
        const char *s;
 
181
 
 
182
        if (!c)
 
183
                return false;
 
184
        s = lxcapi_state(c);
 
185
        if (!s || strcmp(s, "STOPPED") == 0)
 
186
                return false;
 
187
        return true;
 
188
}
 
189
 
 
190
static bool lxcapi_freeze(struct lxc_container *c)
 
191
{
 
192
        int ret;
 
193
        if (!c)
 
194
                return false;
 
195
 
 
196
        if (lxclock(c->slock, 0))
 
197
                return false;
 
198
        ret = lxc_freeze(c->name);
 
199
        lxcunlock(c->slock);
 
200
        if (ret)
 
201
                return false;
 
202
        return true;
 
203
}
 
204
 
 
205
static bool lxcapi_unfreeze(struct lxc_container *c)
 
206
{
 
207
        int ret;
 
208
        if (!c)
 
209
                return false;
 
210
 
 
211
        if (lxclock(c->slock, 0))
 
212
                return false;
 
213
        ret = lxc_unfreeze(c->name);
 
214
        lxcunlock(c->slock);
 
215
        if (ret)
 
216
                return false;
 
217
        return true;
 
218
}
 
219
 
 
220
static pid_t lxcapi_init_pid(struct lxc_container *c)
 
221
{
 
222
        pid_t ret;
 
223
        if (!c)
 
224
                return -1;
 
225
 
 
226
        if (lxclock(c->slock, 0))
 
227
                return -1;
 
228
        ret = get_init_pid(c->name, c->config_path);
 
229
        lxcunlock(c->slock);
 
230
        return ret;
 
231
}
 
232
 
 
233
static bool load_config_locked(struct lxc_container *c, const char *fname)
 
234
{
 
235
        if (!c->lxc_conf)
 
236
                c->lxc_conf = lxc_conf_init();
 
237
        if (c->lxc_conf && !lxc_config_read(fname, c->lxc_conf))
 
238
                return true;
 
239
        return false;
 
240
}
 
241
 
 
242
static bool lxcapi_load_config(struct lxc_container *c, const char *alt_file)
 
243
{
 
244
        bool ret = false;
 
245
        const char *fname;
 
246
        if (!c)
 
247
                return false;
 
248
 
 
249
        fname = c->configfile;
 
250
        if (alt_file)
 
251
                fname = alt_file;
 
252
        if (!fname)
 
253
                return false;
 
254
        if (lxclock(c->slock, 0))
 
255
                return false;
 
256
        ret = load_config_locked(c, fname);
 
257
        lxcunlock(c->slock);
 
258
        return ret;
 
259
}
 
260
 
 
261
static void lxcapi_want_daemonize(struct lxc_container *c)
 
262
{
 
263
        if (!c)
 
264
                return;
 
265
        c->daemonize = 1;
 
266
}
 
267
 
 
268
static bool lxcapi_wait(struct lxc_container *c, const char *state, int timeout)
 
269
{
 
270
        int ret;
 
271
 
 
272
        if (!c)
 
273
                return false;
 
274
 
 
275
        ret = lxc_wait(c->name, state, timeout);
 
276
        return ret == 0;
 
277
}
 
278
 
 
279
 
 
280
static bool wait_on_daemonized_start(struct lxc_container *c)
 
281
{
 
282
        /* we'll probably want to make this timeout configurable? */
 
283
        int timeout = 5, ret, status;
 
284
 
 
285
        /*
 
286
         * our child is going to fork again, then exit.  reap the
 
287
         * child
 
288
         */
 
289
        ret = wait(&status);
 
290
        if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0)
 
291
                DEBUG("failed waiting for first dual-fork child");
 
292
        return lxcapi_wait(c, "RUNNING", timeout);
 
293
}
 
294
 
 
295
/*
 
296
 * I can't decide if it'd be more convenient for callers if we accept '...',
 
297
 * or a null-terminated array (i.e. execl vs execv)
 
298
 */
 
299
static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv[])
 
300
{
 
301
        int ret;
 
302
        struct lxc_conf *conf;
 
303
        int daemonize = 0;
 
304
        char *default_args[] = {
 
305
                "/sbin/init",
 
306
                '\0',
 
307
        };
 
308
 
 
309
        /* container exists */
 
310
        if (!c)
 
311
                return false;
 
312
        /* container has been setup */
 
313
        if (!c->lxc_conf)
 
314
                return false;
 
315
 
 
316
        /* is this app meant to be run through lxcinit, as in lxc-execute? */
 
317
        if (useinit && !argv)
 
318
                return false;
 
319
 
 
320
        if (lxclock(c->privlock, 0))
 
321
                return false;
 
322
        conf = c->lxc_conf;
 
323
        daemonize = c->daemonize;
 
324
        lxcunlock(c->privlock);
 
325
 
 
326
        if (useinit) {
 
327
                ret = lxc_execute(c->name, argv, 1, conf, c->config_path);
 
328
                return ret == 0 ? true : false;
 
329
        }
 
330
 
 
331
        if (!argv)
 
332
                argv = default_args;
 
333
 
 
334
        /*
 
335
        * say, I'm not sure - what locks do we want here?  Any?
 
336
        * Is liblxc's locking enough here to protect the on disk
 
337
        * container?  We don't want to exclude things like lxc_info
 
338
        * while container is running...
 
339
        */
 
340
        if (daemonize) {
 
341
                if (!lxc_container_get(c))
 
342
                        return false;
 
343
                pid_t pid = fork();
 
344
                if (pid < 0) {
 
345
                        lxc_container_put(c);
 
346
                        return false;
 
347
                }
 
348
                if (pid != 0)
 
349
                        return wait_on_daemonized_start(c);
 
350
                /* second fork to be reparented by init */
 
351
                pid = fork();
 
352
                if (pid < 0) {
 
353
                        SYSERROR("Error doing dual-fork");
 
354
                        return false;
 
355
                }
 
356
                if (pid != 0)
 
357
                        exit(0);
 
358
                /* like daemon(), chdir to / and redirect 0,1,2 to /dev/null */
 
359
                if (chdir("/")) {
 
360
                        SYSERROR("Error chdir()ing to /.");
 
361
                        return false;
 
362
                }
 
363
                close(0);
 
364
                close(1);
 
365
                close(2);
 
366
                open("/dev/null", O_RDONLY);
 
367
                open("/dev/null", O_RDWR);
 
368
                open("/dev/null", O_RDWR);
 
369
                setsid();
 
370
        }
 
371
 
 
372
        if (clearenv()) {
 
373
                SYSERROR("failed to clear environment");
 
374
                /* don't error out though */
 
375
        }
 
376
 
 
377
        if (putenv("container=lxc")) {
 
378
                fprintf(stderr, "failed to set environment variable");
 
379
                if (daemonize) {
 
380
                        lxc_container_put(c);
 
381
                        exit(1);
 
382
                } else {
 
383
                        return false;
 
384
                }
 
385
        }
 
386
 
 
387
reboot:
 
388
        conf->reboot = 0;
 
389
        ret = lxc_start(c->name, argv, conf, c->config_path);
 
390
 
 
391
        if (conf->reboot) {
 
392
                INFO("container requested reboot");
 
393
                conf->reboot = 0;
 
394
                goto reboot;
 
395
        }
 
396
 
 
397
        if (daemonize) {
 
398
                lxc_container_put(c);
 
399
                exit (ret == 0 ? true : false);
 
400
        } else {
 
401
                return (ret == 0 ? true : false);
 
402
        }
 
403
}
 
404
 
 
405
/*
 
406
 * note there MUST be an ending NULL
 
407
 */
 
408
static bool lxcapi_startl(struct lxc_container *c, int useinit, ...)
 
409
{
 
410
        va_list ap;
 
411
        char **inargs = NULL, **temp;
 
412
        int n_inargs = 0;
 
413
        bool bret = false;
 
414
 
 
415
        /* container exists */
 
416
        if (!c)
 
417
                return false;
 
418
 
 
419
        /* build array of arguments if any */
 
420
        va_start(ap, useinit);
 
421
        while (1) {
 
422
                char *arg;
 
423
                arg = va_arg(ap, char *);
 
424
                if (!arg)
 
425
                        break;
 
426
                n_inargs++;
 
427
                temp = realloc(inargs, n_inargs * sizeof(*inargs));
 
428
                if (!temp)
 
429
                        goto out;
 
430
                inargs = temp;
 
431
                inargs[n_inargs - 1] = strdup(arg);  // not sure if it's safe not to copy
 
432
        }
 
433
        va_end(ap);
 
434
 
 
435
        /* add trailing NULL */
 
436
        if (n_inargs) {
 
437
                n_inargs++;
 
438
                temp = realloc(inargs, n_inargs * sizeof(*inargs));
 
439
                if (!temp)
 
440
                        goto out;
 
441
                inargs = temp;
 
442
                inargs[n_inargs - 1] = NULL;
 
443
        }
 
444
 
 
445
        bret = lxcapi_start(c, useinit, inargs);
 
446
 
 
447
out:
 
448
        if (inargs) {
 
449
                int i;
 
450
                for (i = 0; i < n_inargs; i++) {
 
451
                        if (inargs[i])
 
452
                                free(inargs[i]);
 
453
                }
 
454
                free(inargs);
 
455
        }
 
456
 
 
457
        return bret;
 
458
}
 
459
 
 
460
static bool lxcapi_stop(struct lxc_container *c)
 
461
{
 
462
        int ret;
 
463
 
 
464
        if (!c)
 
465
                return false;
 
466
 
 
467
        ret = lxc_stop(c->name, c->config_path);
 
468
 
 
469
        return ret == 0;
 
470
}
 
471
 
 
472
static bool valid_template(char *t)
 
473
{
 
474
        struct stat statbuf;
 
475
        int statret;
 
476
 
 
477
        statret = stat(t, &statbuf);
 
478
        if (statret == 0)
 
479
                return true;
 
480
        return false;
 
481
}
 
482
 
 
483
/*
 
484
 * create the standard expected container dir
 
485
 */
 
486
static bool create_container_dir(struct lxc_container *c)
 
487
{
 
488
        char *s;
 
489
        int len, ret;
 
490
 
 
491
        len = strlen(c->config_path) + strlen(c->name) + 2;
 
492
        s = malloc(len);
 
493
        if (!s)
 
494
                return false;
 
495
        ret = snprintf(s, len, "%s/%s", c->config_path, c->name);
 
496
        if (ret < 0 || ret >= len) {
 
497
                free(s);
 
498
                return false;
 
499
        }
 
500
        ret = mkdir(s, 0755);
 
501
        if (ret) {
 
502
                if (errno == EEXIST)
 
503
                        ret = 0;
 
504
                else
 
505
                        SYSERROR("failed to create container path for %s\n", c->name);
 
506
        }
 
507
        free(s);
 
508
        return ret == 0;
 
509
}
 
510
 
 
511
/*
 
512
 * backing stores not (yet) supported
 
513
 * for ->create, argv contains the arguments to pass to the template,
 
514
 * terminated by NULL.  If no arguments, you can just pass NULL.
 
515
 */
 
516
static bool lxcapi_create(struct lxc_container *c, char *t, char *const argv[])
 
517
{
 
518
        bool bret = false;
 
519
        pid_t pid;
 
520
        int ret, status;
 
521
        char *tpath = NULL;
 
522
        int len, nargs = 0;
 
523
        char **newargv;
 
524
 
 
525
        if (!c)
 
526
                return false;
 
527
 
 
528
        len = strlen(LXCTEMPLATEDIR) + strlen(t) + strlen("/lxc-") + 1;
 
529
        tpath = malloc(len);
 
530
        if (!tpath)
 
531
                return false;
 
532
        ret = snprintf(tpath, len, "%s/lxc-%s", LXCTEMPLATEDIR, t);
 
533
        if (ret < 0 || ret >= len)
 
534
                goto out;
 
535
        if (!valid_template(tpath)) {
 
536
                ERROR("bad template: %s\n", t);
 
537
                goto out;
 
538
        }
 
539
 
 
540
        if (!create_container_dir(c))
 
541
                goto out;
 
542
 
 
543
        if (!c->save_config(c, NULL)) {
 
544
                ERROR("failed to save starting configuration for %s\n", c->name);
 
545
                goto out;
 
546
        }
 
547
 
 
548
        /* we're going to fork.  but since we'll wait for our child, we
 
549
           don't need to lxc_container_get */
 
550
 
 
551
        if (lxclock(c->slock, 0)) {
 
552
                ERROR("failed to grab global container lock for %s\n", c->name);
 
553
                goto out;
 
554
        }
 
555
 
 
556
        pid = fork();
 
557
        if (pid < 0) {
 
558
                SYSERROR("failed to fork task for container creation template\n");
 
559
                goto out_unlock;
 
560
        }
 
561
 
 
562
        if (pid == 0) { // child
 
563
                char *patharg, *namearg;
 
564
                int i;
 
565
 
 
566
                close(0);
 
567
                close(1);
 
568
                close(2);
 
569
                open("/dev/null", O_RDONLY);
 
570
                open("/dev/null", O_RDWR);
 
571
                open("/dev/null", O_RDWR);
 
572
 
 
573
                /*
 
574
                 * create our new array, pre-pend the template name and
 
575
                 * base args
 
576
                 */
 
577
                if (argv)
 
578
                        for (; argv[nargs]; nargs++) ;
 
579
                nargs += 3;  // template, path and name args
 
580
                newargv = malloc(nargs * sizeof(*newargv));
 
581
                if (!newargv)
 
582
                        exit(1);
 
583
                newargv[0] = t;
 
584
 
 
585
                len = strlen(c->config_path) + strlen(c->name) + strlen("--path=") + 2;
 
586
                patharg = malloc(len);
 
587
                if (!patharg)
 
588
                        exit(1);
 
589
                ret = snprintf(patharg, len, "--path=%s/%s", c->config_path, c->name);
 
590
                if (ret < 0 || ret >= len)
 
591
                        exit(1);
 
592
                newargv[1] = patharg;
 
593
                len = strlen("--name=") + strlen(c->name) + 1;
 
594
                namearg = malloc(len);
 
595
                if (!namearg)
 
596
                        exit(1);
 
597
                ret = snprintf(namearg, len, "--name=%s", c->name);
 
598
                if (ret < 0 || ret >= len)
 
599
                        exit(1);
 
600
                newargv[2] = namearg;
 
601
 
 
602
                /* add passed-in args */
 
603
                if (argv)
 
604
                        for (i = 3; i < nargs; i++)
 
605
                                newargv[i] = argv[i-3];
 
606
 
 
607
                /* add trailing NULL */
 
608
                nargs++;
 
609
                newargv = realloc(newargv, nargs * sizeof(*newargv));
 
610
                if (!newargv)
 
611
                        exit(1);
 
612
                newargv[nargs - 1] = NULL;
 
613
 
 
614
                /* execute */
 
615
                ret = execv(tpath, newargv);
 
616
                SYSERROR("failed to execute template %s", tpath);
 
617
                exit(1);
 
618
        }
 
619
 
 
620
again:
 
621
        ret = waitpid(pid, &status, 0);
 
622
        if (ret == -1) {
 
623
                if (errno == -EINTR)
 
624
                        goto again;
 
625
                SYSERROR("waitpid failed");
 
626
                goto out_unlock;
 
627
        }
 
628
        if (ret != pid)
 
629
                goto again;
 
630
        if (!WIFEXITED(status))  { // did not exit normally
 
631
                // we could set an error code and string inside the
 
632
                // container_struct here if we like
 
633
                ERROR("container creation template exited abnormally\n");
 
634
                goto out_unlock;
 
635
        }
 
636
 
 
637
        if (WEXITSTATUS(status) != 0) {
 
638
                ERROR("container creation template for %s exited with %d\n",
 
639
                      c->name, WEXITSTATUS(status));
 
640
                goto out_unlock;
 
641
        }
 
642
 
 
643
        // now clear out the lxc_conf we have, reload from the created
 
644
        // container
 
645
        if (c->lxc_conf)
 
646
                lxc_conf_free(c->lxc_conf);
 
647
        c->lxc_conf = NULL;
 
648
        bret = load_config_locked(c, c->configfile);
 
649
 
 
650
out_unlock:
 
651
        lxcunlock(c->slock);
 
652
out:
 
653
        if (tpath)
 
654
                free(tpath);
 
655
        return bret;
 
656
}
 
657
 
 
658
static bool lxcapi_shutdown(struct lxc_container *c, int timeout)
 
659
{
 
660
        bool retv;
 
661
        pid_t pid;
 
662
 
 
663
        if (!c)
 
664
                return false;
 
665
 
 
666
        if (!timeout)
 
667
                timeout = -1;
 
668
        if (!c->is_running(c))
 
669
                return true;
 
670
        pid = c->init_pid(c);
 
671
        if (pid <= 0)
 
672
                return true;
 
673
        kill(pid, SIGPWR);
 
674
        retv = c->wait(c, "STOPPED", timeout);
 
675
        if (!retv && timeout > 0) {
 
676
                c->stop(c);
 
677
                retv = c->wait(c, "STOPPED", 0); // 0 means don't wait
 
678
        }
 
679
        return retv;
 
680
}
 
681
 
 
682
static bool lxcapi_createl(struct lxc_container *c, char *t, ...)
 
683
{
 
684
        bool bret = false;
 
685
        char **args = NULL, **temp;
 
686
        va_list ap;
 
687
        int nargs = 0;
 
688
 
 
689
        if (!c)
 
690
                return false;
 
691
 
 
692
        /*
 
693
         * since we're going to wait for create to finish, I don't think we
 
694
         * need to get a copy of the arguments.
 
695
         */
 
696
        va_start(ap, t);
 
697
        while (1) {
 
698
                char *arg;
 
699
                arg = va_arg(ap, char *);
 
700
                if (!arg)
 
701
                        break;
 
702
                nargs++;
 
703
                temp = realloc(args, (nargs+1) * sizeof(*args));
 
704
                if (!temp)
 
705
                        goto out;
 
706
                args = temp;
 
707
                args[nargs - 1] = arg;
 
708
        }
 
709
        va_end(ap);
 
710
        args[nargs] = NULL;
 
711
 
 
712
        bret = c->create(c, t, args);
 
713
 
 
714
out:
 
715
        if (args)
 
716
                free(args);
 
717
        return bret;
 
718
}
 
719
 
 
720
static bool lxcapi_clear_config_item(struct lxc_container *c, const char *key)
 
721
{
 
722
        int ret;
 
723
 
 
724
        if (!c || !c->lxc_conf)
 
725
                return false;
 
726
        if (lxclock(c->privlock, 0)) {
 
727
                return false;
 
728
        }
 
729
        ret = lxc_clear_config_item(c->lxc_conf, key);
 
730
        lxcunlock(c->privlock);
 
731
        return ret == 0;
 
732
}
 
733
 
 
734
static int lxcapi_get_config_item(struct lxc_container *c, const char *key, char *retv, int inlen)
 
735
{
 
736
        int ret;
 
737
 
 
738
        if (!c || !c->lxc_conf)
 
739
                return -1;
 
740
        if (lxclock(c->privlock, 0)) {
 
741
                return -1;
 
742
        }
 
743
        ret = lxc_get_config_item(c->lxc_conf, key, retv, inlen);
 
744
        lxcunlock(c->privlock);
 
745
        return ret;
 
746
}
 
747
 
 
748
static int lxcapi_get_keys(struct lxc_container *c, const char *key, char *retv, int inlen)
 
749
{
 
750
        if (!key)
 
751
                return lxc_listconfigs(retv, inlen);
 
752
        /*
 
753
         * Support 'lxc.network.<idx>', i.e. 'lxc.network.0'
 
754
         * This is an intelligent result to show which keys are valid given
 
755
         * the type of nic it is
 
756
         */
 
757
        if (!c || !c->lxc_conf)
 
758
                return -1;
 
759
        if (lxclock(c->privlock, 0))
 
760
                return -1;
 
761
        int ret = -1;
 
762
        if (strncmp(key, "lxc.network.", 12) == 0)
 
763
                ret =  lxc_list_nicconfigs(c->lxc_conf, key, retv, inlen);
 
764
        lxcunlock(c->privlock);
 
765
        return ret;
 
766
}
 
767
 
 
768
 
 
769
/* default config file - should probably come through autoconf */
 
770
#define LXC_DEFAULT_CONFIG "/etc/lxc/default.conf"
 
771
static bool lxcapi_save_config(struct lxc_container *c, const char *alt_file)
 
772
{
 
773
        if (!alt_file)
 
774
                alt_file = c->configfile;
 
775
        if (!alt_file)
 
776
                return false;  // should we write to stdout if no file is specified?
 
777
        if (!c->lxc_conf)
 
778
                if (!c->load_config(c, LXC_DEFAULT_CONFIG)) {
 
779
                        ERROR("Error loading default configuration file %s while saving %s\n", LXC_DEFAULT_CONFIG, c->name);
 
780
                        return false;
 
781
                }
 
782
 
 
783
        FILE *fout = fopen(alt_file, "w");
 
784
        if (!fout)
 
785
                return false;
 
786
        if (lxclock(c->privlock, 0)) {
 
787
                fclose(fout);
 
788
                return false;
 
789
        }
 
790
        write_config(fout, c->lxc_conf);
 
791
        fclose(fout);
 
792
        lxcunlock(c->privlock);
 
793
        return true;
 
794
}
 
795
 
 
796
static bool lxcapi_destroy(struct lxc_container *c)
 
797
{
 
798
        pid_t pid;
 
799
        int ret, status;
 
800
 
 
801
        if (!c)
 
802
                return false;
 
803
 
 
804
        pid = fork();
 
805
        if (pid < 0)
 
806
                return false;
 
807
        if (pid == 0) { // child
 
808
                ret = execlp("lxc-destroy", "lxc-destroy", "-n", c->name, NULL);
 
809
                perror("execl");
 
810
                exit(1);
 
811
        }
 
812
 
 
813
again:
 
814
        ret = waitpid(pid, &status, 0);
 
815
        if (ret == -1) {
 
816
                if (errno == -EINTR)
 
817
                        goto again;
 
818
                perror("waitpid");
 
819
                return false;
 
820
        }
 
821
        if (ret != pid)
 
822
                goto again;
 
823
        if (!WIFEXITED(status))  { // did not exit normally
 
824
                // we could set an error code and string inside the
 
825
                // container_struct here if we like
 
826
                return false;
 
827
        }
 
828
 
 
829
        return WEXITSTATUS(status) == 0;
 
830
}
 
831
 
 
832
static bool lxcapi_set_config_item(struct lxc_container *c, const char *key, const char *v)
 
833
{
 
834
        int ret;
 
835
        bool b = false;
 
836
        struct lxc_config_t *config;
 
837
 
 
838
        if (!c)
 
839
                return false;
 
840
 
 
841
        if (lxclock(c->privlock, 0))
 
842
                return false;
 
843
 
 
844
        if (!c->lxc_conf)
 
845
                c->lxc_conf = lxc_conf_init();
 
846
        if (!c->lxc_conf)
 
847
                goto err;
 
848
        config = lxc_getconfig(key);
 
849
        if (!config)
 
850
                goto err;
 
851
        ret = config->cb(key, v, c->lxc_conf);
 
852
        if (!ret)
 
853
                b = true;
 
854
 
 
855
err:
 
856
        lxcunlock(c->privlock);
 
857
        return b;
 
858
}
 
859
 
 
860
static char *lxcapi_config_file_name(struct lxc_container *c)
 
861
{
 
862
        if (!c || !c->configfile)
 
863
                return NULL;
 
864
        return strdup(c->configfile);
 
865
}
 
866
 
 
867
static const char *lxcapi_get_config_path(struct lxc_container *c)
 
868
{
 
869
        if (!c || !c->config_path)
 
870
                return NULL;
 
871
        return (const char *)(c->config_path);
 
872
}
 
873
 
 
874
/*
 
875
 * not for export
 
876
 * Just recalculate the c->configfile based on the
 
877
 * c->config_path, which must be set.
 
878
 * The lxc_container must be locked or not yet public.
 
879
 */
 
880
static bool set_config_filename(struct lxc_container *c)
 
881
{
 
882
        char *newpath;
 
883
        int len, ret;
 
884
 
 
885
        if (!c->config_path)
 
886
                return false;
 
887
 
 
888
        /* $lxc_path + "/" + c->name + "/" + "config" + '\0' */
 
889
        len = strlen(c->config_path) + strlen(c->name) + strlen("config") + 3;
 
890
        newpath = malloc(len);
 
891
        if (!newpath)
 
892
                return false;
 
893
 
 
894
        ret = snprintf(newpath, len, "%s/%s/config", c->config_path, c->name);
 
895
        if (ret < 0 || ret >= len) {
 
896
                fprintf(stderr, "Error printing out config file name\n");
 
897
                free(newpath);
 
898
                return false;
 
899
        }
 
900
 
 
901
        if (c->configfile)
 
902
                free(c->configfile);
 
903
        c->configfile = newpath;
 
904
 
 
905
        return true;
 
906
}
 
907
 
 
908
static bool lxcapi_set_config_path(struct lxc_container *c, const char *path)
 
909
{
 
910
        char *p;
 
911
        bool b = false;
 
912
        char *oldpath = NULL;
 
913
 
 
914
        if (!c)
 
915
                return b;
 
916
 
 
917
        if (lxclock(c->privlock, 0))
 
918
                return b;
 
919
 
 
920
        p = strdup(path);
 
921
        if (!p) {
 
922
                ERROR("Out of memory setting new lxc path");
 
923
                goto err;
 
924
        }
 
925
 
 
926
        b = true;
 
927
        if (c->config_path)
 
928
                oldpath = c->config_path;
 
929
        c->config_path = p;
 
930
 
 
931
        /* Since we've changed the config path, we have to change the
 
932
         * config file name too */
 
933
        if (!set_config_filename(c)) {
 
934
                ERROR("Out of memory setting new config filename");
 
935
                b = false;
 
936
                free(c->config_path);
 
937
                c->config_path = oldpath;
 
938
                oldpath = NULL;
 
939
        }
 
940
err:
 
941
        if (oldpath)
 
942
                free(oldpath);
 
943
        lxcunlock(c->privlock);
 
944
        return b;
 
945
}
 
946
 
 
947
 
 
948
static bool lxcapi_set_cgroup_item(struct lxc_container *c, const char *subsys, const char *value)
 
949
{
 
950
        int ret;
 
951
        bool b = false;
 
952
 
 
953
        if (!c)
 
954
                return false;
 
955
 
 
956
        if (lxclock(c->privlock, 0))
 
957
                return false;
 
958
 
 
959
        if (is_stopped_nolock(c))
 
960
                goto err;
 
961
 
 
962
        ret = lxc_cgroup_set(c->name, subsys, value);
 
963
        if (!ret)
 
964
                b = true;
 
965
err:
 
966
        lxcunlock(c->privlock);
 
967
        return b;
 
968
}
 
969
 
 
970
static int lxcapi_get_cgroup_item(struct lxc_container *c, const char *subsys, char *retv, int inlen)
 
971
{
 
972
        int ret = -1;
 
973
 
 
974
        if (!c || !c->lxc_conf)
 
975
                return -1;
 
976
 
 
977
        if (lxclock(c->privlock, 0))
 
978
                return -1;
 
979
 
 
980
        if (is_stopped_nolock(c))
 
981
                goto out;
 
982
 
 
983
        ret = lxc_cgroup_get(c->name, subsys, retv, inlen);
 
984
 
 
985
out:
 
986
        lxcunlock(c->privlock);
 
987
        return ret;
 
988
}
 
989
 
 
990
char *lxc_get_default_config_path(void)
 
991
{
 
992
        return default_lxc_path();
 
993
}
 
994
 
 
995
struct lxc_container *lxc_container_new(const char *name, const char *configpath)
 
996
{
 
997
        struct lxc_container *c;
 
998
 
 
999
        c = malloc(sizeof(*c));
 
1000
        if (!c) {
 
1001
                fprintf(stderr, "failed to malloc lxc_container\n");
 
1002
                return NULL;
 
1003
        }
 
1004
        memset(c, 0, sizeof(*c));
 
1005
 
 
1006
        if (configpath)
 
1007
                c->config_path = strdup(configpath);
 
1008
        else
 
1009
                c->config_path = default_lxc_path();
 
1010
 
 
1011
        if (!c->config_path) {
 
1012
                fprintf(stderr, "Out of memory");
 
1013
                goto err;
 
1014
        }
 
1015
 
 
1016
        c->name = malloc(strlen(name)+1);
 
1017
        if (!c->name) {
 
1018
                fprintf(stderr, "Error allocating lxc_container name\n");
 
1019
                goto err;
 
1020
        }
 
1021
        strcpy(c->name, name);
 
1022
 
 
1023
        c->numthreads = 1;
 
1024
        c->slock = lxc_newlock(name);
 
1025
        if (!c->slock) {
 
1026
                fprintf(stderr, "failed to create lock\n");
 
1027
                goto err;
 
1028
        }
 
1029
 
 
1030
        c->privlock = lxc_newlock(NULL);
 
1031
        if (!c->privlock) {
 
1032
                fprintf(stderr, "failed to alloc privlock\n");
 
1033
                goto err;
 
1034
        }
 
1035
 
 
1036
        if (!set_config_filename(c)) {
 
1037
                fprintf(stderr, "Error allocating config file pathname\n");
 
1038
                goto err;
 
1039
        }
 
1040
 
 
1041
        if (file_exists(c->configfile))
 
1042
                lxcapi_load_config(c, NULL);
 
1043
 
 
1044
        // assign the member functions
 
1045
        c->is_defined = lxcapi_is_defined;
 
1046
        c->state = lxcapi_state;
 
1047
        c->is_running = lxcapi_is_running;
 
1048
        c->freeze = lxcapi_freeze;
 
1049
        c->unfreeze = lxcapi_unfreeze;
 
1050
        c->init_pid = lxcapi_init_pid;
 
1051
        c->load_config = lxcapi_load_config;
 
1052
        c->want_daemonize = lxcapi_want_daemonize;
 
1053
        c->start = lxcapi_start;
 
1054
        c->startl = lxcapi_startl;
 
1055
        c->stop = lxcapi_stop;
 
1056
        c->config_file_name = lxcapi_config_file_name;
 
1057
        c->wait = lxcapi_wait;
 
1058
        c->set_config_item = lxcapi_set_config_item;
 
1059
        c->destroy = lxcapi_destroy;
 
1060
        c->save_config = lxcapi_save_config;
 
1061
        c->get_keys = lxcapi_get_keys;
 
1062
        c->create = lxcapi_create;
 
1063
        c->createl = lxcapi_createl;
 
1064
        c->shutdown = lxcapi_shutdown;
 
1065
        c->clear_config_item = lxcapi_clear_config_item;
 
1066
        c->get_config_item = lxcapi_get_config_item;
 
1067
        c->get_cgroup_item = lxcapi_get_cgroup_item;
 
1068
        c->set_cgroup_item = lxcapi_set_cgroup_item;
 
1069
        c->get_config_path = lxcapi_get_config_path;
 
1070
        c->set_config_path = lxcapi_set_config_path;
 
1071
 
 
1072
        /* we'll allow the caller to update these later */
 
1073
        if (lxc_log_init(NULL, "none", NULL, "lxc_container", 0)) {
 
1074
                fprintf(stderr, "failed to open log\n");
 
1075
                goto err;
 
1076
        }
 
1077
 
 
1078
        return c;
 
1079
 
 
1080
err:
 
1081
        lxc_container_free(c);
 
1082
        return NULL;
 
1083
}
 
1084
 
 
1085
int lxc_get_wait_states(const char **states)
 
1086
{
 
1087
        int i;
 
1088
 
 
1089
        if (states)
 
1090
                for (i=0; i<MAX_STATE; i++)
 
1091
                        states[i] = lxc_state2str(i);
 
1092
        return MAX_STATE;
 
1093
}