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