105
static int instanciate_veth(struct lxc_netdev *);
106
static int instanciate_macvlan(struct lxc_netdev *);
107
static int instanciate_vlan(struct lxc_netdev *);
108
static int instanciate_phys(struct lxc_netdev *);
109
static int instanciate_empty(struct lxc_netdev *);
110
static int instanciate_veth(struct lxc_handler *, struct lxc_netdev *);
111
static int instanciate_macvlan(struct lxc_handler *, struct lxc_netdev *);
112
static int instanciate_vlan(struct lxc_handler *, struct lxc_netdev *);
113
static int instanciate_phys(struct lxc_handler *, struct lxc_netdev *);
114
static int instanciate_empty(struct lxc_handler *, struct lxc_netdev *);
111
116
static instanciate_cb netdev_conf[LXC_NET_MAXCONFTYPE + 1] = {
112
117
[LXC_NET_VETH] = instanciate_veth,
181
186
{ "mac_admin", CAP_MAC_ADMIN },
184
#if 0 /* will be reactivated with image mounting support */
185
static int configure_find_fstype_cb(char* buffer, void *data)
189
static int run_script(const char *name, const char *section,
190
const char *script, ...)
194
char *buffer, *p, *output;
198
INFO("Executing script '%s' for container '%s', config section '%s'",
199
script, name, section);
201
va_start(ap, script);
202
while ((p = va_arg(ap, char *)))
206
size += strlen(script);
207
size += strlen(name);
208
size += strlen(section);
210
buffer = alloca(size + 1);
212
ERROR("failed to allocate memory");
216
ret = sprintf(buffer, "%s %s %s", script, name, section);
218
va_start(ap, script);
219
while ((p = va_arg(ap, char *)))
220
ret += sprintf(buffer + ret, " %s", p);
223
f = popen(buffer, "r");
225
SYSERROR("popen failed");
229
output = malloc(LXC_LOG_BUFFER_SIZE);
231
ERROR("failed to allocate memory for script output");
235
while(fgets(output, LXC_LOG_BUFFER_SIZE, f))
236
DEBUG("script output: %s", output);
241
ERROR("Script exited on error");
248
static int find_fstype_cb(char* buffer, void *data)
188
251
const char *rootfs;
201
263
fstype += lxc_char_left_gc(fstype, strlen(fstype));
202
264
fstype[lxc_char_right_gc(fstype, strlen(fstype))] = '\0';
204
if (mount(cbarg->rootfs, cbarg->testdir, fstype, cbarg->mntopt, NULL))
266
DEBUG("trying to mount '%s'->'%s' with fstype '%s'",
267
cbarg->rootfs, cbarg->target, fstype);
269
if (mount(cbarg->rootfs, cbarg->target, fstype, cbarg->mntopt, NULL)) {
270
DEBUG("mount failed with error: %s", strerror(errno));
208
umount(cbarg->testdir);
209
strcpy(cbarg->fstype, fstype);
274
INFO("mounted '%s' on '%s', with fstype '%s'",
275
cbarg->rootfs, cbarg->target, fstype);
214
/* find the filesystem type with brute force */
215
static int configure_find_fstype(const char *rootfs, char *fstype, int mntopt)
280
static int mount_unknow_fs(const char *rootfs, const char *target, int mntopt)
220
285
const char *rootfs;
225
289
.rootfs = rootfs,
227
291
.mntopt = mntopt,
230
/* first we check with /etc/filesystems, in case the modules
295
* find the filesystem type with brute force:
296
* first we check with /etc/filesystems, in case the modules
231
297
* are auto-loaded and fall back to the supported kernel fs
233
299
char *fsfile[] = {
235
301
"/proc/filesystems",
238
cbarg.testdir = tempnam("/tmp", "lxc-");
239
if (!cbarg.testdir) {
240
SYSERROR("failed to build a temp name");
244
if (mkdir(cbarg.testdir, 0755)) {
245
SYSERROR("failed to create temporary directory");
249
304
for (i = 0; i < sizeof(fsfile)/sizeof(fsfile[0]); i++) {
251
found = lxc_file_for_each_line(fsfile[i],
252
configure_find_fstype_cb,
256
SYSERROR("failed to read '%s'", fsfile[i]);
308
if (access(fsfile[i], F_OK))
311
ret = lxc_file_for_each_line(fsfile[i], find_fstype_cb, &cbarg);
313
ERROR("failed to parse '%s'", fsfile[i]);
265
ERROR("failed to determine fs type for '%s'", rootfs);
321
ERROR("failed to determine fs type for '%s'", rootfs);
325
static int mount_rootfs_dir(const char *rootfs, const char *target)
327
return mount(rootfs, target, "none", MS_BIND | MS_REC, NULL);
330
static int setup_lodev(const char *rootfs, int fd, struct loop_info64 *loinfo)
335
rfd = open(rootfs, O_RDWR);
337
SYSERROR("failed to open '%s'", rootfs);
341
memset(loinfo, 0, sizeof(*loinfo));
343
loinfo->lo_flags = LO_FLAGS_AUTOCLEAR;
345
if (ioctl(fd, LOOP_SET_FD, rfd)) {
346
SYSERROR("failed to LOOP_SET_FD");
350
if (ioctl(fd, LOOP_SET_STATUS64, loinfo)) {
351
SYSERROR("failed to LOOP_SET_STATUS64");
270
rmdir(cbarg.testdir);
274
static int configure_rootfs_dir_cb(const char *rootfs, const char *absrootfs,
277
return fprintf(f, "%s %s none rbind 0 0\n", absrootfs, rootfs);
280
static int configure_rootfs_blk_cb(const char *rootfs, const char *absrootfs,
283
char fstype[MAXPATHLEN];
285
if (configure_find_fstype(absrootfs, fstype, 0)) {
286
ERROR("failed to configure mount for block device '%s'",
291
return fprintf(f, "%s %s %s defaults 0 0\n", absrootfs, rootfs, fstype);
294
static int configure_rootfs(const char *name, const char *rootfs)
362
static int mount_rootfs_file(const char *rootfs, const char *target)
364
struct dirent dirent, *direntp;
365
struct loop_info64 loinfo;
366
int ret = -1, fd = -1;
296
368
char path[MAXPATHLEN];
370
dir = opendir("/dev");
372
SYSERROR("failed to open '/dev'");
376
while (!readdir_r(dir, &dirent, &direntp)) {
381
if (!strcmp(direntp->d_name, "."))
384
if (!strcmp(direntp->d_name, ".."))
387
if (strncmp(direntp->d_name, "loop", 4))
390
sprintf(path, "/dev/%s", direntp->d_name);
391
fd = open(path, O_RDWR);
395
if (ioctl(fd, LOOP_GET_STATUS64, &loinfo) == 0) {
400
if (errno != ENXIO) {
401
WARN("unexpected error for ioctl on '%s': %m",
406
DEBUG("found '%s' free lodev", path);
408
ret = setup_lodev(rootfs, fd, &loinfo);
410
ret = mount_unknow_fs(path, target, 0);
417
WARN("failed to close directory");
422
static int mount_rootfs_block(const char *rootfs, const char *target)
424
return mount_unknow_fs(rootfs, target, 0);
427
static int mount_rootfs(const char *rootfs, const char *target)
297
429
char absrootfs[MAXPATHLEN];
298
char fstab[MAXPATHLEN];
303
typedef int (*rootfs_cb)(const char *, const char *, FILE *);
433
typedef int (*rootfs_cb)(const char *, const char *);
305
435
struct rootfs_type {
308
438
} rtfs_type[] = {
309
{ __S_IFDIR, configure_rootfs_dir_cb },
310
{ __S_IFBLK, configure_rootfs_blk_cb },
439
{ S_IFDIR, mount_rootfs_dir },
440
{ S_IFBLK, mount_rootfs_block },
441
{ S_IFREG, mount_rootfs_file },
313
444
if (!realpath(rootfs, absrootfs)) {
337
461
if (!__S_ISTYPE(s.st_mode, rtfs_type[i].type))
340
snprintf(fstab, MAXPATHLEN, LXCPATH "/%s/fstab", name);
342
f = fopen(fstab, "a+");
344
SYSERROR("failed to open fstab file");
348
ret = rtfs_type[i].cb(path, absrootfs, f);
353
ERROR("failed to add rootfs mount in fstab");
357
snprintf(path, MAXPATHLEN, LXCPATH "/%s/rootfs/rootfs", name);
359
return symlink(absrootfs, path);
464
return rtfs_type[i].cb(absrootfs, target);
362
467
ERROR("unsupported rootfs type for '%s'", absrootfs);
367
471
static int setup_utsname(struct utsname *utsname)
585
692
if (remove_pivotdir && rmdir(pivotdir))
586
693
WARN("can't remove mountpoint '%s': %m", pivotdir);
588
INFO("pivoted to '%s'", rootfs);
593
698
static int setup_rootfs(const struct lxc_rootfs *rootfs)
595
char *mpath = LXCROOTFSMOUNT;
597
700
if (!rootfs->path)
601
mpath = rootfs->mount;
603
if (access(mpath, F_OK)) {
703
if (access(rootfs->mount, F_OK)) {
604
704
SYSERROR("failed to access to '%s', check it is present",
609
if (mount(rootfs->path, mpath, "none", MS_BIND|MS_REC, NULL)) {
610
SYSERROR("failed to mount '%s'->'%s'", rootfs->path, mpath);
614
DEBUG("mounted '%s' on '%s'", rootfs->path, mpath);
616
if (setup_rootfs_pivot_root(mpath, rootfs->pivot)) {
709
if (mount_rootfs(rootfs->path, rootfs->mount)) {
710
ERROR("failed to mount rootfs");
714
DEBUG("mounted '%s' on '%s'", rootfs->path, rootfs->mount);
719
int setup_pivot_root(const struct lxc_rootfs *rootfs)
724
if (setup_rootfs_pivot_root(rootfs->mount, rootfs->pivot)) {
617
725
ERROR("failed to setup pivot root");
1439
if (netdev->upscript) {
1441
err = run_script(handler->name, "net", netdev->upscript,
1442
"up", "phys", netdev->link, (char*) NULL);
1302
static int instanciate_empty(struct lxc_netdev *netdev)
1450
static int instanciate_empty(struct lxc_handler *handler, struct lxc_netdev *netdev)
1304
1452
netdev->ifindex = 0;
1453
if (netdev->upscript) {
1455
err = run_script(handler->name, "net", netdev->upscript,
1456
"up", "empty", (char*) NULL);
1308
int lxc_create_network(struct lxc_list *network)
1463
int lxc_create_network(struct lxc_handler *handler)
1465
struct lxc_list *network = &handler->conf->network;
1310
1466
struct lxc_list *iterator;
1311
1467
struct lxc_netdev *netdev;