]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/lxccontainer.c
Fix typos identified by lintian
[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"
28#include "log.h"
29#include <unistd.h>
30#include <sys/types.h>
31#include <sys/wait.h>
32#include <errno.h>
2a59a681 33#include <lxc/utils.h>
72d0e1cb
SG
34
35lxc_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
56static 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 }
d95db067
DE
69 if (c->slock) {
70 sem_close(c->slock);
71 c->slock = NULL;
72 }
72d0e1cb
SG
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 }
d95db067
DE
82 if (c->lxc_conf) {
83 lxc_conf_free(c->lxc_conf);
84 c->lxc_conf = NULL;
85 }
2a59a681
SH
86 if (c->config_path) {
87 free(c->config_path);
88 c->config_path = NULL;
89 }
72d0e1cb
SG
90 free(c);
91}
92
93int 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
110int 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
125static bool file_exists(char *f)
126{
127 struct stat statbuf;
128
129 return stat(f, &statbuf) == 0;
130}
131
132static 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
150out:
151 lxcunlock(c->privlock);
152 return ret;
153}
154
155static 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;
13f5be62 164 s = lxc_getstate(c->name, c->config_path);
72d0e1cb
SG
165 ret = lxc_state2str(s);
166 lxcunlock(c->slock);
167
168 return ret;
169}
170
794dd120
SH
171static bool is_stopped_nolock(struct lxc_container *c)
172{
173 lxc_state_t s;
13f5be62 174 s = lxc_getstate(c->name, c->config_path);
794dd120
SH
175 return (s == STOPPED);
176}
177
72d0e1cb
SG
178static 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
190static 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
205static 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
220static 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;
13f5be62 228 ret = get_init_pid(c->name, c->config_path);
72d0e1cb
SG
229 lxcunlock(c->slock);
230 return ret;
231}
232
12a50cc6 233static bool load_config_locked(struct lxc_container *c, const char *fname)
8eb5694b
SH
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
12a50cc6 242static bool lxcapi_load_config(struct lxc_container *c, const char *alt_file)
72d0e1cb
SG
243{
244 bool ret = false;
12a50cc6 245 const char *fname;
72d0e1cb
SG
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;
8eb5694b 256 ret = load_config_locked(c, fname);
72d0e1cb
SG
257 lxcunlock(c->slock);
258 return ret;
259}
260
261static void lxcapi_want_daemonize(struct lxc_container *c)
262{
263 if (!c)
264 return;
265 c->daemonize = 1;
266}
267
12a50cc6 268static bool lxcapi_wait(struct lxc_container *c, const char *state, int timeout)
7a44c8b4
SG
269{
270 int ret;
271
272 if (!c)
273 return false;
274
67e571de 275 ret = lxc_wait(c->name, state, timeout, c->config_path);
7a44c8b4
SG
276 return ret == 0;
277}
278
279
280static bool wait_on_daemonized_start(struct lxc_container *c)
281{
282 /* we'll probably want to make this timeout configurable? */
697fa639 283 int timeout = 5, ret, status;
7a44c8b4 284
697fa639
SH
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");
7a44c8b4
SG
292 return lxcapi_wait(c, "RUNNING", timeout);
293}
294
72d0e1cb
SG
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 */
12a50cc6 299static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv[])
72d0e1cb
SG
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) {
13f5be62 327 ret = lxc_execute(c->name, argv, 1, conf, c->config_path);
72d0e1cb
SG
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)
7a44c8b4 349 return wait_on_daemonized_start(c);
697fa639
SH
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);
72d0e1cb 358 /* like daemon(), chdir to / and redirect 0,1,2 to /dev/null */
c278cef2
SH
359 if (chdir("/")) {
360 SYSERROR("Error chdir()ing to /.");
361 return false;
362 }
72d0e1cb
SG
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
964fe051
SH
372 if (clearenv()) {
373 SYSERROR("failed to clear environment");
374 /* don't error out though */
375 }
376
72d0e1cb
SG
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
387reboot:
388 conf->reboot = 0;
13f5be62 389 ret = lxc_start(c->name, argv, conf, c->config_path);
72d0e1cb
SG
390
391 if (conf->reboot) {
392 INFO("container requested reboot");
393 conf->reboot = 0;
72d0e1cb
SG
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 */
408static 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
447out:
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
460static bool lxcapi_stop(struct lxc_container *c)
461{
462 int ret;
463
464 if (!c)
465 return false;
466
13f5be62 467 ret = lxc_stop(c->name, c->config_path);
72d0e1cb
SG
468
469 return ret == 0;
72d0e1cb
SG
470}
471
472static 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 */
486static bool create_container_dir(struct lxc_container *c)
487{
488 char *s;
489 int len, ret;
490
2a59a681 491 len = strlen(c->config_path) + strlen(c->name) + 2;
72d0e1cb
SG
492 s = malloc(len);
493 if (!s)
494 return false;
2a59a681 495 ret = snprintf(s, len, "%s/%s", c->config_path, c->name);
72d0e1cb
SG
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 */
12a50cc6 516static bool lxcapi_create(struct lxc_container *c, char *t, char *const argv[])
72d0e1cb
SG
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
2a59a681 585 len = strlen(c->config_path) + strlen(c->name) + strlen("--path=") + 2;
72d0e1cb
SG
586 patharg = malloc(len);
587 if (!patharg)
588 exit(1);
2a59a681 589 ret = snprintf(patharg, len, "--path=%s/%s", c->config_path, c->name);
72d0e1cb
SG
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
620again:
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
8eb5694b 637 if (WEXITSTATUS(status) != 0) {
72d0e1cb
SG
638 ERROR("container creation template for %s exited with %d\n",
639 c->name, WEXITSTATUS(status));
8eb5694b
SH
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);
72d0e1cb
SG
649
650out_unlock:
651 lxcunlock(c->slock);
652out:
653 if (tpath)
654 free(tpath);
655 return bret;
656}
657
658static 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);
f6144ed4 675 if (!retv && timeout > 0) {
72d0e1cb
SG
676 c->stop(c);
677 retv = c->wait(c, "STOPPED", 0); // 0 means don't wait
678 }
679 return retv;
680}
681
682static 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++;
83cab6e0 703 temp = realloc(args, (nargs+1) * sizeof(*args));
72d0e1cb
SG
704 if (!temp)
705 goto out;
706 args = temp;
707 args[nargs - 1] = arg;
708 }
709 va_end(ap);
83cab6e0 710 args[nargs] = NULL;
72d0e1cb
SG
711
712 bret = c->create(c, t, args);
713
714out:
715 if (args)
716 free(args);
717 return bret;
718}
719
12a50cc6 720static bool lxcapi_clear_config_item(struct lxc_container *c, const char *key)
72d0e1cb
SG
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
12a50cc6 734static int lxcapi_get_config_item(struct lxc_container *c, const char *key, char *retv, int inlen)
72d0e1cb
SG
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
12a50cc6 748static int lxcapi_get_keys(struct lxc_container *c, const char *key, char *retv, int inlen)
72d0e1cb
SG
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 */
bb9702b5 770#define LXC_DEFAULT_CONFIG "/etc/lxc/default.conf"
12a50cc6 771static bool lxcapi_save_config(struct lxc_container *c, const char *alt_file)
72d0e1cb
SG
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
796static 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
813again:
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
12a50cc6 832static bool lxcapi_set_config_item(struct lxc_container *c, const char *key, const char *v)
72d0e1cb
SG
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
855err:
856 lxcunlock(c->privlock);
857 return b;
858}
859
860static 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
2a59a681
SH
867static 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
afeecbba
SH
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 */
880static 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
2a59a681
SH
908static bool lxcapi_set_config_path(struct lxc_container *c, const char *path)
909{
910 char *p;
911 bool b = false;
afeecbba 912 char *oldpath = NULL;
2a59a681
SH
913
914 if (!c)
915 return b;
916
917 if (lxclock(c->privlock, 0))
918 return b;
919
920 p = strdup(path);
afeecbba
SH
921 if (!p) {
922 ERROR("Out of memory setting new lxc path");
2a59a681 923 goto err;
afeecbba
SH
924 }
925
2a59a681
SH
926 b = true;
927 if (c->config_path)
afeecbba 928 oldpath = c->config_path;
2a59a681 929 c->config_path = p;
afeecbba
SH
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 }
2a59a681 940err:
afeecbba
SH
941 if (oldpath)
942 free(oldpath);
2a59a681
SH
943 lxcunlock(c->privlock);
944 return b;
945}
946
947
794dd120
SH
948static 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;
965err:
966 lxcunlock(c->privlock);
967 return b;
968}
969
970static 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
985out:
986 lxcunlock(c->privlock);
987 return ret;
988}
989
67e571de 990const char *lxc_get_default_config_path(void)
83c98d82
DE
991{
992 return default_lxc_path();
993}
794dd120 994
afeecbba 995struct lxc_container *lxc_container_new(const char *name, const char *configpath)
72d0e1cb
SG
996{
997 struct lxc_container *c;
72d0e1cb
SG
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
afeecbba
SH
1006 if (configpath)
1007 c->config_path = strdup(configpath);
1008 else
67e571de 1009 c->config_path = strdup(default_lxc_path());
afeecbba 1010
2a59a681
SH
1011 if (!c->config_path) {
1012 fprintf(stderr, "Out of memory");
1013 goto err;
1014 }
1015
72d0e1cb
SG
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
afeecbba 1036 if (!set_config_filename(c)) {
72d0e1cb
SG
1037 fprintf(stderr, "Error allocating config file pathname\n");
1038 goto err;
1039 }
72d0e1cb
SG
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;
794dd120
SH
1067 c->get_cgroup_item = lxcapi_get_cgroup_item;
1068 c->set_cgroup_item = lxcapi_set_cgroup_item;
2a59a681
SH
1069 c->get_config_path = lxcapi_get_config_path;
1070 c->set_config_path = lxcapi_set_config_path;
72d0e1cb
SG
1071
1072 /* we'll allow the caller to update these later */
5e1e7aaf 1073 if (lxc_log_init(NULL, "none", NULL, "lxc_container", 0)) {
72d0e1cb
SG
1074 fprintf(stderr, "failed to open log\n");
1075 goto err;
1076 }
1077
72d0e1cb
SG
1078 return c;
1079
1080err:
1081 lxc_container_free(c);
1082 return NULL;
1083}
1084
4a7c7daa 1085int lxc_get_wait_states(const char **states)
72d0e1cb
SG
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}