]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/lxccontainer.c
{start,lxccontainer}: add lxc_free_handler()
[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 *
d75462e4
SH
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
72d0e1cb
SG
19 */
20
9be53773 21#define _GNU_SOURCE
38683db4 22#include <dirent.h>
9be53773 23#include <errno.h>
93dc5327 24#include <fcntl.h>
38683db4 25#include <grp.h>
f2363e38 26#include <libgen.h>
38683db4
CB
27#include <pthread.h>
28#include <sched.h>
29#include <stdarg.h>
d659597e 30#include <stdint.h>
9fc7f8c0 31#include <stdio.h>
38683db4
CB
32#include <unistd.h>
33#include <arpa/inet.h>
66c1f8c2 34#include <sys/sysmacros.h>
38683db4
CB
35#include <sys/mman.h>
36#include <sys/mount.h>
5f7eba0b 37#include <sys/syscall.h>
38683db4
CB
38#include <sys/types.h>
39#include <sys/wait.h>
f2363e38 40
38683db4 41#include "attach.h"
d8e48992
CB
42#include "bdev.h"
43#include "lxcoverlay.h"
44#include "lxcbtrfs.h"
38683db4 45#include "cgroup.h"
72d0e1cb 46#include "conf.h"
38683db4
CB
47#include "config.h"
48#include "commands.h"
72d0e1cb 49#include "confile.h"
b5159817 50#include "console.h"
e29fe1dd 51#include "criu.h"
72d0e1cb 52#include "log.h"
38683db4
CB
53#include "lxc.h"
54#include "lxccontainer.h"
55#include "lxclock.h"
f2363e38
ÇO
56#include "monitor.h"
57#include "namespace.h"
fed29fad 58#include "network.h"
735f2c6e 59#include "sync.h"
aa460476 60#include "start.h"
38683db4
CB
61#include "state.h"
62#include "utils.h"
63#include "version.h"
4ba0d9af 64
af6824fc
ST
65/* major()/minor() */
66#ifdef MAJOR_IN_MKDEV
67# include <sys/mkdev.h>
68#endif
af6824fc 69
4ba0d9af 70#if HAVE_IFADDRS_H
9c83a661 71#include <ifaddrs.h>
4ba0d9af
SG
72#else
73#include <../include/ifaddrs.h>
74#endif
72d0e1cb 75
684f79a5
SG
76#if IS_BIONIC
77#include <../include/lxcmntent.h>
78#else
79#include <mntent.h>
80#endif
81
a9a0ed90
ÇO
82#define MAX_BUFFER 4096
83
c868b261
ÇO
84#define NOT_SUPPORTED_ERROR "the requested function %s is not currently supported with unprivileged containers"
85
5f7eba0b
SG
86/* Define faccessat() if missing from the C library */
87#ifndef HAVE_FACCESSAT
88static int faccessat(int __fd, const char *__file, int __type, int __flag)
89{
90#ifdef __NR_faccessat
91return syscall(__NR_faccessat, __fd, __file, __type, __flag);
92#else
93errno = ENOSYS;
94return -1;
95#endif
96}
97#endif
98
72d0e1cb
SG
99lxc_log_define(lxc_container, lxc);
100
858377e4
SH
101static bool do_lxcapi_destroy(struct lxc_container *c);
102static const char *lxcapi_get_config_path(struct lxc_container *c);
103#define do_lxcapi_get_config_path(c) lxcapi_get_config_path(c)
104static bool do_lxcapi_set_config_item(struct lxc_container *c, const char *key, const char *v);
105static bool container_destroy(struct lxc_container *c);
106static bool get_snappath_dir(struct lxc_container *c, char *snappath);
107static bool lxcapi_snapshot_destroy_all(struct lxc_container *c);
108static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file);
109
a41f104b
SH
110static bool config_file_exists(const char *lxcpath, const char *cname)
111{
112 /* $lxcpath + '/' + $cname + '/config' + \0 */
113 int ret, len = strlen(lxcpath) + strlen(cname) + 9;
114 char *fname = alloca(len);
115
116 ret = snprintf(fname, len, "%s/%s/config", lxcpath, cname);
117 if (ret < 0 || ret >= len)
118 return false;
119
120 return file_exists(fname);
121}
122
3e625e2d
SH
123/*
124 * A few functions to help detect when a container creation failed.
125 * If a container creation was killed partway through, then trying
126 * to actually start that container could harm the host. We detect
127 * this by creating a 'partial' file under the container directory,
128 * and keeping an advisory lock. When container creation completes,
129 * we remove that file. When we load or try to start a container, if
130 * we find that file, without a flock, we remove the container.
131 */
74a3920a 132static int ongoing_create(struct lxc_container *c)
3e625e2d
SH
133{
134 int len = strlen(c->config_path) + strlen(c->name) + 10;
135 char *path = alloca(len);
136 int fd, ret;
93dc5327
SH
137 struct flock lk;
138
3e625e2d
SH
139 ret = snprintf(path, len, "%s/%s/partial", c->config_path, c->name);
140 if (ret < 0 || ret >= len) {
141 ERROR("Error writing partial pathname");
142 return -1;
143 }
144
145 if (!file_exists(path))
146 return 0;
025ed0f3 147 fd = open(path, O_RDWR);
025ed0f3 148 if (fd < 0) {
3e625e2d
SH
149 // give benefit of the doubt
150 SYSERROR("Error opening partial file");
3e625e2d
SH
151 return 0;
152 }
93dc5327
SH
153 lk.l_type = F_WRLCK;
154 lk.l_whence = SEEK_SET;
155 lk.l_start = 0;
156 lk.l_len = 0;
157 lk.l_pid = -1;
158 if (fcntl(fd, F_GETLK, &lk) == 0 && lk.l_pid != -1) {
3e625e2d
SH
159 // create is still ongoing
160 close(fd);
3e625e2d
SH
161 return 1;
162 }
163 // create completed but partial is still there.
164 close(fd);
3e625e2d
SH
165 return 2;
166}
167
74a3920a 168static int create_partial(struct lxc_container *c)
3e625e2d
SH
169{
170 // $lxcpath + '/' + $name + '/partial' + \0
171 int len = strlen(c->config_path) + strlen(c->name) + 10;
172 char *path = alloca(len);
173 int fd, ret;
93dc5327
SH
174 struct flock lk;
175
3e625e2d
SH
176 ret = snprintf(path, len, "%s/%s/partial", c->config_path, c->name);
177 if (ret < 0 || ret >= len) {
178 ERROR("Error writing partial pathname");
179 return -1;
180 }
93dc5327 181 if ((fd=open(path, O_RDWR | O_CREAT | O_EXCL, 0755)) < 0) {
740fe426 182 SYSERROR("Error creating partial file");
3e625e2d
SH
183 return -1;
184 }
93dc5327
SH
185 lk.l_type = F_WRLCK;
186 lk.l_whence = SEEK_SET;
187 lk.l_start = 0;
188 lk.l_len = 0;
189 if (fcntl(fd, F_SETLKW, &lk) < 0) {
3e625e2d
SH
190 SYSERROR("Error locking partial file %s", path);
191 close(fd);
3e625e2d
SH
192 return -1;
193 }
3e625e2d
SH
194
195 return fd;
196}
197
74a3920a 198static void remove_partial(struct lxc_container *c, int fd)
3e625e2d
SH
199{
200 // $lxcpath + '/' + $name + '/partial' + \0
201 int len = strlen(c->config_path) + strlen(c->name) + 10;
202 char *path = alloca(len);
203 int ret;
204
205 close(fd);
206 ret = snprintf(path, len, "%s/%s/partial", c->config_path, c->name);
207 if (ret < 0 || ret >= len) {
208 ERROR("Error writing partial pathname");
209 return;
210 }
3e625e2d
SH
211 if (unlink(path) < 0)
212 SYSERROR("Error unlink partial file %s", path);
3e625e2d
SH
213}
214
72d0e1cb 215/* LOCKING
3bc449ed
SH
216 * 1. container_mem_lock(c) protects the struct lxc_container from multiple threads.
217 * 2. container_disk_lock(c) protects the on-disk container data - in particular the
218 * container configuration file.
219 * The container_disk_lock also takes the container_mem_lock.
220 * 3. thread_mutex protects process data (ex: fd table) from multiple threads.
72d0e1cb
SG
221 * NOTHING mutexes two independent programs with their own struct
222 * lxc_container for the same c->name, between API calls. For instance,
223 * c->config_read(); c->start(); Between those calls, data on disk
224 * could change (which shouldn't bother the caller unless for instance
225 * the rootfs get moved). c->config_read(); update; c->config_write();
226 * Two such updaters could race. The callers should therefore check their
227 * results. Trying to prevent that would necessarily expose us to deadlocks
228 * due to hung callers. So I prefer to keep the locks only within our own
229 * functions, not across functions.
230 *
3bc449ed 231 * If you're going to clone while holding a lxccontainer, increment
72d0e1cb
SG
232 * c->numthreads (under privlock) before forking. When deleting,
233 * decrement numthreads under privlock, then if it hits 0 you can delete.
234 * Do not ever use a lxccontainer whose numthreads you did not bump.
235 */
236
237static void lxc_container_free(struct lxc_container *c)
238{
239 if (!c)
240 return;
241
f10fad2f
ME
242 free(c->configfile);
243 c->configfile = NULL;
244 free(c->error_string);
245 c->error_string = NULL;
d95db067 246 if (c->slock) {
df271a59 247 lxc_putlock(c->slock);
d95db067
DE
248 c->slock = NULL;
249 }
72d0e1cb 250 if (c->privlock) {
df271a59 251 lxc_putlock(c->privlock);
72d0e1cb
SG
252 c->privlock = NULL;
253 }
f10fad2f
ME
254 free(c->name);
255 c->name = NULL;
d95db067
DE
256 if (c->lxc_conf) {
257 lxc_conf_free(c->lxc_conf);
258 c->lxc_conf = NULL;
259 }
f10fad2f
ME
260 free(c->config_path);
261 c->config_path = NULL;
72cf75fa 262
72d0e1cb
SG
263 free(c);
264}
265
43d1aa34
SH
266/*
267 * Consider the following case:
268freer | racing get()er
269==================================================================
270lxc_container_put() | lxc_container_get()
271\ lxclock(c->privlock) | c->numthreads < 1? (no)
272\ c->numthreads = 0 | \ lxclock(c->privlock) -> waits
273\ lxcunlock() | \
274\ lxc_container_free() | \ lxclock() returns
275 | \ c->numthreads < 1 -> return 0
276\ \ (free stuff) |
277\ \ sem_destroy(privlock) |
278
279 * When the get()er checks numthreads the first time, one of the following
280 * is true:
281 * 1. freer has set numthreads = 0. get() returns 0
282 * 2. freer is between lxclock and setting numthreads to 0. get()er will
283 * sem_wait on privlock, get lxclock after freer() drops it, then see
284 * numthreads is 0 and exit without touching lxclock again..
285 * 3. freer has not yet locked privlock. If get()er runs first, then put()er
286 * will see --numthreads = 1 and not call lxc_container_free().
287*/
288
72d0e1cb
SG
289int lxc_container_get(struct lxc_container *c)
290{
291 if (!c)
292 return 0;
293
43d1aa34
SH
294 // if someone else has already started freeing the container, don't
295 // try to take the lock, which may be invalid
296 if (c->numthreads < 1)
297 return 0;
298
5cee8c50 299 if (container_mem_lock(c))
72d0e1cb
SG
300 return 0;
301 if (c->numthreads < 1) {
302 // bail without trying to unlock, bc the privlock is now probably
303 // in freed memory
304 return 0;
305 }
306 c->numthreads++;
5cee8c50 307 container_mem_unlock(c);
72d0e1cb
SG
308 return 1;
309}
310
311int lxc_container_put(struct lxc_container *c)
312{
313 if (!c)
314 return -1;
5cee8c50 315 if (container_mem_lock(c))
72d0e1cb
SG
316 return -1;
317 if (--c->numthreads < 1) {
5cee8c50 318 container_mem_unlock(c);
72d0e1cb
SG
319 lxc_container_free(c);
320 return 1;
321 }
5cee8c50 322 container_mem_unlock(c);
72d0e1cb
SG
323 return 0;
324}
325
858377e4 326static bool do_lxcapi_is_defined(struct lxc_container *c)
72d0e1cb
SG
327{
328 struct stat statbuf;
329 bool ret = false;
330 int statret;
331
332 if (!c)
333 return false;
334
5cee8c50 335 if (container_mem_lock(c))
72d0e1cb
SG
336 return false;
337 if (!c->configfile)
338 goto out;
339 statret = stat(c->configfile, &statbuf);
340 if (statret != 0)
341 goto out;
342 ret = true;
343
344out:
5cee8c50 345 container_mem_unlock(c);
72d0e1cb
SG
346 return ret;
347}
348
858377e4
SH
349#define WRAP_API(rettype, fnname) \
350static rettype fnname(struct lxc_container *c) \
351{ \
352 rettype ret; \
8164f0e2
TA
353 bool reset_config = false; \
354 \
355 if (!current_config && c && c->lxc_conf) { \
356 current_config = c->lxc_conf; \
357 reset_config = true; \
358 } \
359 \
858377e4 360 ret = do_##fnname(c); \
8164f0e2
TA
361 if (reset_config) \
362 current_config = NULL; \
363 \
858377e4
SH
364 return ret; \
365}
366
367#define WRAP_API_1(rettype, fnname, t1) \
368static rettype fnname(struct lxc_container *c, t1 a1) \
369{ \
370 rettype ret; \
8164f0e2
TA
371 bool reset_config = false; \
372 \
373 if (!current_config && c && c->lxc_conf) { \
374 current_config = c->lxc_conf; \
375 reset_config = true; \
376 } \
377 \
858377e4 378 ret = do_##fnname(c, a1); \
8164f0e2
TA
379 if (reset_config) \
380 current_config = NULL; \
381 \
858377e4
SH
382 return ret; \
383}
384
385#define WRAP_API_2(rettype, fnname, t1, t2) \
386static rettype fnname(struct lxc_container *c, t1 a1, t2 a2) \
387{ \
388 rettype ret; \
8164f0e2
TA
389 bool reset_config = false; \
390 \
391 if (!current_config && c && c->lxc_conf) { \
392 current_config = c->lxc_conf; \
393 reset_config = true; \
394 } \
395 \
858377e4 396 ret = do_##fnname(c, a1, a2); \
8164f0e2
TA
397 if (reset_config) \
398 current_config = NULL; \
399 \
858377e4
SH
400 return ret; \
401}
402
403#define WRAP_API_3(rettype, fnname, t1, t2, t3) \
404static rettype fnname(struct lxc_container *c, t1 a1, t2 a2, t3 a3) \
405{ \
406 rettype ret; \
8164f0e2
TA
407 bool reset_config = false; \
408 \
409 if (!current_config && c && c->lxc_conf) { \
410 current_config = c->lxc_conf; \
411 reset_config = true; \
412 } \
413 \
858377e4 414 ret = do_##fnname(c, a1, a2, a3); \
8164f0e2
TA
415 if (reset_config) \
416 current_config = NULL; \
417 \
858377e4
SH
418 return ret; \
419}
420
421WRAP_API(bool, lxcapi_is_defined)
422
423static const char *do_lxcapi_state(struct lxc_container *c)
72d0e1cb 424{
72d0e1cb
SG
425 lxc_state_t s;
426
427 if (!c)
428 return NULL;
13f5be62 429 s = lxc_getstate(c->name, c->config_path);
39dc698c 430 return lxc_state2str(s);
72d0e1cb
SG
431}
432
858377e4
SH
433WRAP_API(const char *, lxcapi_state)
434
39dc698c 435static bool is_stopped(struct lxc_container *c)
794dd120
SH
436{
437 lxc_state_t s;
13f5be62 438 s = lxc_getstate(c->name, c->config_path);
794dd120
SH
439 return (s == STOPPED);
440}
441
858377e4 442static bool do_lxcapi_is_running(struct lxc_container *c)
72d0e1cb
SG
443{
444 const char *s;
445
446 if (!c)
447 return false;
858377e4 448 s = do_lxcapi_state(c);
72d0e1cb
SG
449 if (!s || strcmp(s, "STOPPED") == 0)
450 return false;
451 return true;
452}
453
858377e4
SH
454WRAP_API(bool, lxcapi_is_running)
455
456static bool do_lxcapi_freeze(struct lxc_container *c)
72d0e1cb
SG
457{
458 int ret;
459 if (!c)
460 return false;
461
9123e471 462 ret = lxc_freeze(c->name, c->config_path);
72d0e1cb
SG
463 if (ret)
464 return false;
465 return true;
466}
467
858377e4
SH
468WRAP_API(bool, lxcapi_freeze)
469
470static bool do_lxcapi_unfreeze(struct lxc_container *c)
72d0e1cb
SG
471{
472 int ret;
473 if (!c)
474 return false;
475
9123e471 476 ret = lxc_unfreeze(c->name, c->config_path);
72d0e1cb
SG
477 if (ret)
478 return false;
479 return true;
480}
481
858377e4
SH
482WRAP_API(bool, lxcapi_unfreeze)
483
484static int do_lxcapi_console_getfd(struct lxc_container *c, int *ttynum, int *masterfd)
0115f8fd
DE
485{
486 int ttyfd;
487 if (!c)
488 return -1;
489
b5159817 490 ttyfd = lxc_console_getfd(c, ttynum, masterfd);
0115f8fd
DE
491 return ttyfd;
492}
493
858377e4
SH
494WRAP_API_2(int, lxcapi_console_getfd, int *, int *)
495
b5159817
DE
496static int lxcapi_console(struct lxc_container *c, int ttynum, int stdinfd,
497 int stdoutfd, int stderrfd, int escape)
498{
858377e4
SH
499 int ret;
500
501 if (!c)
502 return -1;
503
504 current_config = c->lxc_conf;
505 ret = lxc_console(c, ttynum, stdinfd, stdoutfd, stderrfd, escape);
506 current_config = NULL;
507 return ret;
b5159817
DE
508}
509
858377e4 510static pid_t do_lxcapi_init_pid(struct lxc_container *c)
72d0e1cb 511{
72d0e1cb
SG
512 if (!c)
513 return -1;
514
5cee8c50 515 return lxc_cmd_get_init_pid(c->name, c->config_path);
72d0e1cb
SG
516}
517
858377e4
SH
518WRAP_API(pid_t, lxcapi_init_pid)
519
12a50cc6 520static bool load_config_locked(struct lxc_container *c, const char *fname)
8eb5694b
SH
521{
522 if (!c->lxc_conf)
523 c->lxc_conf = lxc_conf_init();
6b0d5538
SH
524 if (!c->lxc_conf)
525 return false;
d08779d4
SH
526 if (lxc_config_read(fname, c->lxc_conf, false) != 0)
527 return false;
d08779d4 528 return true;
8eb5694b
SH
529}
530
858377e4 531static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file)
72d0e1cb 532{
39dc698c
SH
533 bool ret = false, need_disklock = false;
534 int lret;
12a50cc6 535 const char *fname;
72d0e1cb
SG
536 if (!c)
537 return false;
538
539 fname = c->configfile;
540 if (alt_file)
541 fname = alt_file;
542 if (!fname)
543 return false;
39dc698c
SH
544 /*
545 * If we're reading something other than the container's config,
546 * we only need to lock the in-memory container. If loading the
547 * container's config file, take the disk lock.
548 */
549 if (strcmp(fname, c->configfile) == 0)
550 need_disklock = true;
551
552 if (need_disklock)
553 lret = container_disk_lock(c);
554 else
555 lret = container_mem_lock(c);
556 if (lret)
72d0e1cb 557 return false;
39dc698c 558
8eb5694b 559 ret = load_config_locked(c, fname);
39dc698c
SH
560
561 if (need_disklock)
562 container_disk_unlock(c);
563 else
564 container_mem_unlock(c);
72d0e1cb
SG
565 return ret;
566}
567
858377e4
SH
568WRAP_API_1(bool, lxcapi_load_config, const char *)
569
570static bool do_lxcapi_want_daemonize(struct lxc_container *c, bool state)
72d0e1cb 571{
497a2995 572 if (!c || !c->lxc_conf)
540f932a 573 return false;
f02abefe 574 if (container_mem_lock(c)) {
3bc449ed 575 ERROR("Error getting mem lock");
540f932a 576 return false;
3bc449ed 577 }
a2739df5 578 c->daemonize = state;
3bc449ed 579 container_mem_unlock(c);
540f932a 580 return true;
72d0e1cb
SG
581}
582
858377e4
SH
583WRAP_API_1(bool, lxcapi_want_daemonize, bool)
584
585static bool do_lxcapi_want_close_all_fds(struct lxc_container *c, bool state)
130a1888
ÇO
586{
587 if (!c || !c->lxc_conf)
49badbbe 588 return false;
130a1888
ÇO
589 if (container_mem_lock(c)) {
590 ERROR("Error getting mem lock");
49badbbe 591 return false;
130a1888 592 }
540f932a 593 c->lxc_conf->close_all_fds = state;
130a1888 594 container_mem_unlock(c);
49badbbe 595 return true;
130a1888
ÇO
596}
597
858377e4
SH
598WRAP_API_1(bool, lxcapi_want_close_all_fds, bool)
599
600static bool do_lxcapi_wait(struct lxc_container *c, const char *state, int timeout)
7a44c8b4
SG
601{
602 int ret;
603
604 if (!c)
605 return false;
606
67e571de 607 ret = lxc_wait(c->name, state, timeout, c->config_path);
7a44c8b4
SG
608 return ret == 0;
609}
610
858377e4 611WRAP_API_2(bool, lxcapi_wait, const char *, int)
7a44c8b4 612
858377e4 613static bool do_wait_on_daemonized_start(struct lxc_container *c, int pid)
7a44c8b4
SG
614{
615 /* we'll probably want to make this timeout configurable? */
697fa639 616 int timeout = 5, ret, status;
7a44c8b4 617
697fa639
SH
618 /*
619 * our child is going to fork again, then exit. reap the
620 * child
621 */
03f064ff 622 ret = waitpid(pid, &status, 0);
697fa639
SH
623 if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0)
624 DEBUG("failed waiting for first dual-fork child");
858377e4 625 return do_lxcapi_wait(c, "RUNNING", timeout);
7a44c8b4
SG
626}
627
858377e4
SH
628WRAP_API_1(bool, wait_on_daemonized_start, int)
629
2d834aa8
SH
630static bool am_single_threaded(void)
631{
74f96976 632 struct dirent *direntp;
2d834aa8
SH
633 DIR *dir;
634 int count=0;
635
2d834aa8 636 dir = opendir("/proc/self/task");
2d834aa8
SH
637 if (!dir) {
638 INFO("failed to open /proc/self/task");
639 return false;
640 }
641
74f96976 642 while ((direntp = readdir(dir))) {
2d834aa8
SH
643 if (!direntp)
644 break;
645
646 if (!strcmp(direntp->d_name, "."))
647 continue;
648
649 if (!strcmp(direntp->d_name, ".."))
650 continue;
651 if (++count > 1)
652 break;
653 }
2d834aa8 654 closedir(dir);
2d834aa8
SH
655 return count == 1;
656}
657
fd51a89b
SH
658static void push_arg(char ***argp, char *arg, int *nargs)
659{
660 char **argv;
661 char *copy;
662
663 do {
664 copy = strdup(arg);
665 } while (!copy);
666 do {
667 argv = realloc(*argp, (*nargs + 2) * sizeof(char *));
668 } while (!argv);
669 *argp = argv;
670 argv[*nargs] = copy;
671 (*nargs)++;
672 argv[*nargs] = NULL;
673}
674
675static char **split_init_cmd(const char *incmd)
676{
677 size_t len;
678 int nargs = 0;
5590a671 679 char *copy, *p, *saveptr = NULL;
fd51a89b
SH
680 char **argv;
681
682 if (!incmd)
683 return NULL;
684
685 len = strlen(incmd) + 1;
686 copy = alloca(len);
687 strncpy(copy, incmd, len);
688 copy[len-1] = '\0';
689
690 do {
691 argv = malloc(sizeof(char *));
692 } while (!argv);
693 argv[0] = NULL;
694 for (p = strtok_r(copy, " ", &saveptr); p != NULL;
695 p = strtok_r(NULL, " ", &saveptr))
696 push_arg(&argv, p, &nargs);
697
698 if (nargs == 0) {
699 free(argv);
700 return NULL;
701 }
702 return argv;
703}
704
705static void free_init_cmd(char **argv)
706{
707 int i = 0;
708
709 if (!argv)
710 return;
711 while (argv[i])
712 free(argv[i++]);
713 free(argv);
714}
715
858377e4 716static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const argv[])
72d0e1cb
SG
717{
718 int ret;
aa460476 719 struct lxc_handler *handler;
72d0e1cb 720 struct lxc_conf *conf;
540f932a 721 bool daemonize = false;
6eaac303 722 FILE *pid_fp = NULL;
72d0e1cb
SG
723 char *default_args[] = {
724 "/sbin/init",
13aad0ae 725 NULL,
72d0e1cb 726 };
fd51a89b 727 char **init_cmd = NULL;
72d0e1cb
SG
728
729 /* container exists */
730 if (!c)
731 return false;
120146b9
SG
732
733 /* If anything fails before we set error_num, we want an error in there */
734 c->error_num = 1;
735
aa460476 736 /* container has not been setup */
72d0e1cb
SG
737 if (!c->lxc_conf)
738 return false;
739
3e625e2d
SH
740 if ((ret = ongoing_create(c)) < 0) {
741 ERROR("Error checking for incomplete creation");
742 return false;
743 }
744 if (ret == 2) {
745 ERROR("Error: %s creation was not completed", c->name);
858377e4 746 do_lxcapi_destroy(c);
3e625e2d
SH
747 return false;
748 } else if (ret == 1) {
749 ERROR("Error: creation of %s is ongoing", c->name);
750 return false;
751 }
752
72d0e1cb
SG
753 /* is this app meant to be run through lxcinit, as in lxc-execute? */
754 if (useinit && !argv)
755 return false;
756
5cee8c50 757 if (container_mem_lock(c))
72d0e1cb
SG
758 return false;
759 conf = c->lxc_conf;
760 daemonize = c->daemonize;
72d0e1cb 761
aa460476
CB
762 /* initialize handler */
763 handler = lxc_init_handler(c->name, conf, c->config_path);
dbc9832d 764 container_mem_unlock(c);
aa460476
CB
765 if (!handler)
766 return false;
767
72d0e1cb 768 if (useinit) {
aa460476
CB
769 TRACE("calling \"lxc_execute\"");
770 ret = lxc_execute(c->name, argv, 1, handler, c->config_path,
771 daemonize);
772 c->error_num = ret;
72d0e1cb
SG
773 return ret == 0 ? true : false;
774 }
775
fd51a89b
SH
776 /* if no argv was passed in, use lxc.init_cmd if provided in
777 * configuration */
778 if (!argv)
779 argv = init_cmd = split_init_cmd(conf->init_cmd);
780
781 /* ... and otherwise use default_args */
782 if (!argv)
783 argv = default_args;
72d0e1cb
SG
784
785 /*
786 * say, I'm not sure - what locks do we want here? Any?
787 * Is liblxc's locking enough here to protect the on disk
788 * container? We don't want to exclude things like lxc_info
789 * while container is running...
790 */
791 if (daemonize) {
0a4be28d 792 char title[2048];
71454076 793
72d0e1cb 794 pid_t pid = fork();
f2e07cb6
CB
795 if (pid < 0) {
796 lxc_free_handler(handler);
72d0e1cb 797 return false;
f2e07cb6 798 }
6eaac303
QH
799
800 if (pid != 0) {
801 /* Set to NULL because we don't want father unlink
802 * the PID file, child will do the free and unlink.
803 */
804 c->pidfile = NULL;
dbc9832d 805 close(handler->conf->maincmd_fd);
03f064ff 806 return wait_on_daemonized_start(c, pid);
6eaac303 807 }
025ed0f3 808
0a4be28d
TA
809 /* We don't really care if this doesn't print all the
810 * characters; all that it means is that the proctitle will be
811 * ugly. Similarly, we also don't care if setproctitle()
812 * fails. */
813 snprintf(title, sizeof(title), "[lxc monitor] %s %s", c->config_path, c->name);
814 INFO("Attempting to set proc title to %s", title);
815 setproctitle(title);
816
697fa639
SH
817 /* second fork to be reparented by init */
818 pid = fork();
819 if (pid < 0) {
820 SYSERROR("Error doing dual-fork");
13353dc4 821 exit(1);
697fa639
SH
822 }
823 if (pid != 0)
824 exit(0);
72d0e1cb 825 /* like daemon(), chdir to / and redirect 0,1,2 to /dev/null */
c278cef2
SH
826 if (chdir("/")) {
827 SYSERROR("Error chdir()ing to /.");
13353dc4 828 exit(1);
c278cef2 829 }
aa460476 830 lxc_check_inherited(conf, true, handler->conf->maincmd_fd);
69aeabac
TA
831 if (null_stdfds() < 0) {
832 ERROR("failed to close fds");
13353dc4 833 exit(1);
69aeabac 834 }
72d0e1cb 835 setsid();
2d834aa8
SH
836 } else {
837 if (!am_single_threaded()) {
838 ERROR("Cannot start non-daemonized container when threaded");
f2e07cb6 839 lxc_free_handler(handler);
2d834aa8
SH
840 return false;
841 }
72d0e1cb
SG
842 }
843
aa460476 844 /* We need to write PID file after daemonize, so we always
6eaac303
QH
845 * write the right PID.
846 */
847 if (c->pidfile) {
848 pid_fp = fopen(c->pidfile, "w");
849 if (pid_fp == NULL) {
850 SYSERROR("Failed to create pidfile '%s' for '%s'",
851 c->pidfile, c->name);
f2e07cb6 852 lxc_free_handler(handler);
13353dc4
SH
853 if (daemonize)
854 exit(1);
6eaac303
QH
855 return false;
856 }
857
858 if (fprintf(pid_fp, "%d\n", getpid()) < 0) {
859 SYSERROR("Failed to write '%s'", c->pidfile);
860 fclose(pid_fp);
861 pid_fp = NULL;
f2e07cb6 862 lxc_free_handler(handler);
13353dc4
SH
863 if (daemonize)
864 exit(1);
6eaac303
QH
865 return false;
866 }
867
868 fclose(pid_fp);
869 pid_fp = NULL;
870 }
871
72d0e1cb 872 conf->reboot = 0;
d2cf4c37 873
a8dfe4e0
WB
874 /* Unshare the mount namespace if requested */
875 if (conf->monitor_unshare) {
876 if (unshare(CLONE_NEWNS)) {
877 SYSERROR("failed to unshare mount namespace");
f2e07cb6 878 lxc_free_handler(handler);
a8dfe4e0
WB
879 return false;
880 }
881 if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
882 SYSERROR("Failed to make / rslave at startup");
f2e07cb6 883 lxc_free_handler(handler);
a8dfe4e0
WB
884 return false;
885 }
886 }
887
8bee8851 888reboot:
aa460476
CB
889 if (conf->reboot == 2) {
890 /* initialize handler */
891 handler = lxc_init_handler(c->name, conf, c->config_path);
892 if (!handler)
893 goto out;
894 }
895
896 if (lxc_check_inherited(conf, daemonize, handler->conf->maincmd_fd)) {
d2cf4c37 897 ERROR("Inherited fds found");
f2e07cb6 898 lxc_free_handler(handler);
d2cf4c37
SH
899 ret = 1;
900 goto out;
901 }
902
aa460476 903 ret = lxc_start(c->name, argv, handler, c->config_path, daemonize);
d4ef230c 904 c->error_num = ret;
72d0e1cb 905
8bee8851 906 if (conf->reboot == 1) {
72d0e1cb 907 INFO("container requested reboot");
8bee8851 908 conf->reboot = 2;
72d0e1cb
SG
909 goto reboot;
910 }
911
d2cf4c37 912out:
487d8008
QH
913 if (c->pidfile) {
914 unlink(c->pidfile);
915 free(c->pidfile);
916 c->pidfile = NULL;
917 }
fd51a89b
SH
918 free_init_cmd(init_cmd);
919
844f7a38 920 if (daemonize)
aa460476
CB
921 exit(ret == 0 ? true : false);
922 return (ret == 0 ? true : false);
72d0e1cb
SG
923}
924
858377e4
SH
925static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv[])
926{
927 bool ret;
928 current_config = c ? c->lxc_conf : NULL;
929 ret = do_lxcapi_start(c, useinit, argv);
930 current_config = NULL;
931 return ret;
932}
933
72d0e1cb
SG
934/*
935 * note there MUST be an ending NULL
936 */
937static bool lxcapi_startl(struct lxc_container *c, int useinit, ...)
938{
939 va_list ap;
a0e93eeb 940 char **inargs = NULL;
72d0e1cb
SG
941 bool bret = false;
942
943 /* container exists */
944 if (!c)
945 return false;
946
858377e4
SH
947 current_config = c->lxc_conf;
948
72d0e1cb 949 va_start(ap, useinit);
a0e93eeb 950 inargs = lxc_va_arg_list_to_argv(ap, 0, 1);
72d0e1cb
SG
951 va_end(ap);
952
a0e93eeb
CS
953 if (!inargs) {
954 ERROR("Memory allocation error.");
955 goto out;
72d0e1cb
SG
956 }
957
a0e93eeb 958 /* pass NULL if no arguments were supplied */
858377e4 959 bret = do_lxcapi_start(c, useinit, *inargs ? inargs : NULL);
72d0e1cb
SG
960
961out:
962 if (inargs) {
4e03ae57
DE
963 char **arg;
964 for (arg = inargs; *arg; arg++)
965 free(*arg);
72d0e1cb
SG
966 free(inargs);
967 }
968
858377e4 969 current_config = NULL;
72d0e1cb
SG
970 return bret;
971}
972
858377e4 973static bool do_lxcapi_stop(struct lxc_container *c)
72d0e1cb
SG
974{
975 int ret;
976
977 if (!c)
978 return false;
979
ef6e34ee 980 ret = lxc_cmd_stop(c->name, c->config_path);
72d0e1cb 981
d775f21b 982 return ret == 0;
72d0e1cb
SG
983}
984
858377e4
SH
985WRAP_API(bool, lxcapi_stop)
986
d5752559
SH
987static int do_create_container_dir(const char *path, struct lxc_conf *conf)
988{
989 int ret = -1, lasterr;
990 char *p = alloca(strlen(path)+1);
991 mode_t mask = umask(0002);
992 ret = mkdir(path, 0770);
993 lasterr = errno;
994 umask(mask);
995 errno = lasterr;
996 if (ret) {
997 if (errno == EEXIST)
998 ret = 0;
999 else {
1000 SYSERROR("failed to create container path %s", path);
1001 return -1;
1002 }
1003 }
1004 strcpy(p, path);
1005 if (!lxc_list_empty(&conf->id_map) && chown_mapped_root(p, conf) != 0) {
1006 ERROR("Failed to chown container dir");
1007 ret = -1;
1008 }
1009 return ret;
1010}
1011
72d0e1cb
SG
1012/*
1013 * create the standard expected container dir
1014 */
1015static bool create_container_dir(struct lxc_container *c)
1016{
1017 char *s;
1018 int len, ret;
1019
2a59a681 1020 len = strlen(c->config_path) + strlen(c->name) + 2;
72d0e1cb
SG
1021 s = malloc(len);
1022 if (!s)
1023 return false;
2a59a681 1024 ret = snprintf(s, len, "%s/%s", c->config_path, c->name);
72d0e1cb
SG
1025 if (ret < 0 || ret >= len) {
1026 free(s);
1027 return false;
1028 }
d5752559 1029 ret = do_create_container_dir(s, c->lxc_conf);
72d0e1cb
SG
1030 free(s);
1031 return ret == 0;
1032}
1033
1034/*
1897e3bc
SH
1035 * do_bdev_create: thin wrapper around bdev_create(). Like bdev_create(),
1036 * it returns a mounted bdev on success, NULL on error.
72d0e1cb 1037 */
1897e3bc
SH
1038static struct bdev *do_bdev_create(struct lxc_container *c, const char *type,
1039 struct bdev_specs *specs)
1040{
1041 char *dest;
1897e3bc
SH
1042 size_t len;
1043 struct bdev *bdev;
1044 int ret;
1045
cd219ae6
SY
1046 /* rootfs.path or lxcpath/lxcname/rootfs */
1047 if (c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) == 0) {
cf465fe4
SH
1048 const char *rpath = c->lxc_conf->rootfs.path;
1049 len = strlen(rpath) + 1;
cd219ae6 1050 dest = alloca(len);
cf465fe4 1051 ret = snprintf(dest, len, "%s", rpath);
cd219ae6 1052 } else {
858377e4 1053 const char *lxcpath = do_lxcapi_get_config_path(c);
cd219ae6
SY
1054 len = strlen(c->name) + strlen(lxcpath) + 9;
1055 dest = alloca(len);
1056 ret = snprintf(dest, len, "%s/%s/rootfs", lxcpath, c->name);
1057 }
1897e3bc
SH
1058 if (ret < 0 || ret >= len)
1059 return NULL;
1060
1061 bdev = bdev_create(dest, type, c->name, specs);
d44e88c2 1062 if (!bdev) {
959aee9c 1063 ERROR("Failed to create backing store type %s", type);
1897e3bc 1064 return NULL;
d44e88c2
SH
1065 }
1066
858377e4 1067 do_lxcapi_set_config_item(c, "lxc.rootfs", bdev->src);
39460be8 1068 do_lxcapi_set_config_item(c, "lxc.rootfs.backend", bdev->type);
cf3ef16d
SH
1069
1070 /* if we are not root, chown the rootfs dir to root in the
1071 * target uidmap */
1072
0e6e3a41 1073 if (geteuid() != 0 || (c->lxc_conf && !lxc_list_empty(&c->lxc_conf->id_map))) {
c4d10a05 1074 if (chown_mapped_root(bdev->dest, c->lxc_conf) < 0) {
959aee9c 1075 ERROR("Error chowning %s to container root", bdev->dest);
97e9cfa0 1076 suggest_default_idmap();
cf3ef16d
SH
1077 bdev_put(bdev);
1078 return NULL;
1079 }
1080 }
1081
1897e3bc
SH
1082 return bdev;
1083}
1084
96b3cb40 1085static char *lxcbasename(char *path)
72d0e1cb 1086{
96b3cb40
SH
1087 char *p = path + strlen(path) - 1;
1088 while (*p != '/' && p > path)
1089 p--;
1090 return p;
1091}
72d0e1cb 1092
69aeabac 1093static bool create_run_template(struct lxc_container *c, char *tpath, bool need_null_stdfds,
96b3cb40
SH
1094 char *const argv[])
1095{
1096 pid_t pid;
72d0e1cb 1097
72d0e1cb 1098 if (!tpath)
96b3cb40 1099 return true;
72d0e1cb
SG
1100
1101 pid = fork();
1102 if (pid < 0) {
959aee9c 1103 SYSERROR("failed to fork task for container creation template");
96b3cb40 1104 return false;
72d0e1cb
SG
1105 }
1106
1107 if (pid == 0) { // child
39460be8 1108 char *patharg, *namearg, *rootfsarg;
1897e3bc 1109 struct bdev *bdev = NULL;
72d0e1cb 1110 int i;
96b3cb40
SH
1111 int ret, len, nargs = 0;
1112 char **newargv;
cf3ef16d 1113 struct lxc_conf *conf = c->lxc_conf;
72d0e1cb 1114
69aeabac
TA
1115 if (need_null_stdfds && null_stdfds() < 0) {
1116 exit(1);
dc23c1c8 1117 }
1897e3bc 1118
39460be8 1119 bdev = bdev_init(c->lxc_conf, c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL);
1897e3bc
SH
1120 if (!bdev) {
1121 ERROR("Error opening rootfs");
1122 exit(1);
1123 }
1124
4de2791f 1125 if (geteuid() == 0) {
cf3ef16d
SH
1126 if (unshare(CLONE_NEWNS) < 0) {
1127 ERROR("error unsharing mounts");
1128 exit(1);
1129 }
4de2791f 1130 if (detect_shared_rootfs()) {
c597baa8 1131 if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
4de2791f
SH
1132 SYSERROR("Failed to make / rslave to run template");
1133 ERROR("Continuing...");
1134 }
1135 }
1136 }
2659c7cb 1137 if (strcmp(bdev->type, "dir") && strcmp(bdev->type, "btrfs")) {
4de2791f 1138 if (geteuid() != 0) {
2659c7cb 1139 ERROR("non-root users can only create btrfs and directory-backed containers");
4de2791f
SH
1140 exit(1);
1141 }
cf3ef16d
SH
1142 if (bdev->ops->mount(bdev) < 0) {
1143 ERROR("Error mounting rootfs");
1144 exit(1);
1145 }
1146 } else { // TODO come up with a better way here!
f10fad2f 1147 free(bdev->dest);
cf3ef16d 1148 bdev->dest = strdup(bdev->src);
1897e3bc
SH
1149 }
1150
72d0e1cb
SG
1151 /*
1152 * create our new array, pre-pend the template name and
1153 * base args
1154 */
1155 if (argv)
1897e3bc 1156 for (nargs = 0; argv[nargs]; nargs++) ;
6849cb5b 1157 nargs += 4; // template, path, rootfs and name args
cf3ef16d 1158
72d0e1cb
SG
1159 newargv = malloc(nargs * sizeof(*newargv));
1160 if (!newargv)
1161 exit(1);
96b3cb40 1162 newargv[0] = lxcbasename(tpath);
72d0e1cb 1163
2a59a681 1164 len = strlen(c->config_path) + strlen(c->name) + strlen("--path=") + 2;
72d0e1cb
SG
1165 patharg = malloc(len);
1166 if (!patharg)
1167 exit(1);
2a59a681 1168 ret = snprintf(patharg, len, "--path=%s/%s", c->config_path, c->name);
72d0e1cb
SG
1169 if (ret < 0 || ret >= len)
1170 exit(1);
1171 newargv[1] = patharg;
1172 len = strlen("--name=") + strlen(c->name) + 1;
1173 namearg = malloc(len);
1174 if (!namearg)
1175 exit(1);
1176 ret = snprintf(namearg, len, "--name=%s", c->name);
1177 if (ret < 0 || ret >= len)
1178 exit(1);
1179 newargv[2] = namearg;
1180
1897e3bc
SH
1181 len = strlen("--rootfs=") + 1 + strlen(bdev->dest);
1182 rootfsarg = malloc(len);
1183 if (!rootfsarg)
1184 exit(1);
1185 ret = snprintf(rootfsarg, len, "--rootfs=%s", bdev->dest);
1186 if (ret < 0 || ret >= len)
1187 exit(1);
1188 newargv[3] = rootfsarg;
1189
72d0e1cb
SG
1190 /* add passed-in args */
1191 if (argv)
1897e3bc
SH
1192 for (i = 4; i < nargs; i++)
1193 newargv[i] = argv[i-4];
72d0e1cb
SG
1194
1195 /* add trailing NULL */
1196 nargs++;
1197 newargv = realloc(newargv, nargs * sizeof(*newargv));
1198 if (!newargv)
1199 exit(1);
1200 newargv[nargs - 1] = NULL;
1201
cf3ef16d
SH
1202 /*
1203 * If we're running the template in a mapped userns, then
1204 * we prepend the template command with:
1205 * lxc-usernsexec <-m map1> ... <-m mapn> --
57d116ab
SH
1206 * and we append "--mapped-uid x", where x is the mapped uid
1207 * for our geteuid()
cf3ef16d 1208 */
0e6e3a41 1209 if (!lxc_list_empty(&conf->id_map)) {
cf3ef16d 1210 int n2args = 1;
57d116ab 1211 char txtuid[20];
2133f58c 1212 char txtgid[20];
cf3ef16d
SH
1213 char **n2 = malloc(n2args * sizeof(*n2));
1214 struct lxc_list *it;
1215 struct id_map *map;
1216
57d116ab
SH
1217 if (!n2) {
1218 SYSERROR("out of memory");
1219 exit(1);
1220 }
cf3ef16d
SH
1221 newargv[0] = tpath;
1222 tpath = "lxc-usernsexec";
1223 n2[0] = "lxc-usernsexec";
1224 lxc_list_for_each(it, &conf->id_map) {
1225 map = it->elem;
1226 n2args += 2;
57d116ab 1227 n2 = realloc(n2, n2args * sizeof(char *));
cf3ef16d
SH
1228 if (!n2)
1229 exit(1);
1230 n2[n2args-2] = "-m";
1231 n2[n2args-1] = malloc(200);
1232 if (!n2[n2args-1])
1233 exit(1);
1234 ret = snprintf(n2[n2args-1], 200, "%c:%lu:%lu:%lu",
1235 map->idtype == ID_TYPE_UID ? 'u' : 'g',
1236 map->nsid, map->hostid, map->range);
1237 if (ret < 0 || ret >= 200)
1238 exit(1);
1239 }
2133f58c 1240 int hostid_mapped = mapped_hostid(geteuid(), conf, ID_TYPE_UID);
6849cb5b 1241 int extraargs = hostid_mapped >= 0 ? 1 : 3;
57d116ab 1242 n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
cf3ef16d
SH
1243 if (!n2)
1244 exit(1);
57d116ab 1245 if (hostid_mapped < 0) {
339efad9 1246 hostid_mapped = find_unmapped_nsid(conf, ID_TYPE_UID);
cf3ef16d 1247 n2[n2args++] = "-m";
57d116ab 1248 if (hostid_mapped < 0) {
cf3ef16d
SH
1249 ERROR("Could not find free uid to map");
1250 exit(1);
1251 }
1252 n2[n2args++] = malloc(200);
1253 if (!n2[n2args-1]) {
1254 SYSERROR("out of memory");
1255 exit(1);
1256 }
1257 ret = snprintf(n2[n2args-1], 200, "u:%d:%d:1",
57d116ab 1258 hostid_mapped, geteuid());
cf3ef16d
SH
1259 if (ret < 0 || ret >= 200) {
1260 ERROR("string too long");
1261 exit(1);
1262 }
1263 }
2133f58c
SH
1264 int hostgid_mapped = mapped_hostid(getegid(), conf, ID_TYPE_GID);
1265 extraargs = hostgid_mapped >= 0 ? 1 : 3;
1266 n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
1267 if (!n2)
1268 exit(1);
1269 if (hostgid_mapped < 0) {
339efad9 1270 hostgid_mapped = find_unmapped_nsid(conf, ID_TYPE_GID);
2133f58c
SH
1271 n2[n2args++] = "-m";
1272 if (hostgid_mapped < 0) {
1273 ERROR("Could not find free uid to map");
1274 exit(1);
1275 }
1276 n2[n2args++] = malloc(200);
1277 if (!n2[n2args-1]) {
1278 SYSERROR("out of memory");
1279 exit(1);
1280 }
1281 ret = snprintf(n2[n2args-1], 200, "g:%d:%d:1",
1282 hostgid_mapped, getegid());
1283 if (ret < 0 || ret >= 200) {
1284 ERROR("string too long");
1285 exit(1);
1286 }
1287 }
cf3ef16d
SH
1288 n2[n2args++] = "--";
1289 for (i = 0; i < nargs; i++)
1290 n2[i + n2args] = newargv[i];
57d116ab
SH
1291 n2args += nargs;
1292 // Finally add "--mapped-uid $uid" to tell template what to chown
1293 // cached images to
2133f58c 1294 n2args += 4;
57d116ab
SH
1295 n2 = realloc(n2, n2args * sizeof(char *));
1296 if (!n2) {
1297 SYSERROR("out of memory");
1298 exit(1);
1299 }
1300 // note n2[n2args-1] is NULL
2133f58c 1301 n2[n2args-5] = "--mapped-uid";
57d116ab 1302 snprintf(txtuid, 20, "%d", hostid_mapped);
2133f58c
SH
1303 n2[n2args-4] = txtuid;
1304 n2[n2args-3] = "--mapped-gid";
1305 snprintf(txtgid, 20, "%d", hostgid_mapped);
1306 n2[n2args-2] = txtgid;
57d116ab 1307 n2[n2args-1] = NULL;
cf3ef16d
SH
1308 free(newargv);
1309 newargv = n2;
1310 }
72d0e1cb 1311 /* execute */
cf3ef16d 1312 execvp(tpath, newargv);
72d0e1cb
SG
1313 SYSERROR("failed to execute template %s", tpath);
1314 exit(1);
1315 }
1316
9be53773 1317 if (wait_for_pid(pid) != 0) {
959aee9c 1318 ERROR("container creation template for %s failed", c->name);
96b3cb40
SH
1319 return false;
1320 }
1321
1322 return true;
1323}
1324
74a3920a 1325static bool prepend_lxc_header(char *path, const char *t, char *const argv[])
3ce74686 1326{
1fd9bd50 1327 long flen;
b4569e93 1328 char *contents;
3ce74686 1329 FILE *f;
025ed0f3 1330 int ret = -1;
52026772 1331#if HAVE_LIBGNUTLS
025ed0f3 1332 int i;
3ce74686 1333 unsigned char md_value[SHA_DIGEST_LENGTH];
b4569e93 1334 char *tpath;
52026772 1335#endif
3ce74686 1336
025ed0f3 1337 f = fopen(path, "r");
025ed0f3 1338 if (f == NULL)
3ce74686 1339 return false;
025ed0f3
SH
1340
1341 if (fseek(f, 0, SEEK_END) < 0)
1342 goto out_error;
1343 if ((flen = ftell(f)) < 0)
1344 goto out_error;
1345 if (fseek(f, 0, SEEK_SET) < 0)
1346 goto out_error;
1347 if ((contents = malloc(flen + 1)) == NULL)
1348 goto out_error;
1349 if (fread(contents, 1, flen, f) != flen)
1350 goto out_free_contents;
1351
3ce74686 1352 contents[flen] = '\0';
025ed0f3 1353 ret = fclose(f);
025ed0f3
SH
1354 f = NULL;
1355 if (ret < 0)
1356 goto out_free_contents;
3ce74686 1357
b4569e93 1358#if HAVE_LIBGNUTLS
01efd4d3 1359 tpath = get_template_path(t);
85db5535 1360 if (!tpath) {
959aee9c 1361 ERROR("bad template: %s", t);
025ed0f3 1362 goto out_free_contents;
3ce74686
SH
1363 }
1364
85db5535
DE
1365 ret = sha1sum_file(tpath, md_value);
1366 if (ret < 0) {
1367 ERROR("Error getting sha1sum of %s", tpath);
3ce74686 1368 free(tpath);
85db5535 1369 goto out_free_contents;
3ce74686 1370 }
85db5535 1371 free(tpath);
3ce74686
SH
1372#endif
1373
025ed0f3 1374 f = fopen(path, "w");
025ed0f3 1375 if (f == NULL) {
3ce74686
SH
1376 SYSERROR("reopening config for writing");
1377 free(contents);
1378 return false;
1379 }
1380 fprintf(f, "# Template used to create this container: %s\n", t);
1381 if (argv) {
1382 fprintf(f, "# Parameters passed to the template:");
1383 while (*argv) {
1384 fprintf(f, " %s", *argv);
1385 argv++;
1386 }
1387 fprintf(f, "\n");
1388 }
1389#if HAVE_LIBGNUTLS
56698177
SH
1390 fprintf(f, "# Template script checksum (SHA-1): ");
1391 for (i=0; i<SHA_DIGEST_LENGTH; i++)
1392 fprintf(f, "%02x", md_value[i]);
1393 fprintf(f, "\n");
3ce74686 1394#endif
0520c252 1395 fprintf(f, "# For additional config options, please look at lxc.container.conf(5)\n");
49a2ed80
SH
1396 fprintf(f, "\n# Uncomment the following line to support nesting containers:\n");
1397 fprintf(f, "#lxc.include = " LXCTEMPLATECONFIG "/nesting.conf\n");
1398 fprintf(f, "# (Be aware this has security implications)\n\n");
3ce74686
SH
1399 if (fwrite(contents, 1, flen, f) != flen) {
1400 SYSERROR("Writing original contents");
1401 free(contents);
1402 fclose(f);
1403 return false;
1404 }
025ed0f3
SH
1405 ret = 0;
1406out_free_contents:
3ce74686 1407 free(contents);
025ed0f3
SH
1408out_error:
1409 if (f) {
1410 int newret;
025ed0f3 1411 newret = fclose(f);
025ed0f3
SH
1412 if (ret == 0)
1413 ret = newret;
1414 }
1415 if (ret < 0) {
1416 SYSERROR("Error prepending header");
3ce74686
SH
1417 return false;
1418 }
1419 return true;
1420}
1421
4df7f012
SH
1422static void lxcapi_clear_config(struct lxc_container *c)
1423{
f979ac15
SH
1424 if (c) {
1425 if (c->lxc_conf) {
1426 lxc_conf_free(c->lxc_conf);
1427 c->lxc_conf = NULL;
1428 }
4df7f012
SH
1429 }
1430}
1431
858377e4
SH
1432#define do_lxcapi_clear_config(c) lxcapi_clear_config(c)
1433
96b3cb40
SH
1434/*
1435 * lxcapi_create:
1436 * create a container with the given parameters.
1437 * @c: container to be created. It has the lxcpath, name, and a starting
1438 * configuration already set
1439 * @t: the template to execute to instantiate the root filesystem and
1440 * adjust the configuration.
1441 * @bdevtype: backing store type to use. If NULL, dir will be used.
1442 * @specs: additional parameters for the backing store, i.e. LVM vg to
1443 * use.
1444 *
1445 * @argv: the arguments to pass to the template, terminated by NULL. If no
1446 * arguments, you can just pass NULL.
1447 */
858377e4 1448static bool do_lxcapi_create(struct lxc_container *c, const char *t,
dc23c1c8 1449 const char *bdevtype, struct bdev_specs *specs, int flags,
96b3cb40
SH
1450 char *const argv[])
1451{
a69aad27 1452 bool ret = false;
96b3cb40 1453 pid_t pid;
85db5535 1454 char *tpath = NULL;
cbee8106 1455 int partial_fd;
96b3cb40
SH
1456
1457 if (!c)
1458 return false;
1459
85db5535
DE
1460 if (t) {
1461 tpath = get_template_path(t);
1462 if (!tpath) {
959aee9c 1463 ERROR("bad template: %s", t);
85db5535
DE
1464 goto out;
1465 }
96b3cb40
SH
1466 }
1467
cf465fe4
SH
1468 /*
1469 * If a template is passed in, and the rootfs already is defined in
1470 * the container config and exists, then * caller is trying to create
1471 * an existing container. Return an error, but do NOT delete the
1472 * container.
1473 */
858377e4 1474 if (do_lxcapi_is_defined(c) && c->lxc_conf && c->lxc_conf->rootfs.path &&
cf465fe4
SH
1475 access(c->lxc_conf->rootfs.path, F_OK) == 0 && tpath) {
1476 ERROR("Container %s:%s already exists", c->config_path, c->name);
6c6892b5 1477 goto free_tpath;
cf465fe4
SH
1478 }
1479
6c6892b5 1480 if (!c->lxc_conf) {
858377e4 1481 if (!do_lxcapi_load_config(c, lxc_global_config_value("lxc.default_config"))) {
959aee9c 1482 ERROR("Error loading default configuration file %s", lxc_global_config_value("lxc.default_config"));
6c6892b5
DE
1483 goto free_tpath;
1484 }
96b3cb40
SH
1485 }
1486
6c6892b5
DE
1487 if (!create_container_dir(c))
1488 goto free_tpath;
1489
0590e82c 1490 /*
0590e82c
SH
1491 * if both template and rootfs.path are set, template is setup as rootfs.path.
1492 * container is already created if we have a config and rootfs.path is accessible
1493 */
00370edd
DW
1494 if (!c->lxc_conf->rootfs.path && !tpath) {
1495 /* no template passed in and rootfs does not exist */
1496 if (!c->save_config(c, NULL)) {
1497 ERROR("failed to save starting configuration for %s\n", c->name);
1498 goto out;
1499 }
1500 ret = true;
0590e82c 1501 goto out;
00370edd 1502 }
0590e82c
SH
1503 if (c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) != 0)
1504 /* rootfs passed into configuration, but does not exist: error */
1505 goto out;
858377e4 1506 if (do_lxcapi_is_defined(c) && c->lxc_conf->rootfs.path && !tpath) {
0590e82c
SH
1507 /* Rootfs already existed, user just wanted to save the
1508 * loaded configuration */
0f4cdd77
DW
1509 if (!c->save_config(c, NULL))
1510 ERROR("failed to save starting configuration for %s\n", c->name);
0590e82c
SH
1511 ret = true;
1512 goto out;
a69aad27 1513 }
96b3cb40
SH
1514
1515 /* Mark that this container is being created */
1516 if ((partial_fd = create_partial(c)) < 0)
1517 goto out;
1518
1519 /* no need to get disk lock bc we have the partial locked */
1520
1521 /*
1522 * Create the backing store
1523 * Note we can't do this in the same task as we use to execute the
1524 * template because of the way zfs works.
1525 * After you 'zfs create', zfs mounts the fs only in the initial
1526 * namespace.
1527 */
1528 pid = fork();
1529 if (pid < 0) {
959aee9c 1530 SYSERROR("failed to fork task for container creation template");
8eb5694b
SH
1531 goto out_unlock;
1532 }
1533
96b3cb40
SH
1534 if (pid == 0) { // child
1535 struct bdev *bdev = NULL;
1536
1537 if (!(bdev = do_bdev_create(c, bdevtype, specs))) {
1538 ERROR("Error creating backing store type %s for %s",
1539 bdevtype ? bdevtype : "(none)", c->name);
1540 exit(1);
1541 }
1542
1543 /* save config file again to store the new rootfs location */
858377e4 1544 if (!do_lxcapi_save_config(c, NULL)) {
959aee9c 1545 ERROR("failed to save starting configuration for %s", c->name);
96b3cb40
SH
1546 // parent task won't see bdev in config so we delete it
1547 bdev->ops->umount(bdev);
1548 bdev->ops->destroy(bdev);
1549 exit(1);
1550 }
1551 exit(0);
1552 }
1553 if (wait_for_pid(pid) != 0)
a09295f8 1554 goto out_unlock;
96b3cb40
SH
1555
1556 /* reload config to get the rootfs */
a3b47c09 1557 lxc_conf_free(c->lxc_conf);
96b3cb40
SH
1558 c->lxc_conf = NULL;
1559 if (!load_config_locked(c, c->configfile))
a09295f8 1560 goto out_unlock;
96b3cb40 1561
dc23c1c8 1562 if (!create_run_template(c, tpath, !!(flags & LXC_CREATE_QUIET), argv))
96b3cb40
SH
1563 goto out_unlock;
1564
8eb5694b
SH
1565 // now clear out the lxc_conf we have, reload from the created
1566 // container
858377e4 1567 do_lxcapi_clear_config(c);
3ce74686 1568
9d65a487
KY
1569 if (t) {
1570 if (!prepend_lxc_header(c->configfile, tpath, argv)) {
1571 ERROR("Error prepending header to configuration file");
1572 goto out_unlock;
1573 }
3ce74686 1574 }
a69aad27 1575 ret = load_config_locked(c, c->configfile);
72d0e1cb
SG
1576
1577out_unlock:
3e625e2d
SH
1578 if (partial_fd >= 0)
1579 remove_partial(c, partial_fd);
72d0e1cb 1580out:
c55d4505 1581 if (!ret)
18aa217b 1582 container_destroy(c);
6c6892b5 1583free_tpath:
f10fad2f 1584 free(tpath);
a69aad27 1585 return ret;
72d0e1cb
SG
1586}
1587
858377e4
SH
1588static bool lxcapi_create(struct lxc_container *c, const char *t,
1589 const char *bdevtype, struct bdev_specs *specs, int flags,
1590 char *const argv[])
1591{
1592 bool ret;
1593 current_config = c ? c->lxc_conf : NULL;
1594 ret = do_lxcapi_create(c, t, bdevtype, specs, flags, argv);
1595 current_config = NULL;
1596 return ret;
1597}
1598
1599static bool do_lxcapi_reboot(struct lxc_container *c)
3e625e2d
SH
1600{
1601 pid_t pid;
dd267776 1602 int rebootsignal = SIGINT;
3e625e2d
SH
1603
1604 if (!c)
1605 return false;
858377e4 1606 if (!do_lxcapi_is_running(c))
3e625e2d 1607 return false;
858377e4 1608 pid = do_lxcapi_init_pid(c);
3e625e2d
SH
1609 if (pid <= 0)
1610 return false;
dd267776
BP
1611 if (c->lxc_conf && c->lxc_conf->rebootsignal)
1612 rebootsignal = c->lxc_conf->rebootsignal;
591614a7
CB
1613 if (kill(pid, rebootsignal) < 0) {
1614 WARN("Could not send signal %d to pid %d.", rebootsignal, pid);
3e625e2d 1615 return false;
591614a7 1616 }
3e625e2d
SH
1617 return true;
1618
1619}
1620
858377e4
SH
1621WRAP_API(bool, lxcapi_reboot)
1622
1623static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
72d0e1cb
SG
1624{
1625 bool retv;
1626 pid_t pid;
f0f1d8c0 1627 int haltsignal = SIGPWR;
72d0e1cb
SG
1628
1629 if (!c)
1630 return false;
1631
858377e4 1632 if (!do_lxcapi_is_running(c))
72d0e1cb 1633 return true;
858377e4 1634 pid = do_lxcapi_init_pid(c);
72d0e1cb
SG
1635 if (pid <= 0)
1636 return true;
330ae3d3
CB
1637
1638 /* Detect whether we should send SIGRTMIN + 3 (e.g. systemd). */
1639 if (task_blocking_signal(pid, (SIGRTMIN + 3)))
1640 haltsignal = (SIGRTMIN + 3);
1641
b0227444 1642 if (c->lxc_conf && c->lxc_conf->haltsignal)
f0f1d8c0 1643 haltsignal = c->lxc_conf->haltsignal;
330ae3d3
CB
1644
1645 INFO("Using signal number '%d' as halt signal.", haltsignal);
1646
591614a7
CB
1647 if (kill(pid, haltsignal) < 0)
1648 WARN("Could not send signal %d to pid %d.", haltsignal, pid);
1649
858377e4 1650 retv = do_lxcapi_wait(c, "STOPPED", timeout);
72d0e1cb
SG
1651 return retv;
1652}
1653
858377e4
SH
1654WRAP_API_1(bool, lxcapi_shutdown, int)
1655
1897e3bc 1656static bool lxcapi_createl(struct lxc_container *c, const char *t,
dc23c1c8 1657 const char *bdevtype, struct bdev_specs *specs, int flags, ...)
72d0e1cb
SG
1658{
1659 bool bret = false;
a0e93eeb 1660 char **args = NULL;
72d0e1cb 1661 va_list ap;
72d0e1cb
SG
1662
1663 if (!c)
1664 return false;
1665
858377e4
SH
1666 current_config = c->lxc_conf;
1667
72d0e1cb
SG
1668 /*
1669 * since we're going to wait for create to finish, I don't think we
1670 * need to get a copy of the arguments.
1671 */
dc23c1c8 1672 va_start(ap, flags);
a0e93eeb 1673 args = lxc_va_arg_list_to_argv(ap, 0, 0);
72d0e1cb 1674 va_end(ap);
a0e93eeb
CS
1675 if (!args) {
1676 ERROR("Memory allocation error.");
1677 goto out;
1678 }
72d0e1cb 1679
858377e4 1680 bret = do_lxcapi_create(c, t, bdevtype, specs, flags, args);
72d0e1cb
SG
1681
1682out:
a0e93eeb 1683 free(args);
858377e4 1684 current_config = NULL;
72d0e1cb
SG
1685 return bret;
1686}
1687
6b0d5538
SH
1688static void do_clear_unexp_config_line(struct lxc_conf *conf, const char *key)
1689{
1690 if (strcmp(key, "lxc.cgroup") == 0)
1691 clear_unexp_config_line(conf, key, true);
1692 else if (strcmp(key, "lxc.network") == 0)
1693 clear_unexp_config_line(conf, key, true);
1694 else if (strcmp(key, "lxc.hook") == 0)
1695 clear_unexp_config_line(conf, key, true);
1696 else
1697 clear_unexp_config_line(conf, key, false);
1698 if (!do_append_unexp_config_line(conf, key, ""))
1699 WARN("Error clearing configuration for %s", key);
1700}
1701
6afd673f
CB
1702static bool do_lxcapi_clear_config_item(struct lxc_container *c,
1703 const char *key)
72d0e1cb 1704{
6afd673f
CB
1705 int ret = 1;
1706 struct lxc_config_t *config;
72d0e1cb
SG
1707
1708 if (!c || !c->lxc_conf)
1709 return false;
6afd673f 1710
5cee8c50 1711 if (container_mem_lock(c))
72d0e1cb 1712 return false;
6afd673f
CB
1713
1714 config = lxc_getconfig(key);
1715 /* Verify that the config key exists and that it has a callback
1716 * implemented.
1717 */
1718 if (config && config->clr)
1719 ret = config->clr(key, c->lxc_conf);
6b0d5538
SH
1720 if (!ret)
1721 do_clear_unexp_config_line(c->lxc_conf, key);
6afd673f 1722
5cee8c50 1723 container_mem_unlock(c);
72d0e1cb
SG
1724 return ret == 0;
1725}
1726
858377e4
SH
1727WRAP_API_1(bool, lxcapi_clear_config_item, const char *)
1728
e0f59189 1729static inline bool enter_net_ns(struct lxc_container *c)
51d0854c 1730{
858377e4 1731 pid_t pid = do_lxcapi_init_pid(c);
ae22a220 1732
0e6e3a41 1733 if ((geteuid() != 0 || (c->lxc_conf && !lxc_list_empty(&c->lxc_conf->id_map))) && access("/proc/self/ns/user", F_OK) == 0) {
51d0854c
DY
1734 if (!switch_to_ns(pid, "user"))
1735 return false;
9c83a661 1736 }
51d0854c 1737 return switch_to_ns(pid, "net");
799f29ab
ÇO
1738}
1739
9c88ff1f
ÇO
1740// used by qsort and bsearch functions for comparing names
1741static inline int string_cmp(char **first, char **second)
1742{
1743 return strcmp(*first, *second);
1744}
1745
1746// used by qsort and bsearch functions for comparing container names
1747static inline int container_cmp(struct lxc_container **first, struct lxc_container **second)
1748{
1749 return strcmp((*first)->name, (*second)->name);
1750}
1751
1752static bool add_to_array(char ***names, char *cname, int pos)
1753{
1754 char **newnames = realloc(*names, (pos+1) * sizeof(char *));
1755 if (!newnames) {
1756 ERROR("Out of memory");
1757 return false;
1758 }
1759
1760 *names = newnames;
1761 newnames[pos] = strdup(cname);
1762 if (!newnames[pos])
1763 return false;
1764
1765 // sort the arrray as we will use binary search on it
1766 qsort(newnames, pos + 1, sizeof(char *), (int (*)(const void *,const void *))string_cmp);
1767
1768 return true;
1769}
1770
2871830a 1771static bool add_to_clist(struct lxc_container ***list, struct lxc_container *c, int pos, bool sort)
9c88ff1f
ÇO
1772{
1773 struct lxc_container **newlist = realloc(*list, (pos+1) * sizeof(struct lxc_container *));
1774 if (!newlist) {
1775 ERROR("Out of memory");
1776 return false;
1777 }
1778
1779 *list = newlist;
1780 newlist[pos] = c;
1781
1782 // sort the arrray as we will use binary search on it
2871830a
DE
1783 if (sort)
1784 qsort(newlist, pos + 1, sizeof(struct lxc_container *), (int (*)(const void *,const void *))container_cmp);
9c88ff1f
ÇO
1785
1786 return true;
1787}
1788
1789static char** get_from_array(char ***names, char *cname, int size)
1790{
1791 return (char **)bsearch(&cname, *names, size, sizeof(char *), (int (*)(const void *, const void *))string_cmp);
1792}
1793
1794
1795static bool array_contains(char ***names, char *cname, int size) {
1796 if(get_from_array(names, cname, size) != NULL)
1797 return true;
1798 return false;
1799}
1800
1801static bool remove_from_array(char ***names, char *cname, int size)
1802{
1803 char **result = get_from_array(names, cname, size);
1804 if (result != NULL) {
1805 free(result);
1806 return true;
1807 }
1808 return false;
1809}
1810
858377e4 1811static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
799f29ab 1812{
ae22a220
ÇO
1813 pid_t pid;
1814 int i, count = 0, pipefd[2];
9c88ff1f 1815 char **interfaces = NULL;
ae22a220 1816 char interface[IFNAMSIZ];
799f29ab 1817
ae22a220
ÇO
1818 if(pipe(pipefd) < 0) {
1819 SYSERROR("pipe failed");
1820 return NULL;
c868b261
ÇO
1821 }
1822
ae22a220
ÇO
1823 pid = fork();
1824 if (pid < 0) {
959aee9c 1825 SYSERROR("failed to fork task to get interfaces information");
ae22a220
ÇO
1826 close(pipefd[0]);
1827 close(pipefd[1]);
1828 return NULL;
1829 }
799f29ab 1830
ae22a220
ÇO
1831 if (pid == 0) { // child
1832 int ret = 1, nbytes;
1833 struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
1834
1835 /* close the read-end of the pipe */
1836 close(pipefd[0]);
1837
e0f59189 1838 if (!enter_net_ns(c)) {
ae22a220
ÇO
1839 SYSERROR("failed to enter namespace");
1840 goto out;
1841 }
1842
1843 /* Grab the list of interfaces */
1844 if (getifaddrs(&interfaceArray)) {
1845 SYSERROR("failed to get interfaces list");
1846 goto out;
1847 }
1848
1849 /* Iterate through the interfaces */
1850 for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = tempIfAddr->ifa_next) {
1851 nbytes = write(pipefd[1], tempIfAddr->ifa_name, IFNAMSIZ);
1852 if (nbytes < 0) {
1853 ERROR("write failed");
1854 goto out;
1855 }
1856 count++;
1857 }
1858 ret = 0;
1859
1860 out:
1861 if (interfaceArray)
1862 freeifaddrs(interfaceArray);
1863
1864 /* close the write-end of the pipe, thus sending EOF to the reader */
1865 close(pipefd[1]);
1866 exit(ret);
799f29ab
ÇO
1867 }
1868
ae22a220
ÇO
1869 /* close the write-end of the pipe */
1870 close(pipefd[1]);
1871
358afd84 1872 while (read(pipefd[0], &interface, IFNAMSIZ) == IFNAMSIZ) {
ae22a220
ÇO
1873 if (array_contains(&interfaces, interface, count))
1874 continue;
799f29ab 1875
ae22a220
ÇO
1876 if(!add_to_array(&interfaces, interface, count))
1877 ERROR("PARENT: add_to_array failed");
9c88ff1f
ÇO
1878 count++;
1879 }
799f29ab 1880
ae22a220
ÇO
1881 if (wait_for_pid(pid) != 0) {
1882 for(i=0;i<count;i++)
1883 free(interfaces[i]);
1884 free(interfaces);
1885 interfaces = NULL;
1886 }
9c88ff1f 1887
ae22a220
ÇO
1888 /* close the read-end of the pipe */
1889 close(pipefd[0]);
799f29ab 1890
9c88ff1f
ÇO
1891 /* Append NULL to the array */
1892 if(interfaces)
1893 interfaces = (char **)lxc_append_null_to_array((void **)interfaces, count);
799f29ab 1894
9c88ff1f 1895 return interfaces;
799f29ab
ÇO
1896}
1897
858377e4
SH
1898WRAP_API(char **, lxcapi_get_interfaces)
1899
1900static char** do_lxcapi_get_ips(struct lxc_container *c, const char* interface, const char* family, int scope)
799f29ab 1901{
ae22a220
ÇO
1902 pid_t pid;
1903 int i, count = 0, pipefd[2];
9c88ff1f 1904 char **addresses = NULL;
ae22a220 1905 char address[INET6_ADDRSTRLEN];
799f29ab 1906
ae22a220
ÇO
1907 if(pipe(pipefd) < 0) {
1908 SYSERROR("pipe failed");
1909 return NULL;
c868b261
ÇO
1910 }
1911
ae22a220
ÇO
1912 pid = fork();
1913 if (pid < 0) {
959aee9c 1914 SYSERROR("failed to fork task to get container ips");
ae22a220
ÇO
1915 close(pipefd[0]);
1916 close(pipefd[1]);
1917 return NULL;
9c83a661
SG
1918 }
1919
ae22a220
ÇO
1920 if (pid == 0) { // child
1921 int ret = 1, nbytes;
1922 struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
1923 char addressOutputBuffer[INET6_ADDRSTRLEN];
1924 void *tempAddrPtr = NULL;
1925 char *address = NULL;
fe218ca3 1926
ae22a220
ÇO
1927 /* close the read-end of the pipe */
1928 close(pipefd[0]);
1929
e0f59189 1930 if (!enter_net_ns(c)) {
ae22a220
ÇO
1931 SYSERROR("failed to enter namespace");
1932 goto out;
9c83a661 1933 }
ae22a220
ÇO
1934
1935 /* Grab the list of interfaces */
1936 if (getifaddrs(&interfaceArray)) {
1937 SYSERROR("failed to get interfaces list");
1938 goto out;
1939 }
1940
1941 /* Iterate through the interfaces */
1942 for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = tempIfAddr->ifa_next) {
1943 if (tempIfAddr->ifa_addr == NULL)
9c83a661
SG
1944 continue;
1945
ae22a220
ÇO
1946 if(tempIfAddr->ifa_addr->sa_family == AF_INET) {
1947 if (family && strcmp(family, "inet"))
1948 continue;
1949 tempAddrPtr = &((struct sockaddr_in *)tempIfAddr->ifa_addr)->sin_addr;
1950 }
1951 else {
1952 if (family && strcmp(family, "inet6"))
1953 continue;
1954
1955 if (((struct sockaddr_in6 *)tempIfAddr->ifa_addr)->sin6_scope_id != scope)
1956 continue;
1957
1958 tempAddrPtr = &((struct sockaddr_in6 *)tempIfAddr->ifa_addr)->sin6_addr;
1959 }
1960
1961 if (interface && strcmp(interface, tempIfAddr->ifa_name))
1962 continue;
1963 else if (!interface && strcmp("lo", tempIfAddr->ifa_name) == 0)
9c83a661
SG
1964 continue;
1965
ae22a220
ÇO
1966 address = (char *)inet_ntop(tempIfAddr->ifa_addr->sa_family,
1967 tempAddrPtr,
1968 addressOutputBuffer,
1969 sizeof(addressOutputBuffer));
1970 if (!address)
1971 continue;
1972
1973 nbytes = write(pipefd[1], address, INET6_ADDRSTRLEN);
1974 if (nbytes < 0) {
1975 ERROR("write failed");
1976 goto out;
1977 }
1978 count++;
9c83a661 1979 }
ae22a220 1980 ret = 0;
9c83a661 1981
ae22a220
ÇO
1982 out:
1983 if(interfaceArray)
1984 freeifaddrs(interfaceArray);
9c83a661 1985
ae22a220
ÇO
1986 /* close the write-end of the pipe, thus sending EOF to the reader */
1987 close(pipefd[1]);
1988 exit(ret);
6849cb5b 1989 }
9c83a661 1990
ae22a220
ÇO
1991 /* close the write-end of the pipe */
1992 close(pipefd[1]);
1993
358afd84 1994 while (read(pipefd[0], &address, INET6_ADDRSTRLEN) == INET6_ADDRSTRLEN) {
9c88ff1f 1995 if(!add_to_array(&addresses, address, count))
ae22a220 1996 ERROR("PARENT: add_to_array failed");
9c88ff1f 1997 count++;
9c83a661
SG
1998 }
1999
ae22a220
ÇO
2000 if (wait_for_pid(pid) != 0) {
2001 for(i=0;i<count;i++)
2002 free(addresses[i]);
2003 free(addresses);
2004 addresses = NULL;
2005 }
9c83a661 2006
ae22a220
ÇO
2007 /* close the read-end of the pipe */
2008 close(pipefd[0]);
9c83a661
SG
2009
2010 /* Append NULL to the array */
9c88ff1f
ÇO
2011 if(addresses)
2012 addresses = (char **)lxc_append_null_to_array((void **)addresses, count);
9c83a661
SG
2013
2014 return addresses;
2015}
2016
858377e4
SH
2017WRAP_API_3(char **, lxcapi_get_ips, const char *, const char *, int)
2018
2019static int do_lxcapi_get_config_item(struct lxc_container *c, const char *key, char *retv, int inlen)
72d0e1cb 2020{
fce687aa
CB
2021 int ret = -1;
2022 struct lxc_config_t *config;
72d0e1cb
SG
2023
2024 if (!c || !c->lxc_conf)
2025 return -1;
fce687aa 2026
5cee8c50 2027 if (container_mem_lock(c))
72d0e1cb 2028 return -1;
fce687aa
CB
2029
2030 config = lxc_getconfig(key);
2031 /* Verify that the config key exists and that it has a callback
2032 * implemented.
2033 */
2034 if (config && config->get)
6bede808 2035 ret = config->get(key, retv, inlen, c->lxc_conf);
fce687aa 2036
5cee8c50 2037 container_mem_unlock(c);
72d0e1cb
SG
2038 return ret;
2039}
2040
858377e4
SH
2041WRAP_API_3(int, lxcapi_get_config_item, const char *, char *, int)
2042
2043static char* do_lxcapi_get_running_config_item(struct lxc_container *c, const char *key)
8ac18377
ÇO
2044{
2045 char *ret;
2046
2047 if (!c || !c->lxc_conf)
2048 return NULL;
2049 if (container_mem_lock(c))
2050 return NULL;
858377e4 2051 ret = lxc_cmd_get_config_item(c->name, key, do_lxcapi_get_config_path(c));
8ac18377
ÇO
2052 container_mem_unlock(c);
2053 return ret;
2054}
2055
858377e4
SH
2056WRAP_API_1(char *, lxcapi_get_running_config_item, const char *)
2057
2058static int do_lxcapi_get_keys(struct lxc_container *c, const char *key, char *retv, int inlen)
72d0e1cb
SG
2059{
2060 if (!key)
2061 return lxc_listconfigs(retv, inlen);
2062 /*
2063 * Support 'lxc.network.<idx>', i.e. 'lxc.network.0'
2064 * This is an intelligent result to show which keys are valid given
2065 * the type of nic it is
2066 */
2067 if (!c || !c->lxc_conf)
2068 return -1;
5cee8c50 2069 if (container_mem_lock(c))
72d0e1cb
SG
2070 return -1;
2071 int ret = -1;
2072 if (strncmp(key, "lxc.network.", 12) == 0)
6849cb5b 2073 ret = lxc_list_nicconfigs(c->lxc_conf, key, retv, inlen);
5cee8c50 2074 container_mem_unlock(c);
72d0e1cb
SG
2075 return ret;
2076}
2077
858377e4
SH
2078WRAP_API_3(int, lxcapi_get_keys, const char *, char *, int)
2079
2080static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file)
72d0e1cb 2081{
39dc698c
SH
2082 FILE *fout;
2083 bool ret = false, need_disklock = false;
2084 int lret;
2085
72d0e1cb
SG
2086 if (!alt_file)
2087 alt_file = c->configfile;
2088 if (!alt_file)
6849cb5b 2089 return false; // should we write to stdout if no file is specified?
39dc698c
SH
2090
2091 // If we haven't yet loaded a config, load the stock config
2092 if (!c->lxc_conf) {
858377e4 2093 if (!do_lxcapi_load_config(c, lxc_global_config_value("lxc.default_config"))) {
959aee9c 2094 ERROR("Error loading default configuration file %s while saving %s", lxc_global_config_value("lxc.default_config"), c->name);
72d0e1cb
SG
2095 return false;
2096 }
39dc698c 2097 }
72d0e1cb 2098
5a3d2e1e
SG
2099 if (!create_container_dir(c))
2100 return false;
2101
39dc698c
SH
2102 /*
2103 * If we're writing to the container's config file, take the
2104 * disk lock. Otherwise just take the memlock to protect the
2105 * struct lxc_container while we're traversing it.
2106 */
2107 if (strcmp(c->configfile, alt_file) == 0)
2108 need_disklock = true;
2109
2110 if (need_disklock)
2111 lret = container_disk_lock(c);
2112 else
2113 lret = container_mem_lock(c);
2114
2115 if (lret)
72d0e1cb 2116 return false;
39dc698c
SH
2117
2118 fout = fopen(alt_file, "w");
2119 if (!fout)
2120 goto out;
6b0d5538 2121 write_config(fout, c->lxc_conf);
72d0e1cb 2122 fclose(fout);
39dc698c
SH
2123 ret = true;
2124
2125out:
2126 if (need_disklock)
2127 container_disk_unlock(c);
2128 else
2129 container_mem_unlock(c);
2130 return ret;
72d0e1cb
SG
2131}
2132
858377e4
SH
2133WRAP_API_1(bool, lxcapi_save_config, const char *)
2134
0ea055b3
CB
2135
2136static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc)
dfb31b25 2137{
0ea055b3
CB
2138 FILE *f1;
2139 struct stat fbuf;
42342bed
CB
2140 void *buf = NULL;
2141 char *del = NULL;
dfb31b25 2142 char path[MAXPATHLEN];
0ea055b3
CB
2143 char newpath[MAXPATHLEN];
2144 int fd, ret, n = 0, v = 0;
dfb31b25 2145 bool bret = false;
42342bed 2146 size_t len = 0, bytes = 0;
dfb31b25 2147
0ea055b3 2148 if (container_disk_lock(c0))
dfb31b25 2149 return false;
0ea055b3
CB
2150
2151 ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_snapshots", c0->config_path, c0->name);
dfb31b25
SH
2152 if (ret < 0 || ret > MAXPATHLEN)
2153 goto out;
0ea055b3
CB
2154 ret = snprintf(newpath, MAXPATHLEN, "%s\n%s\n", c->config_path, c->name);
2155 if (ret < 0 || ret > MAXPATHLEN)
dfb31b25 2156 goto out;
0ea055b3
CB
2157
2158 /* If we find an lxc-snapshot file using the old format only listing the
2159 * number of snapshots we will keep using it. */
2160 f1 = fopen(path, "r");
2161 if (f1) {
2162 n = fscanf(f1, "%d", &v);
2163 fclose(f1);
2164 if (n == 1 && v == 0) {
2165 remove(path);
2166 n = 0;
2167 }
dfb31b25 2168 }
0ea055b3
CB
2169 if (n == 1) {
2170 v += inc ? 1 : -1;
2171 f1 = fopen(path, "w");
2172 if (!f1)
2173 goto out;
2174 if (fprintf(f1, "%d\n", v) < 0) {
2175 ERROR("Error writing new snapshots value");
2176 fclose(f1);
2177 goto out;
2178 }
2179 ret = fclose(f1);
2180 if (ret != 0) {
2181 SYSERROR("Error writing to or closing snapshots file");
2182 goto out;
2183 }
2184 } else {
2185 /* Here we know that we have or can use an lxc-snapshot file
2186 * using the new format. */
2187 if (inc) {
2188 f1 = fopen(path, "a");
2189 if (!f1)
2190 goto out;
2191
2192 if (fprintf(f1, "%s", newpath) < 0) {
2193 ERROR("Error writing new snapshots entry");
2194 ret = fclose(f1);
2195 if (ret != 0)
2196 SYSERROR("Error writing to or closing snapshots file");
2197 goto out;
2198 }
2199
2200 ret = fclose(f1);
2201 if (ret != 0) {
2202 SYSERROR("Error writing to or closing snapshots file");
2203 goto out;
2204 }
2205 } else if (!inc) {
d028235d
SG
2206 if ((fd = open(path, O_RDWR | O_CLOEXEC)) < 0)
2207 goto out;
2208
2209 if (fstat(fd, &fbuf) < 0) {
2210 close(fd);
2211 goto out;
2212 }
2213
2214 if (fbuf.st_size != 0) {
d028235d 2215
25086a5f 2216 buf = lxc_strmmap(NULL, fbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
d028235d
SG
2217 if (buf == MAP_FAILED) {
2218 SYSERROR("Failed to create mapping %s", path);
2219 close(fd);
2220 goto out;
2221 }
2222
2223 len = strlen(newpath);
2224 while ((del = strstr((char *)buf, newpath))) {
2225 memmove(del, del + len, strlen(del) - len + 1);
2226 bytes += len;
2227 }
2228
25086a5f 2229 lxc_strmunmap(buf, fbuf.st_size);
d028235d
SG
2230 if (ftruncate(fd, fbuf.st_size - bytes) < 0) {
2231 SYSERROR("Failed to truncate file %s", path);
2232 close(fd);
2233 goto out;
2234 }
2235 }
2236 close(fd);
2237 }
0ea055b3
CB
2238
2239 /* If the lxc-snapshot file is empty, remove it. */
2240 if (stat(path, &fbuf) < 0)
2241 goto out;
d028235d
SG
2242 if (!fbuf.st_size) {
2243 remove(path);
0ea055b3 2244 }
dfb31b25
SH
2245 }
2246
2247 bret = true;
2248
2249out:
0ea055b3 2250 container_disk_unlock(c0);
dfb31b25
SH
2251 return bret;
2252}
2253
2254static void strip_newline(char *p)
2255{
2256 size_t len = strlen(p);
2257 if (len < 1)
2258 return;
2259 if (p[len-1] == '\n')
2260 p[len-1] = '\0';
2261}
2262
d825fff3 2263void mod_all_rdeps(struct lxc_container *c, bool inc)
dfb31b25
SH
2264{
2265 struct lxc_container *p;
2266 char *lxcpath = NULL, *lxcname = NULL, path[MAXPATHLEN];
2267 size_t pathlen = 0, namelen = 0;
2268 FILE *f;
2269 int ret;
2270
2271 ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_rdepends",
2272 c->config_path, c->name);
2273 if (ret < 0 || ret >= MAXPATHLEN) {
2274 ERROR("Path name too long");
2275 return;
2276 }
025ed0f3 2277 f = fopen(path, "r");
025ed0f3 2278 if (f == NULL)
dfb31b25
SH
2279 return;
2280 while (getline(&lxcpath, &pathlen, f) != -1) {
2281 if (getline(&lxcname, &namelen, f) == -1) {
959aee9c 2282 ERROR("badly formatted file %s", path);
dfb31b25
SH
2283 goto out;
2284 }
2285 strip_newline(lxcpath);
2286 strip_newline(lxcname);
2287 if ((p = lxc_container_new(lxcname, lxcpath)) == NULL) {
2288 ERROR("Unable to find dependent container %s:%s",
2289 lxcpath, lxcname);
2290 continue;
2291 }
0ea055b3
CB
2292 if (!mod_rdep(p, c, inc))
2293 ERROR("Failed to update snapshots file for %s:%s",
dfb31b25
SH
2294 lxcpath, lxcname);
2295 lxc_container_put(p);
2296 }
2297out:
f10fad2f
ME
2298 free(lxcpath);
2299 free(lxcname);
dfb31b25
SH
2300 fclose(f);
2301}
2302
18aa217b 2303static bool has_fs_snapshots(struct lxc_container *c)
dfb31b25 2304{
0ea055b3 2305 FILE *f;
dfb31b25
SH
2306 char path[MAXPATHLEN];
2307 int ret, v;
0ea055b3 2308 struct stat fbuf;
dfb31b25
SH
2309 bool bret = false;
2310
2311 ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_snapshots", c->config_path,
2312 c->name);
2313 if (ret < 0 || ret > MAXPATHLEN)
2314 goto out;
0ea055b3
CB
2315 /* If the file doesn't exist there are no snapshots. */
2316 if (stat(path, &fbuf) < 0)
dfb31b25 2317 goto out;
0ea055b3
CB
2318 v = fbuf.st_size;
2319 if (v != 0) {
2320 f = fopen(path, "r");
2321 if (!f)
2322 goto out;
2323 ret = fscanf(f, "%d", &v);
2324 fclose(f);
2325 // TODO: Figure out what to do with the return value of fscanf.
2326 if (ret != 1)
2327 INFO("Container uses new lxc-snapshots format %s", path);
2328 }
dfb31b25
SH
2329 bret = v != 0;
2330
2331out:
2332 return bret;
2333}
2334
18aa217b
SH
2335static bool has_snapshots(struct lxc_container *c)
2336{
2337 char path[MAXPATHLEN];
74f96976 2338 struct dirent *direntp;
18aa217b
SH
2339 int count=0;
2340 DIR *dir;
2341
2342 if (!get_snappath_dir(c, path))
2343 return false;
2344 dir = opendir(path);
2345 if (!dir)
2346 return false;
74f96976 2347 while ((direntp = readdir(dir))) {
18aa217b
SH
2348 if (!direntp)
2349 break;
2350
2351 if (!strcmp(direntp->d_name, "."))
2352 continue;
2353
2354 if (!strcmp(direntp->d_name, ".."))
2355 continue;
2356 count++;
2357 break;
2358 }
2359 closedir(dir);
2360 return count > 0;
2361}
2362
297c2d58 2363static bool do_destroy_container(struct lxc_conf *conf) {
d028235d 2364 if (am_unpriv()) {
c9b7c33e
CB
2365 if (userns_exec_1(conf, bdev_destroy_wrapper, conf,
2366 "bdev_destroy_wrapper") < 0)
d028235d
SG
2367 return false;
2368 return true;
2369 }
2370 return bdev_destroy(conf);
297c2d58
CB
2371}
2372
4355ab5f
SH
2373static int lxc_rmdir_onedev_wrapper(void *data)
2374{
2375 char *arg = (char *) data;
18aa217b 2376 return lxc_rmdir_onedev(arg, "snaps");
4355ab5f
SH
2377}
2378
18aa217b 2379static bool container_destroy(struct lxc_container *c)
72d0e1cb 2380{
c868b261 2381 bool bret = false;
297c2d58 2382 int ret = 0;
a70a69e8 2383 struct lxc_conf *conf;
72d0e1cb 2384
858377e4 2385 if (!c || !do_lxcapi_is_defined(c))
5a3d2e1e
SG
2386 return false;
2387
a70a69e8 2388 conf = c->lxc_conf;
3bc449ed 2389 if (container_disk_lock(c))
72d0e1cb 2390 return false;
72d0e1cb 2391
39dc698c 2392 if (!is_stopped(c)) {
60bf62d4
SH
2393 // we should queue some sort of error - in c->error_string?
2394 ERROR("container %s is not stopped", c->name);
2395 goto out;
72d0e1cb
SG
2396 }
2397
a70a69e8 2398 if (conf && !lxc_list_empty(&conf->hooks[LXCHOOK_DESTROY])) {
37cf711b 2399 /* Start of environment variable setup for hooks */
ab7efcf5 2400 if (c->name && setenv("LXC_NAME", c->name, 1)) {
37cf711b
SY
2401 SYSERROR("failed to set environment variable for container name");
2402 }
ab7efcf5 2403 if (conf->rcfile && setenv("LXC_CONFIG_FILE", conf->rcfile, 1)) {
37cf711b
SY
2404 SYSERROR("failed to set environment variable for config path");
2405 }
ab7efcf5 2406 if (conf->rootfs.mount && setenv("LXC_ROOTFS_MOUNT", conf->rootfs.mount, 1)) {
37cf711b
SY
2407 SYSERROR("failed to set environment variable for rootfs mount");
2408 }
ab7efcf5 2409 if (conf->rootfs.path && setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1)) {
37cf711b
SY
2410 SYSERROR("failed to set environment variable for rootfs mount");
2411 }
2412 if (conf->console.path && setenv("LXC_CONSOLE", conf->console.path, 1)) {
2413 SYSERROR("failed to set environment variable for console path");
2414 }
2415 if (conf->console.log_path && setenv("LXC_CONSOLE_LOGPATH", conf->console.log_path, 1)) {
2416 SYSERROR("failed to set environment variable for console log");
2417 }
2418 /* End of environment variable setup for hooks */
2419
2420 if (run_lxc_hooks(c->name, "destroy", conf, c->get_config_path(c), NULL)) {
2421 ERROR("Error executing clone hook for %s", c->name);
2422 goto out;
2423 }
2424 }
2425
2426 if (current_config && conf == current_config) {
858377e4 2427 current_config = NULL;
37cf711b
SY
2428 if (conf->logfd != -1) {
2429 close(conf->logfd);
2430 conf->logfd = -1;
858377e4
SH
2431 }
2432 }
2433
d028235d
SG
2434 if (conf && conf->rootfs.path && conf->rootfs.mount) {
2435 if (!do_destroy_container(conf)) {
2436 ERROR("Error destroying rootfs for %s", c->name);
2437 goto out;
2438 }
2439 INFO("Destroyed rootfs for %s", c->name);
2440 }
60bf62d4 2441
dfb31b25
SH
2442 mod_all_rdeps(c, false);
2443
858377e4 2444 const char *p1 = do_lxcapi_get_config_path(c);
60bf62d4
SH
2445 char *path = alloca(strlen(p1) + strlen(c->name) + 2);
2446 sprintf(path, "%s/%s", p1, c->name);
c868b261 2447 if (am_unpriv())
c9b7c33e
CB
2448 ret = userns_exec_1(conf, lxc_rmdir_onedev_wrapper, path,
2449 "lxc_rmdir_onedev_wrapper");
4355ab5f 2450 else
18aa217b 2451 ret = lxc_rmdir_onedev(path, "snaps");
4355ab5f 2452 if (ret < 0) {
60bf62d4
SH
2453 ERROR("Error destroying container directory for %s", c->name);
2454 goto out;
2455 }
d028235d 2456 INFO("Destroyed directory for %s", c->name);
297c2d58 2457
fef48dc9 2458 bret = true;
60bf62d4
SH
2459
2460out:
3bc449ed 2461 container_disk_unlock(c);
fef48dc9 2462 return bret;
72d0e1cb
SG
2463}
2464
858377e4 2465static bool do_lxcapi_destroy(struct lxc_container *c)
18aa217b
SH
2466{
2467 if (!c || !lxcapi_is_defined(c))
2468 return false;
2469 if (has_snapshots(c)) {
2470 ERROR("Container %s has snapshots; not removing", c->name);
2471 return false;
2472 }
2473
2474 if (has_fs_snapshots(c)) {
2475 ERROR("container %s has snapshots on its rootfs", c->name);
2476 return false;
2477 }
2478
2479 return container_destroy(c);
2480}
2481
858377e4 2482WRAP_API(bool, lxcapi_destroy)
18aa217b 2483
858377e4 2484static bool do_lxcapi_destroy_with_snapshots(struct lxc_container *c)
18aa217b
SH
2485{
2486 if (!c || !lxcapi_is_defined(c))
2487 return false;
2488 if (!lxcapi_snapshot_destroy_all(c)) {
2489 ERROR("Error deleting all snapshots");
2490 return false;
2491 }
2492 return lxcapi_destroy(c);
2493}
2494
858377e4
SH
2495WRAP_API(bool, lxcapi_destroy_with_snapshots)
2496
96532523
SH
2497static bool set_config_item_locked(struct lxc_container *c, const char *key, const char *v)
2498{
2499 struct lxc_config_t *config;
2500
2501 if (!c->lxc_conf)
2502 c->lxc_conf = lxc_conf_init();
6b0d5538 2503 if (!c->lxc_conf)
96532523
SH
2504 return false;
2505 config = lxc_getconfig(key);
2506 if (!config)
2507 return false;
d37f7cd7 2508 if (config->set(key, v, c->lxc_conf) != 0)
f979ac15 2509 return false;
6b0d5538 2510 return do_append_unexp_config_line(c->lxc_conf, key, v);
96532523
SH
2511}
2512
858377e4 2513static bool do_lxcapi_set_config_item(struct lxc_container *c, const char *key, const char *v)
72d0e1cb 2514{
72d0e1cb 2515 bool b = false;
72d0e1cb
SG
2516
2517 if (!c)
2518 return false;
2519
5cee8c50 2520 if (container_mem_lock(c))
72d0e1cb
SG
2521 return false;
2522
96532523 2523 b = set_config_item_locked(c, key, v);
72d0e1cb 2524
5cee8c50 2525 container_mem_unlock(c);
72d0e1cb
SG
2526 return b;
2527}
2528
858377e4
SH
2529WRAP_API_2(bool, lxcapi_set_config_item, const char *, const char *)
2530
72d0e1cb
SG
2531static char *lxcapi_config_file_name(struct lxc_container *c)
2532{
2533 if (!c || !c->configfile)
2534 return NULL;
2535 return strdup(c->configfile);
2536}
2537
2a59a681
SH
2538static const char *lxcapi_get_config_path(struct lxc_container *c)
2539{
2540 if (!c || !c->config_path)
2541 return NULL;
2542 return (const char *)(c->config_path);
2543}
2544
afeecbba
SH
2545/*
2546 * not for export
2547 * Just recalculate the c->configfile based on the
2548 * c->config_path, which must be set.
2549 * The lxc_container must be locked or not yet public.
2550 */
2551static bool set_config_filename(struct lxc_container *c)
2552{
2553 char *newpath;
2554 int len, ret;
2555
2556 if (!c->config_path)
2557 return false;
2558
2559 /* $lxc_path + "/" + c->name + "/" + "config" + '\0' */
2560 len = strlen(c->config_path) + strlen(c->name) + strlen("config") + 3;
2561 newpath = malloc(len);
2562 if (!newpath)
2563 return false;
2564
2565 ret = snprintf(newpath, len, "%s/%s/config", c->config_path, c->name);
2566 if (ret < 0 || ret >= len) {
2567 fprintf(stderr, "Error printing out config file name\n");
2568 free(newpath);
2569 return false;
2570 }
2571
f10fad2f 2572 free(c->configfile);
afeecbba
SH
2573 c->configfile = newpath;
2574
2575 return true;
2576}
2577
858377e4 2578static bool do_lxcapi_set_config_path(struct lxc_container *c, const char *path)
2a59a681
SH
2579{
2580 char *p;
2581 bool b = false;
afeecbba 2582 char *oldpath = NULL;
2a59a681
SH
2583
2584 if (!c)
2585 return b;
2586
5cee8c50 2587 if (container_mem_lock(c))
2a59a681
SH
2588 return b;
2589
2590 p = strdup(path);
afeecbba
SH
2591 if (!p) {
2592 ERROR("Out of memory setting new lxc path");
2a59a681 2593 goto err;
afeecbba
SH
2594 }
2595
2a59a681
SH
2596 b = true;
2597 if (c->config_path)
afeecbba 2598 oldpath = c->config_path;
2a59a681 2599 c->config_path = p;
afeecbba
SH
2600
2601 /* Since we've changed the config path, we have to change the
2602 * config file name too */
2603 if (!set_config_filename(c)) {
2604 ERROR("Out of memory setting new config filename");
2605 b = false;
2606 free(c->config_path);
2607 c->config_path = oldpath;
2608 oldpath = NULL;
2609 }
2a59a681 2610err:
f10fad2f 2611 free(oldpath);
5cee8c50 2612 container_mem_unlock(c);
2a59a681
SH
2613 return b;
2614}
2615
858377e4 2616WRAP_API_1(bool, lxcapi_set_config_path, const char *)
2a59a681 2617
858377e4 2618static bool do_lxcapi_set_cgroup_item(struct lxc_container *c, const char *subsys, const char *value)
794dd120
SH
2619{
2620 int ret;
794dd120
SH
2621
2622 if (!c)
2623 return false;
2624
3bc449ed 2625 if (is_stopped(c))
794dd120
SH
2626 return false;
2627
3bc449ed
SH
2628 if (container_disk_lock(c))
2629 return false;
794dd120 2630
33ad9f1a 2631 ret = lxc_cgroup_set(subsys, value, c->name, c->config_path);
3bc449ed
SH
2632
2633 container_disk_unlock(c);
2634 return ret == 0;
794dd120
SH
2635}
2636
858377e4
SH
2637WRAP_API_2(bool, lxcapi_set_cgroup_item, const char *, const char *)
2638
2639static int do_lxcapi_get_cgroup_item(struct lxc_container *c, const char *subsys, char *retv, int inlen)
794dd120 2640{
3bc449ed 2641 int ret;
794dd120 2642
6502006a 2643 if (!c)
794dd120
SH
2644 return -1;
2645
3bc449ed 2646 if (is_stopped(c))
794dd120
SH
2647 return -1;
2648
3bc449ed
SH
2649 if (container_disk_lock(c))
2650 return -1;
794dd120 2651
33ad9f1a 2652 ret = lxc_cgroup_get(subsys, retv, inlen, c->name, c->config_path);
794dd120 2653
3bc449ed 2654 container_disk_unlock(c);
794dd120
SH
2655 return ret;
2656}
2657
858377e4
SH
2658WRAP_API_3(int, lxcapi_get_cgroup_item, const char *, char *, int)
2659
593e8478 2660const char *lxc_get_global_config_item(const char *key)
83c98d82 2661{
593e8478 2662 return lxc_global_config_value(key);
a8428dfa
SH
2663}
2664
b6b918a1
SG
2665const char *lxc_get_version(void)
2666{
95ee490b 2667 return LXC_VERSION;
b6b918a1
SG
2668}
2669
f0ca2726 2670static int copy_file(const char *old, const char *new)
9be53773
SH
2671{
2672 int in, out;
2673 ssize_t len, ret;
2674 char buf[8096];
2675 struct stat sbuf;
2676
2677 if (file_exists(new)) {
2678 ERROR("copy destination %s exists", new);
2679 return -1;
2680 }
2681 ret = stat(old, &sbuf);
2682 if (ret < 0) {
dfb31b25 2683 INFO("Error stat'ing %s", old);
9be53773
SH
2684 return -1;
2685 }
2686
2687 in = open(old, O_RDONLY);
2688 if (in < 0) {
dfb31b25 2689 SYSERROR("Error opening original file %s", old);
9be53773
SH
2690 return -1;
2691 }
2692 out = open(new, O_CREAT | O_EXCL | O_WRONLY, 0644);
2693 if (out < 0) {
dfb31b25 2694 SYSERROR("Error opening new file %s", new);
9be53773
SH
2695 close(in);
2696 return -1;
2697 }
2698
2699 while (1) {
2700 len = read(in, buf, 8096);
2701 if (len < 0) {
dfb31b25 2702 SYSERROR("Error reading old file %s", old);
9be53773
SH
2703 goto err;
2704 }
2705 if (len == 0)
2706 break;
2707 ret = write(out, buf, len);
6849cb5b 2708 if (ret < len) { // should we retry?
dfb31b25 2709 SYSERROR("Error: write to new file %s was interrupted", new);
9be53773
SH
2710 goto err;
2711 }
2712 }
2713 close(in);
2714 close(out);
2715
2716 // we set mode, but not owner/group
2717 ret = chmod(new, sbuf.st_mode);
2718 if (ret) {
dfb31b25 2719 SYSERROR("Error setting mode on %s", new);
9be53773
SH
2720 return -1;
2721 }
2722
2723 return 0;
2724
2725err:
2726 close(in);
2727 close(out);
2728 return -1;
2729}
2730
9be53773
SH
2731static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
2732{
619256b5 2733 int i, len, ret;
9be53773 2734 struct lxc_list *it;
619256b5
ÇO
2735 char *cpath;
2736
2737 len = strlen(oldc->config_path) + strlen(oldc->name) + 3;
2738 cpath = alloca(len);
2739 ret = snprintf(cpath, len, "%s/%s/", oldc->config_path, oldc->name);
2740 if (ret < 0 || ret >= len)
2741 return -1;
9be53773
SH
2742
2743 for (i=0; i<NUM_LXC_HOOKS; i++) {
2744 lxc_list_for_each(it, &c->lxc_conf->hooks[i]) {
2745 char *hookname = it->elem;
c32981c3 2746 char *fname = strrchr(hookname, '/');
9be53773
SH
2747 char tmppath[MAXPATHLEN];
2748 if (!fname) // relative path - we don't support, but maybe we should
2749 return 0;
619256b5
ÇO
2750 if (strncmp(hookname, cpath, len - 1) != 0) {
2751 // this hook is public - ignore
2752 continue;
2753 }
9be53773
SH
2754 // copy the script, and change the entry in confile
2755 ret = snprintf(tmppath, MAXPATHLEN, "%s/%s/%s",
2756 c->config_path, c->name, fname+1);
2757 if (ret < 0 || ret >= MAXPATHLEN)
2758 return -1;
2759 ret = copy_file(it->elem, tmppath);
2760 if (ret < 0)
2761 return -1;
2762 free(it->elem);
2763 it->elem = strdup(tmppath);
2764 if (!it->elem) {
2765 ERROR("out of memory copying hook path");
2766 return -1;
2767 }
9be53773
SH
2768 }
2769 }
2770
67702c21
SH
2771 if (!clone_update_unexp_hooks(c->lxc_conf, oldc->config_path,
2772 c->config_path, oldc->name, c->name)) {
6b0d5538
SH
2773 ERROR("Error saving new hooks in clone");
2774 return -1;
2775 }
858377e4 2776 do_lxcapi_save_config(c, NULL);
9be53773
SH
2777 return 0;
2778}
2779
9be53773
SH
2780
2781static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c)
2782{
2783 char newpath[MAXPATHLEN];
2784 char *oldpath = oldc->lxc_conf->fstab;
2785 int ret;
2786
2787 if (!oldpath)
2788 return 0;
2789
6b0d5538
SH
2790 clear_unexp_config_line(c->lxc_conf, "lxc.mount", false);
2791
c32981c3 2792 char *p = strrchr(oldpath, '/');
9be53773
SH
2793 if (!p)
2794 return -1;
2795 ret = snprintf(newpath, MAXPATHLEN, "%s/%s%s",
2796 c->config_path, c->name, p);
2797 if (ret < 0 || ret >= MAXPATHLEN) {
2798 ERROR("error printing new path for %s", oldpath);
2799 return -1;
2800 }
2801 if (file_exists(newpath)) {
2802 ERROR("error: fstab file %s exists", newpath);
2803 return -1;
2804 }
2805
2806 if (copy_file(oldpath, newpath) < 0) {
2807 ERROR("error: copying %s to %s", oldpath, newpath);
2808 return -1;
2809 }
2810 free(c->lxc_conf->fstab);
2811 c->lxc_conf->fstab = strdup(newpath);
2812 if (!c->lxc_conf->fstab) {
2813 ERROR("error: allocating pathname");
2814 return -1;
2815 }
6b0d5538
SH
2816 if (!do_append_unexp_config_line(c->lxc_conf, "lxc.mount", newpath)) {
2817 ERROR("error saving new lxctab");
2818 return -1;
2819 }
9be53773
SH
2820
2821 return 0;
2822}
2823
dfb31b25
SH
2824static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0)
2825{
2826 char path0[MAXPATHLEN], path1[MAXPATHLEN];
2827 int ret;
2828
2829 ret = snprintf(path0, MAXPATHLEN, "%s/%s/lxc_rdepends", c0->config_path,
2830 c0->name);
2831 if (ret < 0 || ret >= MAXPATHLEN) {
2832 WARN("Error copying reverse dependencies");
2833 return;
2834 }
2835 ret = snprintf(path1, MAXPATHLEN, "%s/%s/lxc_rdepends", c->config_path,
2836 c->name);
2837 if (ret < 0 || ret >= MAXPATHLEN) {
2838 WARN("Error copying reverse dependencies");
2839 return;
2840 }
2841 if (copy_file(path0, path1) < 0) {
2842 INFO("Error copying reverse dependencies");
2843 return;
2844 }
2845}
2846
2847static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0)
2848{
2849 int ret;
2850 char path[MAXPATHLEN];
2851 FILE *f;
2852 bool bret;
2853
2854 ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_rdepends", c->config_path,
2855 c->name);
2856 if (ret < 0 || ret >= MAXPATHLEN)
2857 return false;
2858 f = fopen(path, "a");
2859 if (!f)
2860 return false;
2861 bret = true;
2862 // if anything goes wrong, just return an error
2863 if (fprintf(f, "%s\n%s\n", c0->config_path, c0->name) < 0)
2864 bret = false;
2865 if (fclose(f) != 0)
2866 bret = false;
2867 return bret;
2868}
2869
15a90a10
SH
2870/*
2871 * If the fs natively supports snapshot clones with no penalty,
2872 * then default to those even if not requested.
2873 * Currently we only do this for btrfs.
2874 */
2875bool should_default_to_snapshot(struct lxc_container *c0,
2876 struct lxc_container *c1)
2877{
2878 size_t l0 = strlen(c0->config_path) + strlen(c0->name) + 2;
2879 size_t l1 = strlen(c1->config_path) + strlen(c1->name) + 2;
2880 char *p0 = alloca(l0 + 1);
2881 char *p1 = alloca(l1 + 1);
6e0fa6a0 2882 char *rootfs = c0->lxc_conf->rootfs.path;
15a90a10
SH
2883
2884 snprintf(p0, l0, "%s/%s", c0->config_path, c0->name);
2885 snprintf(p1, l1, "%s/%s", c1->config_path, c1->name);
9a09badc
CB
2886
2887 if (!is_btrfs_fs(p0) || !is_btrfs_fs(p1))
2888 return false;
2889
6e0fa6a0
CB
2890 if (is_btrfs_subvol(rootfs) <= 0)
2891 return false;
2892
15a90a10
SH
2893 return btrfs_same_fs(p0, p1) == 0;
2894}
2895
9be53773 2896static int copy_storage(struct lxc_container *c0, struct lxc_container *c,
763429b6
CB
2897 const char *newtype, int flags, const char *bdevdata,
2898 uint64_t newsize)
9be53773
SH
2899{
2900 struct bdev *bdev;
dfb31b25 2901 int need_rdep;
9be53773 2902
15a90a10
SH
2903 if (should_default_to_snapshot(c0, c))
2904 flags |= LXC_CLONE_SNAPSHOT;
2905
763429b6
CB
2906 bdev = bdev_copy(c0, c->name, c->config_path, newtype, flags, bdevdata,
2907 newsize, &need_rdep);
9be53773 2908 if (!bdev) {
763429b6 2909 ERROR("Error copying storage.");
9be53773
SH
2910 return -1;
2911 }
763429b6
CB
2912
2913 /* Set new rootfs. */
9be53773
SH
2914 free(c->lxc_conf->rootfs.path);
2915 c->lxc_conf->rootfs.path = strdup(bdev->src);
763429b6
CB
2916
2917 /* Set new bdev type. */
8869eb5f
CB
2918 free(c->lxc_conf->rootfs.bdev_type);
2919 c->lxc_conf->rootfs.bdev_type = strdup(bdev->type);
9be53773 2920 bdev_put(bdev);
763429b6 2921
dfb31b25 2922 if (!c->lxc_conf->rootfs.path) {
763429b6
CB
2923 ERROR("Out of memory while setting storage path.");
2924 return -1;
2925 }
2926 if (!c->lxc_conf->rootfs.bdev_type) {
2927 ERROR("Out of memory while setting rootfs backend.");
9be53773 2928 return -1;
dfb31b25 2929 }
763429b6
CB
2930
2931 /* Append a new lxc.rootfs entry to the unexpanded config. */
6b0d5538 2932 clear_unexp_config_line(c->lxc_conf, "lxc.rootfs", false);
763429b6
CB
2933 if (!do_append_unexp_config_line(c->lxc_conf, "lxc.rootfs",
2934 c->lxc_conf->rootfs.path)) {
2935 ERROR("Error saving new rootfs to cloned config.");
d0218321
SH
2936 return -1;
2937 }
763429b6
CB
2938
2939 /* Append a new lxc.rootfs.backend entry to the unexpanded config. */
8869eb5f 2940 clear_unexp_config_line(c->lxc_conf, "lxc.rootfs.backend", false);
763429b6
CB
2941 if (!do_append_unexp_config_line(c->lxc_conf, "lxc.rootfs.backend",
2942 c->lxc_conf->rootfs.bdev_type)) {
2943 ERROR("Error saving new rootfs backend to cloned config.");
8869eb5f
CB
2944 return -1;
2945 }
763429b6 2946
eee59f94
SH
2947 if (flags & LXC_CLONE_SNAPSHOT)
2948 copy_rdepends(c, c0);
dfb31b25
SH
2949 if (need_rdep) {
2950 if (!add_rdepends(c, c0))
2951 WARN("Error adding reverse dependency from %s to %s",
763429b6 2952 c->name, c0->name);
dfb31b25
SH
2953 }
2954
2955 mod_all_rdeps(c, true);
2956
9be53773
SH
2957 return 0;
2958}
2959
1354955b
SH
2960struct clone_update_data {
2961 struct lxc_container *c0;
2962 struct lxc_container *c1;
2963 int flags;
2964 char **hookargs;
2965};
2966
2967static int clone_update_rootfs(struct clone_update_data *data)
9be53773 2968{
1354955b
SH
2969 struct lxc_container *c0 = data->c0;
2970 struct lxc_container *c = data->c1;
2971 int flags = data->flags;
2972 char **hookargs = data->hookargs;
9be53773
SH
2973 int ret = -1;
2974 char path[MAXPATHLEN];
2975 struct bdev *bdev;
2976 FILE *fout;
148e91f5 2977 struct lxc_conf *conf = c->lxc_conf;
9be53773
SH
2978
2979 /* update hostname in rootfs */
2980 /* we're going to mount, so run in a clean namespace to simplify cleanup */
2981
1354955b
SH
2982 if (setgid(0) < 0) {
2983 ERROR("Failed to setgid to 0");
2984 return -1;
2985 }
2986 if (setuid(0) < 0) {
2987 ERROR("Failed to setuid to 0");
9be53773 2988 return -1;
1354955b 2989 }
c476bdce
SH
2990 if (setgroups(0, NULL) < 0)
2991 WARN("Failed to clear groups");
9be53773 2992
1354955b
SH
2993 if (unshare(CLONE_NEWNS) < 0)
2994 return -1;
76a26f55 2995 bdev = bdev_init(c->lxc_conf, c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL);
9be53773 2996 if (!bdev)
1354955b 2997 return -1;
cf3ef16d
SH
2998 if (strcmp(bdev->type, "dir") != 0) {
2999 if (unshare(CLONE_NEWNS) < 0) {
3000 ERROR("error unsharing mounts");
e7de366c 3001 bdev_put(bdev);
1354955b 3002 return -1;
cf3ef16d 3003 }
2c6f3fc9
SH
3004 if (detect_shared_rootfs()) {
3005 if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
3006 SYSERROR("Failed to make / rslave");
3007 ERROR("Continuing...");
3008 }
3009 }
e7de366c
SG
3010 if (bdev->ops->mount(bdev) < 0) {
3011 bdev_put(bdev);
1354955b 3012 return -1;
e7de366c 3013 }
cf3ef16d 3014 } else { // TODO come up with a better way
f10fad2f 3015 free(bdev->dest);
cf3ef16d
SH
3016 bdev->dest = strdup(bdev->src);
3017 }
148e91f5
SH
3018
3019 if (!lxc_list_empty(&conf->hooks[LXCHOOK_CLONE])) {
3020 /* Start of environment variable setup for hooks */
ab7efcf5 3021 if (c0->name && setenv("LXC_SRC_NAME", c0->name, 1)) {
1143ed39
DE
3022 SYSERROR("failed to set environment variable for source container name");
3023 }
ab7efcf5 3024 if (c->name && setenv("LXC_NAME", c->name, 1)) {
148e91f5
SH
3025 SYSERROR("failed to set environment variable for container name");
3026 }
ab7efcf5 3027 if (conf->rcfile && setenv("LXC_CONFIG_FILE", conf->rcfile, 1)) {
148e91f5
SH
3028 SYSERROR("failed to set environment variable for config path");
3029 }
ab7efcf5 3030 if (bdev->dest && setenv("LXC_ROOTFS_MOUNT", bdev->dest, 1)) {
148e91f5
SH
3031 SYSERROR("failed to set environment variable for rootfs mount");
3032 }
ab7efcf5 3033 if (conf->rootfs.path && setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1)) {
148e91f5
SH
3034 SYSERROR("failed to set environment variable for rootfs mount");
3035 }
3036
283678ed 3037 if (run_lxc_hooks(c->name, "clone", conf, c->get_config_path(c), hookargs)) {
148e91f5 3038 ERROR("Error executing clone hook for %s", c->name);
e7de366c 3039 bdev_put(bdev);
1354955b 3040 return -1;
148e91f5
SH
3041 }
3042 }
3043
3044 if (!(flags & LXC_CLONE_KEEPNAME)) {
3045 ret = snprintf(path, MAXPATHLEN, "%s/etc/hostname", bdev->dest);
e7de366c
SG
3046 bdev_put(bdev);
3047
148e91f5 3048 if (ret < 0 || ret >= MAXPATHLEN)
1354955b 3049 return -1;
8058be39 3050 if (!file_exists(path))
1354955b 3051 return 0;
148e91f5 3052 if (!(fout = fopen(path, "w"))) {
959aee9c 3053 SYSERROR("unable to open %s: ignoring", path);
1354955b 3054 return 0;
148e91f5 3055 }
a684f0b7
ÇO
3056 if (fprintf(fout, "%s", c->name) < 0) {
3057 fclose(fout);
1354955b 3058 return -1;
6849cb5b 3059 }
148e91f5 3060 if (fclose(fout) < 0)
1354955b 3061 return -1;
9be53773 3062 }
e7de366c
SG
3063 else
3064 bdev_put(bdev);
3065
1354955b
SH
3066 return 0;
3067}
3068
3069static int clone_update_rootfs_wrapper(void *data)
3070{
3071 struct clone_update_data *arg = (struct clone_update_data *) data;
3072 return clone_update_rootfs(arg);
9be53773
SH
3073}
3074
3075/*
3076 * We want to support:
3077sudo lxc-clone -o o1 -n n1 -s -L|-fssize fssize -v|--vgname vgname \
3078 -p|--lvprefix lvprefix -t|--fstype fstype -B backingstore
3079
3080-s [ implies overlayfs]
3081-s -B overlayfs
3082-s -B aufs
3083
3084only rootfs gets converted (copied/snapshotted) on clone.
3085*/
3086
d5752559 3087static int create_file_dirname(char *path, struct lxc_conf *conf)
9be53773 3088{
c32981c3 3089 char *p = strrchr(path, '/');
d5752559 3090 int ret = -1;
9be53773
SH
3091
3092 if (!p)
3093 return -1;
3094 *p = '\0';
d028235d 3095 ret = do_create_container_dir(path, conf);
9be53773
SH
3096 *p = '/';
3097 return ret;
3098}
3099
858377e4 3100static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char *newname,
9be53773 3101 const char *lxcpath, int flags,
d659597e 3102 const char *bdevtype, const char *bdevdata, uint64_t newsize,
148e91f5 3103 char **hookargs)
9be53773
SH
3104{
3105 struct lxc_container *c2 = NULL;
3106 char newpath[MAXPATHLEN];
176d9acb 3107 int ret, storage_copied = 0;
5eea90e8 3108 char *origroot = NULL, *saved_unexp_conf = NULL;
1354955b 3109 struct clone_update_data data;
3b392519 3110 size_t saved_unexp_len;
9be53773 3111 FILE *fout;
1354955b 3112 pid_t pid;
9be53773 3113
858377e4 3114 if (!c || !do_lxcapi_is_defined(c))
9be53773
SH
3115 return NULL;
3116
5cee8c50 3117 if (container_mem_lock(c))
9be53773
SH
3118 return NULL;
3119
39dc698c 3120 if (!is_stopped(c)) {
9be53773
SH
3121 ERROR("error: Original container (%s) is running", c->name);
3122 goto out;
3123 }
3124
3125 // Make sure the container doesn't yet exist.
05d53f4c
SH
3126 if (!newname)
3127 newname = c->name;
3128 if (!lxcpath)
858377e4 3129 lxcpath = do_lxcapi_get_config_path(c);
05d53f4c 3130 ret = snprintf(newpath, MAXPATHLEN, "%s/%s/config", lxcpath, newname);
6849cb5b 3131 if (ret < 0 || ret >= MAXPATHLEN) {
9be53773
SH
3132 SYSERROR("clone: failed making config pathname");
3133 goto out;
3134 }
3135 if (file_exists(newpath)) {
3136 ERROR("error: clone: %s exists", newpath);
3137 goto out;
3138 }
3139
d5752559 3140 ret = create_file_dirname(newpath, c->lxc_conf);
96532523 3141 if (ret < 0 && errno != EEXIST) {
9be53773
SH
3142 ERROR("Error creating container dir for %s", newpath);
3143 goto out;
3144 }
3145
3146 // copy the configuration, tweak it as needed,
8d2efe40
SH
3147 if (c->lxc_conf->rootfs.path) {
3148 origroot = c->lxc_conf->rootfs.path;
3149 c->lxc_conf->rootfs.path = NULL;
3150 }
9be53773
SH
3151 fout = fopen(newpath, "w");
3152 if (!fout) {
3153 SYSERROR("open %s", newpath);
3154 goto out;
3155 }
5eea90e8
SH
3156
3157 saved_unexp_conf = c->lxc_conf->unexpanded_config;
3b392519 3158 saved_unexp_len = c->lxc_conf->unexpanded_len;
5eea90e8
SH
3159 c->lxc_conf->unexpanded_config = strdup(saved_unexp_conf);
3160 if (!c->lxc_conf->unexpanded_config) {
3161 ERROR("Out of memory");
7d72b959 3162 fclose(fout);
5eea90e8
SH
3163 goto out;
3164 }
3165 clear_unexp_config_line(c->lxc_conf, "lxc.rootfs", false);
6b0d5538 3166 write_config(fout, c->lxc_conf);
9be53773 3167 fclose(fout);
8d2efe40 3168 c->lxc_conf->rootfs.path = origroot;
5eea90e8
SH
3169 free(c->lxc_conf->unexpanded_config);
3170 c->lxc_conf->unexpanded_config = saved_unexp_conf;
3171 saved_unexp_conf = NULL;
3b392519 3172 c->lxc_conf->unexpanded_len = saved_unexp_len;
9be53773 3173
05d53f4c 3174 sprintf(newpath, "%s/%s/rootfs", lxcpath, newname);
9be53773
SH
3175 if (mkdir(newpath, 0755) < 0) {
3176 SYSERROR("error creating %s", newpath);
3177 goto out;
3178 }
3179
1354955b
SH
3180 if (am_unpriv()) {
3181 if (chown_mapped_root(newpath, c->lxc_conf) < 0) {
959aee9c 3182 ERROR("Error chowning %s to container root", newpath);
1354955b
SH
3183 goto out;
3184 }
3185 }
3186
05d53f4c 3187 c2 = lxc_container_new(newname, lxcpath);
375c2258 3188 if (!c2) {
05d53f4c
SH
3189 ERROR("clone: failed to create new container (%s %s)", newname,
3190 lxcpath);
9be53773
SH
3191 goto out;
3192 }
8d2efe40
SH
3193
3194 // copy/snapshot rootfs's
3195 ret = copy_storage(c, c2, bdevtype, flags, bdevdata, newsize);
3196 if (ret < 0)
3197 goto out;
9be53773 3198
6b0d5538 3199
96532523 3200 // update utsname
3d7ad474
CB
3201 if (!(flags & LXC_CLONE_KEEPNAME)) {
3202 clear_unexp_config_line(c2->lxc_conf, "lxc.utsname", false);
3203
3204 if (!set_config_item_locked(c2, "lxc.utsname", newname)) {
3205 ERROR("Error setting new hostname");
3206 goto out;
3207 }
96532523
SH
3208 }
3209
619256b5
ÇO
3210 // copy hooks
3211 ret = copyhooks(c, c2);
3212 if (ret < 0) {
3213 ERROR("error copying hooks");
3214 goto out;
9be53773
SH
3215 }
3216
3217 if (copy_fstab(c, c2) < 0) {
3218 ERROR("error copying fstab");
9be53773
SH
3219 goto out;
3220 }
3221
3222 // update macaddrs
6b0d5538 3223 if (!(flags & LXC_CLONE_KEEPMACADDR)) {
67702c21
SH
3224 if (!network_new_hwaddrs(c2->lxc_conf)) {
3225 ERROR("Error updating mac addresses");
6b0d5538
SH
3226 goto out;
3227 }
3228 }
9be53773 3229
030ce9a9 3230 // update absolute paths for overlay mount directories
83e79752 3231 if (ovl_update_abs_paths(c2->lxc_conf, c->config_path, c->name, lxcpath, newname) < 0)
030ce9a9
CB
3232 goto out;
3233
176d9acb
SH
3234 // We've now successfully created c2's storage, so clear it out if we
3235 // fail after this
3236 storage_copied = 1;
3237
375c2258 3238 if (!c2->save_config(c2, NULL))
9be53773 3239 goto out;
9be53773 3240
1354955b
SH
3241 if ((pid = fork()) < 0) {
3242 SYSERROR("fork");
9be53773 3243 goto out;
1354955b
SH
3244 }
3245 if (pid > 0) {
3246 ret = wait_for_pid(pid);
3247 if (ret)
3248 goto out;
3249 container_mem_unlock(c);
3250 return c2;
3251 }
3252 data.c0 = c;
3253 data.c1 = c2;
3254 data.flags = flags;
3255 data.hookargs = hookargs;
3256 if (am_unpriv())
3257 ret = userns_exec_1(c->lxc_conf, clone_update_rootfs_wrapper,
c9b7c33e 3258 &data, "clone_update_rootfs_wrapper");
1354955b
SH
3259 else
3260 ret = clone_update_rootfs(&data);
3261 if (ret < 0)
3262 exit(1);
9be53773 3263
5cee8c50 3264 container_mem_unlock(c);
1354955b 3265 exit(0);
9be53773
SH
3266
3267out:
5cee8c50 3268 container_mem_unlock(c);
375c2258 3269 if (c2) {
176d9acb
SH
3270 if (!storage_copied)
3271 c2->lxc_conf->rootfs.path = NULL;
375c2258 3272 c2->destroy(c2);
9be53773 3273 lxc_container_put(c2);
375c2258 3274 }
9be53773
SH
3275
3276 return NULL;
3277}
3278
858377e4
SH
3279static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *newname,
3280 const char *lxcpath, int flags,
3281 const char *bdevtype, const char *bdevdata, uint64_t newsize,
3282 char **hookargs)
3283{
3284 struct lxc_container * ret;
3285 current_config = c ? c->lxc_conf : NULL;
3286 ret = do_lxcapi_clone(c, newname, lxcpath, flags, bdevtype, bdevdata, newsize, hookargs);
3287 current_config = NULL;
3288 return ret;
3289}
3290
3291static bool do_lxcapi_rename(struct lxc_container *c, const char *newname)
06e5650e
ÇO
3292{
3293 struct bdev *bdev;
3294 struct lxc_container *newc;
06e5650e 3295
d693cf93 3296 if (!c || !c->name || !c->config_path || !c->lxc_conf)
06e5650e
ÇO
3297 return false;
3298
18aa217b
SH
3299 if (has_fs_snapshots(c) || has_snapshots(c)) {
3300 ERROR("Renaming a container with snapshots is not supported");
3301 return false;
3302 }
76a26f55 3303 bdev = bdev_init(c->lxc_conf, c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL);
06e5650e
ÇO
3304 if (!bdev) {
3305 ERROR("Failed to find original backing store type");
3306 return false;
3307 }
3308
619256b5 3309 newc = lxcapi_clone(c, newname, c->config_path, LXC_CLONE_KEEPMACADDR, NULL, bdev->type, 0, NULL);
06e5650e
ÇO
3310 bdev_put(bdev);
3311 if (!newc) {
3312 lxc_container_put(newc);
3313 return false;
3314 }
3315
3316 if (newc && lxcapi_is_defined(newc))
3317 lxc_container_put(newc);
3318
18aa217b 3319 if (!container_destroy(c)) {
06e5650e
ÇO
3320 ERROR("Could not destroy existing container %s", c->name);
3321 return false;
3322 }
3323 return true;
3324}
3325
858377e4
SH
3326WRAP_API_1(bool, lxcapi_rename, const char *)
3327
a0e93eeb
CS
3328static int lxcapi_attach(struct lxc_container *c, lxc_attach_exec_t exec_function, void *exec_payload, lxc_attach_options_t *options, pid_t *attached_process)
3329{
858377e4
SH
3330 int ret;
3331
a0e93eeb
CS
3332 if (!c)
3333 return -1;
3334
858377e4
SH
3335 current_config = c->lxc_conf;
3336
3337 ret = lxc_attach(c->name, c->config_path, exec_function, exec_payload, options, attached_process);
3338 current_config = NULL;
3339 return ret;
a0e93eeb
CS
3340}
3341
858377e4 3342static int do_lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char * const argv[])
a0e93eeb
CS
3343{
3344 lxc_attach_command_t command;
3345 pid_t pid;
3346 int r;
3347
3348 if (!c)
3349 return -1;
3350
3351 command.program = (char*)program;
3352 command.argv = (char**)argv;
3353 r = lxc_attach(c->name, c->config_path, lxc_attach_run_command, &command, options, &pid);
3354 if (r < 0) {
3355 ERROR("ups");
3356 return r;
3357 }
3358 return lxc_wait_for_pid_status(pid);
3359}
3360
858377e4
SH
3361static int lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char * const argv[])
3362{
3363 int ret;
3364 current_config = c ? c->lxc_conf : NULL;
3365 ret = do_lxcapi_attach_run_wait(c, options, program, argv);
3366 current_config = NULL;
3367 return ret;
3368}
3369
74a3920a 3370static int get_next_index(const char *lxcpath, char *cname)
f5dd1d53
SH
3371{
3372 char *fname;
3373 struct stat sb;
3374 int i = 0, ret;
3375
3376 fname = alloca(strlen(lxcpath) + 20);
3377 while (1) {
3378 sprintf(fname, "%s/snap%d", lxcpath, i);
3379 ret = stat(fname, &sb);
3380 if (ret != 0)
3381 return i;
3382 i++;
3383 }
3384}
3385
18aa217b
SH
3386static bool get_snappath_dir(struct lxc_container *c, char *snappath)
3387{
3388 int ret;
3389 /*
3390 * If the old style snapshot path exists, use it
3391 * /var/lib/lxc -> /var/lib/lxcsnaps
3392 */
3393 ret = snprintf(snappath, MAXPATHLEN, "%ssnaps", c->config_path);
3394 if (ret < 0 || ret >= MAXPATHLEN)
3395 return false;
3396 if (dir_exists(snappath)) {
3397 ret = snprintf(snappath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name);
3398 if (ret < 0 || ret >= MAXPATHLEN)
3399 return false;
3400 return true;
3401 }
3402
3403 /*
3404 * Use the new style path
3405 * /var/lib/lxc -> /var/lib/lxc + c->name + /snaps + \0
3406 */
3407 ret = snprintf(snappath, MAXPATHLEN, "%s/%s/snaps", c->config_path, c->name);
3408 if (ret < 0 || ret >= MAXPATHLEN)
3409 return false;
3410 return true;
3411}
3412
858377e4 3413static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
f5dd1d53
SH
3414{
3415 int i, flags, ret;
3416 struct lxc_container *c2;
3417 char snappath[MAXPATHLEN], newname[20];
3418
840f05df
SH
3419 if (!c || !lxcapi_is_defined(c))
3420 return -1;
3421
cdd01be2
SH
3422 if (!bdev_can_backup(c->lxc_conf)) {
3423 ERROR("%s's backing store cannot be backed up.", c->name);
3424 ERROR("Your container must use another backing store type.");
3425 return -1;
3426 }
3427
18aa217b 3428 if (!get_snappath_dir(c, snappath))
f5dd1d53 3429 return -1;
18aa217b 3430
f5dd1d53
SH
3431 i = get_next_index(snappath, c->name);
3432
3433 if (mkdir_p(snappath, 0755) < 0) {
3434 ERROR("Failed to create snapshot directory %s", snappath);
3435 return -1;
3436 }
3437
3438 ret = snprintf(newname, 20, "snap%d", i);
3439 if (ret < 0 || ret >= 20)
3440 return -1;
3441
0a83cbbb
SH
3442 /*
3443 * We pass LXC_CLONE_SNAPSHOT to make sure that a rdepends file entry is
3444 * created in the original container
3445 */
3446 flags = LXC_CLONE_SNAPSHOT | LXC_CLONE_KEEPMACADDR | LXC_CLONE_KEEPNAME |
3447 LXC_CLONE_KEEPBDEVTYPE | LXC_CLONE_MAYBE_SNAPSHOT;
76a26f55 3448 if (bdev_is_dir(c->lxc_conf, c->lxc_conf->rootfs.path)) {
8c39f7a4
SH
3449 ERROR("Snapshot of directory-backed container requested.");
3450 ERROR("Making a copy-clone. If you do want snapshots, then");
1f92162d 3451 ERROR("please create an aufs or overlayfs clone first, snapshot that");
8c39f7a4
SH
3452 ERROR("and keep the original container pristine.");
3453 flags &= ~LXC_CLONE_SNAPSHOT | LXC_CLONE_MAYBE_SNAPSHOT;
3454 }
858377e4 3455 c2 = do_lxcapi_clone(c, newname, snappath, flags, NULL, NULL, 0, NULL);
f5dd1d53 3456 if (!c2) {
959aee9c 3457 ERROR("clone of %s:%s failed", c->config_path, c->name);
f5dd1d53
SH
3458 return -1;
3459 }
3460
3461 lxc_container_put(c2);
3462
3463 // Now write down the creation time
3464 time_t timer;
3465 char buffer[25];
3466 struct tm* tm_info;
025ed0f3 3467 FILE *f;
f5dd1d53
SH
3468
3469 time(&timer);
3470 tm_info = localtime(&timer);
3471
3472 strftime(buffer, 25, "%Y:%m:%d %H:%M:%S", tm_info);
3473
3474 char *dfnam = alloca(strlen(snappath) + strlen(newname) + 5);
3475 sprintf(dfnam, "%s/%s/ts", snappath, newname);
025ed0f3 3476 f = fopen(dfnam, "w");
f5dd1d53 3477 if (!f) {
959aee9c 3478 ERROR("Failed to open %s", dfnam);
f5dd1d53
SH
3479 return -1;
3480 }
3481 if (fprintf(f, "%s", buffer) < 0) {
3482 SYSERROR("Writing timestamp");
3483 fclose(f);
3484 return -1;
3485 }
025ed0f3 3486 ret = fclose(f);
025ed0f3 3487 if (ret != 0) {
f5dd1d53
SH
3488 SYSERROR("Writing timestamp");
3489 return -1;
3490 }
3491
3492 if (commentfile) {
3493 // $p / $name / comment \0
3494 int len = strlen(snappath) + strlen(newname) + 10;
3495 char *path = alloca(len);
3496 sprintf(path, "%s/%s/comment", snappath, newname);
3497 return copy_file(commentfile, path) < 0 ? -1 : i;
3498 }
3499
3500 return i;
3501}
3502
858377e4
SH
3503WRAP_API_1(int, lxcapi_snapshot, const char *)
3504
f5dd1d53
SH
3505static void lxcsnap_free(struct lxc_snapshot *s)
3506{
f10fad2f
ME
3507 free(s->name);
3508 free(s->comment_pathname);
3509 free(s->timestamp);
3510 free(s->lxcpath);
f5dd1d53
SH
3511}
3512
3513static char *get_snapcomment_path(char* snappath, char *name)
3514{
3515 // $snappath/$name/comment
3516 int ret, len = strlen(snappath) + strlen(name) + 10;
3517 char *s = malloc(len);
3518
3519 if (s) {
3520 ret = snprintf(s, len, "%s/%s/comment", snappath, name);
3521 if (ret < 0 || ret >= len) {
3522 free(s);
3523 s = NULL;
3524 }
3525 }
3526 return s;
3527}
3528
3529static char *get_timestamp(char* snappath, char *name)
3530{
3531 char path[MAXPATHLEN], *s = NULL;
3532 int ret, len;
3533 FILE *fin;
3534
3535 ret = snprintf(path, MAXPATHLEN, "%s/%s/ts", snappath, name);
3536 if (ret < 0 || ret >= MAXPATHLEN)
3537 return NULL;
025ed0f3 3538 fin = fopen(path, "r");
025ed0f3 3539 if (!fin)
f5dd1d53
SH
3540 return NULL;
3541 (void) fseek(fin, 0, SEEK_END);
3542 len = ftell(fin);
3543 (void) fseek(fin, 0, SEEK_SET);
3544 if (len > 0) {
3545 s = malloc(len+1);
3546 if (s) {
3547 s[len] = '\0';
3548 if (fread(s, 1, len, fin) != len) {
3549 SYSERROR("reading timestamp");
3550 free(s);
3551 s = NULL;
3552 }
3553 }
3554 }
3555 fclose(fin);
3556 return s;
3557}
3558
858377e4 3559static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **ret_snaps)
f5dd1d53
SH
3560{
3561 char snappath[MAXPATHLEN], path2[MAXPATHLEN];
18aa217b 3562 int count = 0, ret;
74f96976 3563 struct dirent *direntp;
f5dd1d53
SH
3564 struct lxc_snapshot *snaps =NULL, *nsnaps;
3565 DIR *dir;
3566
3567 if (!c || !lxcapi_is_defined(c))
3568 return -1;
c868b261 3569
18aa217b 3570 if (!get_snappath_dir(c, snappath)) {
f5dd1d53
SH
3571 ERROR("path name too long");
3572 return -1;
3573 }
025ed0f3 3574 dir = opendir(snappath);
025ed0f3 3575 if (!dir) {
f5dd1d53
SH
3576 INFO("failed to open %s - assuming no snapshots", snappath);
3577 return 0;
3578 }
3579
74f96976 3580 while ((direntp = readdir(dir))) {
f5dd1d53
SH
3581 if (!direntp)
3582 break;
3583
3584 if (!strcmp(direntp->d_name, "."))
3585 continue;
3586
3587 if (!strcmp(direntp->d_name, ".."))
3588 continue;
3589
3590 ret = snprintf(path2, MAXPATHLEN, "%s/%s/config", snappath, direntp->d_name);
3591 if (ret < 0 || ret >= MAXPATHLEN) {
3592 ERROR("pathname too long");
3593 goto out_free;
3594 }
3595 if (!file_exists(path2))
3596 continue;
3597 nsnaps = realloc(snaps, (count + 1)*sizeof(*snaps));
3598 if (!nsnaps) {
3599 SYSERROR("Out of memory");
3600 goto out_free;
3601 }
3602 snaps = nsnaps;
3603 snaps[count].free = lxcsnap_free;
3604 snaps[count].name = strdup(direntp->d_name);
3605 if (!snaps[count].name)
3606 goto out_free;
3607 snaps[count].lxcpath = strdup(snappath);
3608 if (!snaps[count].lxcpath) {
3609 free(snaps[count].name);
3610 goto out_free;
3611 }
3612 snaps[count].comment_pathname = get_snapcomment_path(snappath, direntp->d_name);
3613 snaps[count].timestamp = get_timestamp(snappath, direntp->d_name);
3614 count++;
3615 }
3616
3617 if (closedir(dir))
3618 WARN("failed to close directory");
3619
3620 *ret_snaps = snaps;
3621 return count;
3622
3623out_free:
3624 if (snaps) {
3625 int i;
3626 for (i=0; i<count; i++)
3627 lxcsnap_free(&snaps[i]);
3628 free(snaps);
3629 }
9baa57bd
SH
3630 if (closedir(dir))
3631 WARN("failed to close directory");
f5dd1d53
SH
3632 return -1;
3633}
3634
858377e4
SH
3635WRAP_API_1(int, lxcapi_snapshot_list, struct lxc_snapshot **)
3636
3637static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snapname, const char *newname)
f5dd1d53
SH
3638{
3639 char clonelxcpath[MAXPATHLEN];
18aa217b 3640 int flags = 0;
f5dd1d53
SH
3641 struct lxc_container *snap, *rest;
3642 struct bdev *bdev;
3643 bool b = false;
3644
3645 if (!c || !c->name || !c->config_path)
3646 return false;
3647
18aa217b
SH
3648 if (has_fs_snapshots(c)) {
3649 ERROR("container rootfs has dependent snapshots");
3650 return false;
3651 }
3652
76a26f55 3653 bdev = bdev_init(c->lxc_conf, c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL);
f5dd1d53
SH
3654 if (!bdev) {
3655 ERROR("Failed to find original backing store type");
3656 return false;
3657 }
3658
3659 if (!newname)
3660 newname = c->name;
7e36f87e 3661
18aa217b 3662 if (!get_snappath_dir(c, clonelxcpath)) {
f5dd1d53
SH
3663 bdev_put(bdev);
3664 return false;
3665 }
3666 // how should we lock this?
3667
3668 snap = lxc_container_new(snapname, clonelxcpath);
3669 if (!snap || !lxcapi_is_defined(snap)) {
3670 ERROR("Could not open snapshot %s", snapname);
3671 if (snap) lxc_container_put(snap);
3672 bdev_put(bdev);
3673 return false;
3674 }
3675
7e36f87e 3676 if (strcmp(c->name, newname) == 0) {
18aa217b 3677 if (!container_destroy(c)) {
7e36f87e
ÇO
3678 ERROR("Could not destroy existing container %s", newname);
3679 lxc_container_put(snap);
3680 bdev_put(bdev);
3681 return false;
3682 }
3683 }
3684
de269ee8
SH
3685 if (strcmp(bdev->type, "dir") != 0 && strcmp(bdev->type, "loop") != 0)
3686 flags = LXC_CLONE_SNAPSHOT | LXC_CLONE_MAYBE_SNAPSHOT;
3687 rest = lxcapi_clone(snap, newname, c->config_path, flags,
3688 bdev->type, NULL, 0, NULL);
f5dd1d53
SH
3689 bdev_put(bdev);
3690 if (rest && lxcapi_is_defined(rest))
3691 b = true;
3692 if (rest)
3693 lxc_container_put(rest);
3694 lxc_container_put(snap);
3695 return b;
3696}
3697
858377e4
SH
3698WRAP_API_2(bool, lxcapi_snapshot_restore, const char *, const char *)
3699
18aa217b 3700static bool do_snapshot_destroy(const char *snapname, const char *clonelxcpath)
771d96b3 3701{
771d96b3 3702 struct lxc_container *snap = NULL;
18aa217b 3703 bool bret = false;
771d96b3
ÇO
3704
3705 snap = lxc_container_new(snapname, clonelxcpath);
18aa217b 3706 if (!snap) {
771d96b3
ÇO
3707 ERROR("Could not find snapshot %s", snapname);
3708 goto err;
3709 }
3710
858377e4 3711 if (!do_lxcapi_destroy(snap)) {
771d96b3
ÇO
3712 ERROR("Could not destroy snapshot %s", snapname);
3713 goto err;
3714 }
18aa217b 3715 bret = true;
771d96b3 3716
771d96b3
ÇO
3717err:
3718 if (snap)
3719 lxc_container_put(snap);
18aa217b
SH
3720 return bret;
3721}
3722
3723static bool remove_all_snapshots(const char *path)
3724{
3725 DIR *dir;
74f96976 3726 struct dirent *direntp;
18aa217b
SH
3727 bool bret = true;
3728
3729 dir = opendir(path);
3730 if (!dir) {
3731 SYSERROR("opendir on snapshot path %s", path);
3732 return false;
3733 }
74f96976 3734 while ((direntp = readdir(dir))) {
18aa217b
SH
3735 if (!direntp)
3736 break;
3737 if (!strcmp(direntp->d_name, "."))
3738 continue;
3739 if (!strcmp(direntp->d_name, ".."))
3740 continue;
3741 if (!do_snapshot_destroy(direntp->d_name, path)) {
3742 bret = false;
3743 continue;
3744 }
3745 }
3746
3747 closedir(dir);
3748
3749 if (rmdir(path))
3750 SYSERROR("Error removing directory %s", path);
3751
3752 return bret;
3753}
3754
858377e4 3755static bool do_lxcapi_snapshot_destroy(struct lxc_container *c, const char *snapname)
18aa217b
SH
3756{
3757 char clonelxcpath[MAXPATHLEN];
3758
3759 if (!c || !c->name || !c->config_path || !snapname)
3760 return false;
3761
3762 if (!get_snappath_dir(c, clonelxcpath))
3763 return false;
3764
3765 return do_snapshot_destroy(snapname, clonelxcpath);
3766}
3767
858377e4
SH
3768WRAP_API_1(bool, lxcapi_snapshot_destroy, const char *)
3769
3770static bool do_lxcapi_snapshot_destroy_all(struct lxc_container *c)
18aa217b
SH
3771{
3772 char clonelxcpath[MAXPATHLEN];
3773
3774 if (!c || !c->name || !c->config_path)
3775 return false;
3776
3777 if (!get_snappath_dir(c, clonelxcpath))
3778 return false;
3779
3780 return remove_all_snapshots(clonelxcpath);
771d96b3
ÇO
3781}
3782
858377e4
SH
3783WRAP_API(bool, lxcapi_snapshot_destroy_all)
3784
3785static bool do_lxcapi_may_control(struct lxc_container *c)
b494d2dd
SH
3786{
3787 return lxc_try_cmd(c->name, c->config_path) == 0;
3788}
3789
858377e4
SH
3790WRAP_API(bool, lxcapi_may_control)
3791
d5aa23e6
SH
3792static bool do_add_remove_node(pid_t init_pid, const char *path, bool add,
3793 struct stat *st)
3794{
3795 char chrootpath[MAXPATHLEN];
3796 char *directory_path = NULL;
3797 pid_t pid;
3798 int ret;
3799
3800 if ((pid = fork()) < 0) {
3801 SYSERROR("failed to fork a child helper");
3802 return false;
3803 }
3804 if (pid) {
3805 if (wait_for_pid(pid) != 0) {
3806 ERROR("Failed to create note in guest");
3807 return false;
3808 }
3809 return true;
3810 }
3811
3812 /* prepare the path */
3813 ret = snprintf(chrootpath, MAXPATHLEN, "/proc/%d/root", init_pid);
3814 if (ret < 0 || ret >= MAXPATHLEN)
3815 return false;
3816
6b9324bd 3817 if (chroot(chrootpath) < 0)
d5aa23e6 3818 exit(1);
6b9324bd 3819 if (chdir("/") < 0)
d5aa23e6
SH
3820 exit(1);
3821 /* remove path if it exists */
3822 if(faccessat(AT_FDCWD, path, F_OK, AT_SYMLINK_NOFOLLOW) == 0) {
3823 if (unlink(path) < 0) {
3824 ERROR("unlink failed");
3825 exit(1);
3826 }
3827 }
3828 if (!add)
3829 exit(0);
3830
3831 /* create any missing directories */
3832 directory_path = dirname(strdup(path));
3833 if (mkdir_p(directory_path, 0755) < 0 && errno != EEXIST) {
3834 ERROR("failed to create directory");
3835 exit(1);
3836 }
3837
3838 /* create the device node */
3839 if (mknod(path, st->st_mode, st->st_rdev) < 0) {
3840 ERROR("mknod failed");
3841 exit(1);
3842 }
3843
3844 exit(0);
3845}
3846
f0ca2726 3847static bool add_remove_device_node(struct lxc_container *c, const char *src_path, const char *dest_path, bool add)
a9a0ed90
ÇO
3848{
3849 int ret;
3850 struct stat st;
a9a0ed90 3851 char value[MAX_BUFFER];
f0ca2726 3852 const char *p;
a9a0ed90
ÇO
3853
3854 /* make sure container is running */
858377e4 3855 if (!do_lxcapi_is_running(c)) {
a9a0ed90 3856 ERROR("container is not running");
d5aa23e6 3857 return false;
a9a0ed90
ÇO
3858 }
3859
3860 /* use src_path if dest_path is NULL otherwise use dest_path */
3861 p = dest_path ? dest_path : src_path;
3862
a9a0ed90
ÇO
3863 /* make sure we can access p */
3864 if(access(p, F_OK) < 0 || stat(p, &st) < 0)
d5aa23e6 3865 return false;
a9a0ed90
ÇO
3866
3867 /* continue if path is character device or block device */
c6a9b0d7 3868 if (S_ISCHR(st.st_mode))
a9a0ed90 3869 ret = snprintf(value, MAX_BUFFER, "c %d:%d rwm", major(st.st_rdev), minor(st.st_rdev));
c6a9b0d7 3870 else if (S_ISBLK(st.st_mode))
a9a0ed90
ÇO
3871 ret = snprintf(value, MAX_BUFFER, "b %d:%d rwm", major(st.st_rdev), minor(st.st_rdev));
3872 else
d5aa23e6 3873 return false;
a9a0ed90
ÇO
3874
3875 /* check snprintf return code */
3876 if (ret < 0 || ret >= MAX_BUFFER)
d5aa23e6 3877 return false;
a9a0ed90 3878
858377e4 3879 if (!do_add_remove_node(do_lxcapi_init_pid(c), p, add, &st))
d5aa23e6 3880 return false;
a9a0ed90 3881
d5aa23e6 3882 /* add or remove device to/from cgroup access list */
a9a0ed90 3883 if (add) {
858377e4 3884 if (!do_lxcapi_set_cgroup_item(c, "devices.allow", value)) {
a9a0ed90 3885 ERROR("set_cgroup_item failed while adding the device node");
d5aa23e6 3886 return false;
a9a0ed90
ÇO
3887 }
3888 } else {
858377e4 3889 if (!do_lxcapi_set_cgroup_item(c, "devices.deny", value)) {
a9a0ed90 3890 ERROR("set_cgroup_item failed while removing the device node");
d5aa23e6 3891 return false;
a9a0ed90
ÇO
3892 }
3893 }
d5aa23e6 3894
a9a0ed90 3895 return true;
a9a0ed90
ÇO
3896}
3897
858377e4 3898static bool do_lxcapi_add_device_node(struct lxc_container *c, const char *src_path, const char *dest_path)
a9a0ed90 3899{
c868b261
ÇO
3900 if (am_unpriv()) {
3901 ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
3902 return false;
3903 }
a9a0ed90
ÇO
3904 return add_remove_device_node(c, src_path, dest_path, true);
3905}
3906
858377e4
SH
3907WRAP_API_2(bool, lxcapi_add_device_node, const char *, const char *)
3908
3909static bool do_lxcapi_remove_device_node(struct lxc_container *c, const char *src_path, const char *dest_path)
a9a0ed90 3910{
c868b261
ÇO
3911 if (am_unpriv()) {
3912 ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
3913 return false;
3914 }
a9a0ed90
ÇO
3915 return add_remove_device_node(c, src_path, dest_path, false);
3916}
3917
858377e4
SH
3918WRAP_API_2(bool, lxcapi_remove_device_node, const char *, const char *)
3919
3920static bool do_lxcapi_attach_interface(struct lxc_container *c, const char *ifname,
e58fae8f
DY
3921 const char *dst_ifname)
3922{
3923 int ret = 0;
3924 if (am_unpriv()) {
3925 ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
3926 return false;
3927 }
3928
3929 if (!ifname) {
3930 ERROR("No source interface name given");
3931 return false;
3932 }
3933
3934 ret = lxc_netdev_isup(ifname);
e58fae8f 3935
e5848d39
SH
3936 if (ret > 0) {
3937 /* netdev of ifname is up. */
e58fae8f
DY
3938 ret = lxc_netdev_down(ifname);
3939 if (ret)
3940 goto err;
3941 }
3942
858377e4 3943 ret = lxc_netdev_move_by_name(ifname, do_lxcapi_init_pid(c), dst_ifname);
e58fae8f
DY
3944 if (ret)
3945 goto err;
3946
3947 return true;
e5848d39 3948
e58fae8f 3949err:
e58fae8f
DY
3950 return false;
3951}
3952
858377e4
SH
3953WRAP_API_2(bool, lxcapi_attach_interface, const char *, const char *)
3954
3955static bool do_lxcapi_detach_interface(struct lxc_container *c, const char *ifname,
e58fae8f
DY
3956 const char *dst_ifname)
3957{
3958 pid_t pid, pid_outside;
3959
3960 if (am_unpriv()) {
3961 ERROR(NOT_SUPPORTED_ERROR, __FUNCTION__);
3962 return false;
3963 }
3964
3965 if (!ifname) {
3966 ERROR("No source interface name given");
3967 return false;
3968 }
3969
3970 pid_outside = getpid();
3971 pid = fork();
3972 if (pid < 0) {
3973 ERROR("failed to fork task to get interfaces information");
3974 return false;
3975 }
3976
3977 if (pid == 0) { // child
3978 int ret = 0;
e0f59189 3979 if (!enter_net_ns(c)) {
e58fae8f
DY
3980 ERROR("failed to enter namespace");
3981 exit(-1);
3982 }
3983
3984 ret = lxc_netdev_isup(ifname);
3985 if (ret < 0)
3986 exit(ret);
3987
3988 /* netdev of ifname is up. */
3989 if (ret) {
3990 ret = lxc_netdev_down(ifname);
3991 if (ret)
3992 exit(ret);
3993 }
3994
3995 ret = lxc_netdev_move_by_name(ifname, pid_outside, dst_ifname);
3996
3997 /* -EINVAL means there is no netdev named as ifanme. */
3998 if (ret == -EINVAL) {
3999 ERROR("No network device named as %s.", ifname);
4000 }
4001 exit(ret);
4002 }
4003
4004 if (wait_for_pid(pid) != 0)
4005 return false;
4006
4007 return true;
4008}
4009
858377e4
SH
4010WRAP_API_2(bool, lxcapi_detach_interface, const char *, const char *)
4011
aef3d51e
TA
4012static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
4013 struct migrate_opts *opts, unsigned int size)
bbd4e13e 4014{
aef3d51e 4015 int ret;
2cb80427 4016 struct migrate_opts *valid_opts = opts;
85c50991 4017
aef3d51e
TA
4018 /* If the caller has a bigger (newer) struct migrate_opts, let's make
4019 * sure that the stuff on the end is zero, i.e. that they didn't ask us
4020 * to do anything special.
4021 */
4022 if (size > sizeof(*opts)) {
4023 unsigned char *addr;
4024 unsigned char *end;
4025
4026 addr = (void *)opts + sizeof(*opts);
4027 end = (void *)opts + size;
4028 for (; addr < end; addr++) {
4029 if (*addr) {
4030 return -E2BIG;
4031 }
4032 }
85c50991
TA
4033 }
4034
2cb80427
TA
4035 /* If the caller has a smaller struct, let's zero out the end for them
4036 * so we don't accidentally use bits of it that they didn't know about
4037 * to initialize.
4038 */
4039 if (size < sizeof(*opts)) {
4040 valid_opts = malloc(sizeof(*opts));
4041 if (!valid_opts)
4042 return -ENOMEM;
4043
4044 memset(valid_opts, 0, sizeof(*opts));
4045 memcpy(valid_opts, opts, size);
4046 }
4047
aef3d51e
TA
4048 switch (cmd) {
4049 case MIGRATE_PRE_DUMP:
7ad13c91
TA
4050 if (!do_lxcapi_is_running(c)) {
4051 ERROR("container is not running");
4052 return false;
4053 }
2cb80427 4054 ret = !__criu_pre_dump(c, valid_opts);
aef3d51e
TA
4055 break;
4056 case MIGRATE_DUMP:
7ad13c91
TA
4057 if (!do_lxcapi_is_running(c)) {
4058 ERROR("container is not running");
4059 return false;
4060 }
2cb80427 4061 ret = !__criu_dump(c, valid_opts);
aef3d51e
TA
4062 break;
4063 case MIGRATE_RESTORE:
7ad13c91
TA
4064 if (do_lxcapi_is_running(c)) {
4065 ERROR("container is already running");
4066 return false;
4067 }
2cb80427 4068 ret = !__criu_restore(c, valid_opts);
aef3d51e
TA
4069 break;
4070 default:
4071 ERROR("invalid migrate command %u", cmd);
4072 ret = -EINVAL;
4073 }
735f2c6e 4074
f686506d
TA
4075 if (size < sizeof(*opts))
4076 free(valid_opts);
4077
aef3d51e
TA
4078 return ret;
4079}
735f2c6e 4080
aef3d51e 4081WRAP_API_3(int, lxcapi_migrate, unsigned int, struct migrate_opts *, unsigned int)
735f2c6e 4082
aef3d51e
TA
4083static bool do_lxcapi_checkpoint(struct lxc_container *c, char *directory, bool stop, bool verbose)
4084{
ebb088e1
AR
4085 struct migrate_opts opts;
4086
4087 memset(&opts, 0, sizeof(opts));
4088
4089 opts.directory = directory;
4090 opts.stop = stop;
4091 opts.verbose = verbose;
735f2c6e 4092
aef3d51e 4093 return !do_lxcapi_migrate(c, MIGRATE_DUMP, &opts, sizeof(opts));
735f2c6e
TA
4094}
4095
858377e4
SH
4096WRAP_API_3(bool, lxcapi_checkpoint, char *, bool, bool)
4097
4098static bool do_lxcapi_restore(struct lxc_container *c, char *directory, bool verbose)
c9d8f2ee 4099{
ebb088e1
AR
4100 struct migrate_opts opts;
4101
4102 memset(&opts, 0, sizeof(opts));
4103
4104 opts.directory = directory;
4105 opts.verbose = verbose;
c9d8f2ee 4106
aef3d51e 4107 return !do_lxcapi_migrate(c, MIGRATE_RESTORE, &opts, sizeof(opts));
735f2c6e
TA
4108}
4109
858377e4
SH
4110WRAP_API_2(bool, lxcapi_restore, char *, bool)
4111
a0e93eeb
CS
4112static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...)
4113{
4114 va_list ap;
4115 const char **argv;
4116 int ret;
4117
4118 if (!c)
4119 return -1;
4120
858377e4
SH
4121 current_config = c->lxc_conf;
4122
a0e93eeb
CS
4123 va_start(ap, arg);
4124 argv = lxc_va_arg_list_to_argv_const(ap, 1);
4125 va_end(ap);
4126
4127 if (!argv) {
4128 ERROR("Memory allocation error.");
858377e4
SH
4129 ret = -1;
4130 goto out;
a0e93eeb
CS
4131 }
4132 argv[0] = arg;
4133
858377e4 4134 ret = do_lxcapi_attach_run_wait(c, options, program, (const char * const *)argv);
a0e93eeb 4135 free((void*)argv);
858377e4
SH
4136out:
4137 current_config = NULL;
a0e93eeb
CS
4138 return ret;
4139}
4140
afeecbba 4141struct lxc_container *lxc_container_new(const char *name, const char *configpath)
72d0e1cb
SG
4142{
4143 struct lxc_container *c;
72d0e1cb 4144
18aa217b
SH
4145 if (!name)
4146 return NULL;
4147
72d0e1cb
SG
4148 c = malloc(sizeof(*c));
4149 if (!c) {
4150 fprintf(stderr, "failed to malloc lxc_container\n");
4151 return NULL;
4152 }
4153 memset(c, 0, sizeof(*c));
4154
afeecbba
SH
4155 if (configpath)
4156 c->config_path = strdup(configpath);
4157 else
593e8478 4158 c->config_path = strdup(lxc_global_config_value("lxc.lxcpath"));
afeecbba 4159
2a59a681 4160 if (!c->config_path) {
03fadd16 4161 fprintf(stderr, "Out of memory\n");
2a59a681
SH
4162 goto err;
4163 }
4164
f5dd1d53 4165 remove_trailing_slashes(c->config_path);
72d0e1cb
SG
4166 c->name = malloc(strlen(name)+1);
4167 if (!c->name) {
4168 fprintf(stderr, "Error allocating lxc_container name\n");
4169 goto err;
4170 }
4171 strcpy(c->name, name);
4172
4173 c->numthreads = 1;
df271a59 4174 if (!(c->slock = lxc_newlock(c->config_path, name))) {
72d0e1cb
SG
4175 fprintf(stderr, "failed to create lock\n");
4176 goto err;
4177 }
4178
df271a59 4179 if (!(c->privlock = lxc_newlock(NULL, NULL))) {
72d0e1cb
SG
4180 fprintf(stderr, "failed to alloc privlock\n");
4181 goto err;
4182 }
4183
afeecbba 4184 if (!set_config_filename(c)) {
72d0e1cb
SG
4185 fprintf(stderr, "Error allocating config file pathname\n");
4186 goto err;
4187 }
72d0e1cb 4188
bac806d1
SH
4189 if (file_exists(c->configfile) && !lxcapi_load_config(c, NULL))
4190 goto err;
72d0e1cb 4191
3e625e2d
SH
4192 if (ongoing_create(c) == 2) {
4193 ERROR("Error: %s creation was not completed", c->name);
18aa217b 4194 container_destroy(c);
4df7f012 4195 lxcapi_clear_config(c);
3e625e2d 4196 }
a2739df5 4197 c->daemonize = true;
72cf75fa 4198 c->pidfile = NULL;
3e625e2d 4199
72d0e1cb
SG
4200 // assign the member functions
4201 c->is_defined = lxcapi_is_defined;
4202 c->state = lxcapi_state;
4203 c->is_running = lxcapi_is_running;
4204 c->freeze = lxcapi_freeze;
4205 c->unfreeze = lxcapi_unfreeze;
0115f8fd 4206 c->console = lxcapi_console;
b5159817 4207 c->console_getfd = lxcapi_console_getfd;
72d0e1cb
SG
4208 c->init_pid = lxcapi_init_pid;
4209 c->load_config = lxcapi_load_config;
4210 c->want_daemonize = lxcapi_want_daemonize;
130a1888 4211 c->want_close_all_fds = lxcapi_want_close_all_fds;
72d0e1cb
SG
4212 c->start = lxcapi_start;
4213 c->startl = lxcapi_startl;
4214 c->stop = lxcapi_stop;
4215 c->config_file_name = lxcapi_config_file_name;
4216 c->wait = lxcapi_wait;
4217 c->set_config_item = lxcapi_set_config_item;
4218 c->destroy = lxcapi_destroy;
18aa217b 4219 c->destroy_with_snapshots = lxcapi_destroy_with_snapshots;
06e5650e 4220 c->rename = lxcapi_rename;
72d0e1cb
SG
4221 c->save_config = lxcapi_save_config;
4222 c->get_keys = lxcapi_get_keys;
4223 c->create = lxcapi_create;
4224 c->createl = lxcapi_createl;
4225 c->shutdown = lxcapi_shutdown;
3e625e2d 4226 c->reboot = lxcapi_reboot;
4df7f012 4227 c->clear_config = lxcapi_clear_config;
72d0e1cb
SG
4228 c->clear_config_item = lxcapi_clear_config_item;
4229 c->get_config_item = lxcapi_get_config_item;
8ac18377 4230 c->get_running_config_item = lxcapi_get_running_config_item;
794dd120
SH
4231 c->get_cgroup_item = lxcapi_get_cgroup_item;
4232 c->set_cgroup_item = lxcapi_set_cgroup_item;
2a59a681
SH
4233 c->get_config_path = lxcapi_get_config_path;
4234 c->set_config_path = lxcapi_set_config_path;
9be53773 4235 c->clone = lxcapi_clone;
799f29ab 4236 c->get_interfaces = lxcapi_get_interfaces;
9c83a661 4237 c->get_ips = lxcapi_get_ips;
a0e93eeb
CS
4238 c->attach = lxcapi_attach;
4239 c->attach_run_wait = lxcapi_attach_run_wait;
4240 c->attach_run_waitl = lxcapi_attach_run_waitl;
f5dd1d53
SH
4241 c->snapshot = lxcapi_snapshot;
4242 c->snapshot_list = lxcapi_snapshot_list;
4243 c->snapshot_restore = lxcapi_snapshot_restore;
771d96b3 4244 c->snapshot_destroy = lxcapi_snapshot_destroy;
18aa217b 4245 c->snapshot_destroy_all = lxcapi_snapshot_destroy_all;
b494d2dd 4246 c->may_control = lxcapi_may_control;
a9a0ed90
ÇO
4247 c->add_device_node = lxcapi_add_device_node;
4248 c->remove_device_node = lxcapi_remove_device_node;
e58fae8f
DY
4249 c->attach_interface = lxcapi_attach_interface;
4250 c->detach_interface = lxcapi_detach_interface;
735f2c6e
TA
4251 c->checkpoint = lxcapi_checkpoint;
4252 c->restore = lxcapi_restore;
aef3d51e 4253 c->migrate = lxcapi_migrate;
72d0e1cb 4254
72d0e1cb
SG
4255 return c;
4256
4257err:
4258 lxc_container_free(c);
4259 return NULL;
4260}
4261
4a7c7daa 4262int lxc_get_wait_states(const char **states)
72d0e1cb
SG
4263{
4264 int i;
4265
4266 if (states)
4267 for (i=0; i<MAX_STATE; i++)
4268 states[i] = lxc_state2str(i);
4269 return MAX_STATE;
4270}
a41f104b 4271
a41f104b
SH
4272/*
4273 * These next two could probably be done smarter with reusing a common function
4274 * with different iterators and tests...
4275 */
4276int list_defined_containers(const char *lxcpath, char ***names, struct lxc_container ***cret)
4277{
4278 DIR *dir;
4279 int i, cfound = 0, nfound = 0;
74f96976 4280 struct dirent *direntp;
a41f104b
SH
4281 struct lxc_container *c;
4282
4283 if (!lxcpath)
593e8478 4284 lxcpath = lxc_global_config_value("lxc.lxcpath");
a41f104b 4285
a41f104b 4286 dir = opendir(lxcpath);
a41f104b
SH
4287 if (!dir) {
4288 SYSERROR("opendir on lxcpath");
4289 return -1;
4290 }
4291
4292 if (cret)
4293 *cret = NULL;
4294 if (names)
4295 *names = NULL;
4296
74f96976 4297 while ((direntp = readdir(dir))) {
a41f104b
SH
4298 if (!direntp)
4299 break;
e4ebeab1
CALP
4300
4301 // Ignore '.', '..' and any hidden directory
4302 if (!strncmp(direntp->d_name, ".", 1))
a41f104b
SH
4303 continue;
4304
4305 if (!config_file_exists(lxcpath, direntp->d_name))
4306 continue;
4307
4308 if (names) {
9c88ff1f 4309 if (!add_to_array(names, direntp->d_name, cfound))
a41f104b
SH
4310 goto free_bad;
4311 }
4312 cfound++;
4313
4314 if (!cret) {
4315 nfound++;
4316 continue;
4317 }
4318
4319 c = lxc_container_new(direntp->d_name, lxcpath);
4320 if (!c) {
4321 INFO("Container %s:%s has a config but could not be loaded",
4322 lxcpath, direntp->d_name);
4323 if (names)
9c88ff1f
ÇO
4324 if(!remove_from_array(names, direntp->d_name, cfound--))
4325 goto free_bad;
a41f104b
SH
4326 continue;
4327 }
858377e4 4328 if (!do_lxcapi_is_defined(c)) {
a41f104b
SH
4329 INFO("Container %s:%s has a config but is not defined",
4330 lxcpath, direntp->d_name);
4331 if (names)
9c88ff1f
ÇO
4332 if(!remove_from_array(names, direntp->d_name, cfound--))
4333 goto free_bad;
a41f104b
SH
4334 lxc_container_put(c);
4335 continue;
4336 }
4337
2871830a 4338 if (!add_to_clist(cret, c, nfound, true)) {
a41f104b
SH
4339 lxc_container_put(c);
4340 goto free_bad;
4341 }
4342 nfound++;
4343 }
4344
a41f104b 4345 closedir(dir);
a41f104b
SH
4346 return nfound;
4347
4348free_bad:
4349 if (names && *names) {
4350 for (i=0; i<cfound; i++)
4351 free((*names)[i]);
4352 free(*names);
4353 }
4354 if (cret && *cret) {
4355 for (i=0; i<nfound; i++)
4356 lxc_container_put((*cret)[i]);
4357 free(*cret);
4358 }
a41f104b 4359 closedir(dir);
a41f104b
SH
4360 return -1;
4361}
4362
148a9d27
DE
4363int list_active_containers(const char *lxcpath, char ***nret,
4364 struct lxc_container ***cret)
a41f104b 4365{
148a9d27 4366 int i, ret = -1, cret_cnt = 0, ct_name_cnt = 0;
a41f104b
SH
4367 int lxcpath_len;
4368 char *line = NULL;
148a9d27 4369 char **ct_name = NULL;
a41f104b 4370 size_t len = 0;
97bc2422 4371 struct lxc_container *c = NULL;
88556fd7 4372 bool is_hashed;
a41f104b
SH
4373
4374 if (!lxcpath)
593e8478 4375 lxcpath = lxc_global_config_value("lxc.lxcpath");
a41f104b
SH
4376 lxcpath_len = strlen(lxcpath);
4377
4378 if (cret)
4379 *cret = NULL;
148a9d27
DE
4380 if (nret)
4381 *nret = NULL;
a41f104b 4382
a41f104b 4383 FILE *f = fopen("/proc/net/unix", "r");
a41f104b
SH
4384 if (!f)
4385 return -1;
4386
4387 while (getline(&line, &len, f) != -1) {
88556fd7 4388
0f8f9c8a 4389 char *p = strrchr(line, ' '), *p2;
a41f104b
SH
4390 if (!p)
4391 continue;
4392 p++;
4393 if (*p != 0x40)
4394 continue;
4395 p++;
88556fd7
ÇO
4396
4397 is_hashed = false;
4398 if (strncmp(p, lxcpath, lxcpath_len) == 0) {
4399 p += lxcpath_len;
4400 } else if (strncmp(p, "lxc/", 4) == 0) {
4401 p += 4;
4402 is_hashed = true;
4403 } else {
a41f104b 4404 continue;
88556fd7
ÇO
4405 }
4406
a41f104b
SH
4407 while (*p == '/')
4408 p++;
4409
4410 // Now p is the start of lxc_name
46cd2845 4411 p2 = strchr(p, '/');
a41f104b
SH
4412 if (!p2 || strncmp(p2, "/command", 8) != 0)
4413 continue;
4414 *p2 = '\0';
4415
88556fd7 4416 if (is_hashed) {
899a9f55
CB
4417 char *recvpath = lxc_cmd_get_lxcpath(p);
4418 if (!recvpath)
4419 continue;
4420 if (strncmp(lxcpath, recvpath, lxcpath_len) != 0)
88556fd7
ÇO
4421 continue;
4422 p = lxc_cmd_get_name(p);
4423 }
4424
148a9d27 4425 if (array_contains(&ct_name, p, ct_name_cnt))
9c88ff1f
ÇO
4426 continue;
4427
148a9d27
DE
4428 if (!add_to_array(&ct_name, p, ct_name_cnt))
4429 goto free_cret_list;
9c88ff1f 4430
148a9d27 4431 ct_name_cnt++;
a41f104b 4432
148a9d27 4433 if (!cret)
a41f104b 4434 continue;
a41f104b
SH
4435
4436 c = lxc_container_new(p, lxcpath);
4437 if (!c) {
4438 INFO("Container %s:%s is running but could not be loaded",
4439 lxcpath, p);
148a9d27 4440 remove_from_array(&ct_name, p, ct_name_cnt--);
a41f104b
SH
4441 continue;
4442 }
4443
4444 /*
4445 * If this is an anonymous container, then is_defined *can*
4446 * return false. So we don't do that check. Count on the
4447 * fact that the command socket exists.
4448 */
4449
148a9d27 4450 if (!add_to_clist(cret, c, cret_cnt, true)) {
a41f104b 4451 lxc_container_put(c);
148a9d27 4452 goto free_cret_list;
a41f104b 4453 }
148a9d27 4454 cret_cnt++;
a41f104b
SH
4455 }
4456
97bc2422
CB
4457 if (nret && cret && cret_cnt != ct_name_cnt) {
4458 if (c)
4459 lxc_container_put(c);
4460 goto free_cret_list;
4461 }
4462
148a9d27
DE
4463 ret = ct_name_cnt;
4464 if (nret)
4465 *nret = ct_name;
4466 else
4467 goto free_ct_name;
4468 goto out;
a41f104b 4469
148a9d27 4470free_cret_list:
a41f104b 4471 if (cret && *cret) {
148a9d27 4472 for (i = 0; i < cret_cnt; i++)
a41f104b
SH
4473 lxc_container_put((*cret)[i]);
4474 free(*cret);
4475 }
148a9d27
DE
4476
4477free_ct_name:
4478 if (ct_name) {
4479 for (i = 0; i < ct_name_cnt; i++)
4480 free(ct_name[i]);
4481 free(ct_name);
4482 }
4483
4484out:
f10fad2f 4485 free(line);
e853a32d 4486
a41f104b 4487 fclose(f);
148a9d27 4488 return ret;
a41f104b 4489}
2871830a
DE
4490
4491int list_all_containers(const char *lxcpath, char ***nret,
4492 struct lxc_container ***cret)
4493{
4494 int i, ret, active_cnt, ct_cnt, ct_list_cnt;
4495 char **active_name;
4496 char **ct_name;
4497 struct lxc_container **ct_list = NULL;
4498
4499 ct_cnt = list_defined_containers(lxcpath, &ct_name, NULL);
4500 if (ct_cnt < 0)
4501 return ct_cnt;
4502
4503 active_cnt = list_active_containers(lxcpath, &active_name, NULL);
4504 if (active_cnt < 0) {
4505 ret = active_cnt;
4506 goto free_ct_name;
4507 }
4508
4509 for (i = 0; i < active_cnt; i++) {
4510 if (!array_contains(&ct_name, active_name[i], ct_cnt)) {
4511 if (!add_to_array(&ct_name, active_name[i], ct_cnt)) {
4512 ret = -1;
4513 goto free_active_name;
4514 }
4515 ct_cnt++;
4516 }
4517 free(active_name[i]);
4518 active_name[i] = NULL;
4519 }
4520 free(active_name);
4521 active_name = NULL;
4522 active_cnt = 0;
4523
4524 for (i = 0, ct_list_cnt = 0; i < ct_cnt && cret; i++) {
4525 struct lxc_container *c;
4526
4527 c = lxc_container_new(ct_name[i], lxcpath);
4528 if (!c) {
4529 WARN("Container %s:%s could not be loaded", lxcpath, ct_name[i]);
4530 remove_from_array(&ct_name, ct_name[i], ct_cnt--);
4531 continue;
4532 }
4533
4534 if (!add_to_clist(&ct_list, c, ct_list_cnt, false)) {
4535 lxc_container_put(c);
4536 ret = -1;
4537 goto free_ct_list;
4538 }
4539 ct_list_cnt++;
4540 }
4541
4542 if (cret)
4543 *cret = ct_list;
4544
4545 if (nret)
4546 *nret = ct_name;
4547 else {
4548 ret = ct_cnt;
4549 goto free_ct_name;
4550 }
4551 return ct_cnt;
4552
4553free_ct_list:
4554 for (i = 0; i < ct_list_cnt; i++) {
4555 lxc_container_put(ct_list[i]);
4556 }
f10fad2f 4557 free(ct_list);
2871830a
DE
4558
4559free_active_name:
4560 for (i = 0; i < active_cnt; i++) {
f10fad2f 4561 free(active_name[i]);
2871830a 4562 }
f10fad2f 4563 free(active_name);
2871830a
DE
4564
4565free_ct_name:
4566 for (i = 0; i < ct_cnt; i++) {
4567 free(ct_name[i]);
4568 }
4569 free(ct_name);
4570 return ret;
4571}
12461428
CB
4572
4573bool lxc_config_item_is_supported(const char *key)
4574{
4575 return !!lxc_getconfig(key);
4576}