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