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