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