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