~serge-hallyn/ubuntu/natty/lxc/lxc-fix-3bugs

« back to all changes in this revision

Viewing changes to src/lxc/conf.c

  • Committer: Bazaar Package Importer
  • Author(s): Guido Trotter
  • Date: 2010-12-06 16:24:31 UTC
  • mfrom: (1.1.6 upstream) (3.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20101206162431-lvg92fyuiupfoqek
Tags: 0.7.3-1
* New upstream version (closes: #602631)
  - Support for specifying debian suite (closes: #600459)
  - Support for declaring a different architecture (closes: #597875)
* Fix restart init.d action sequence (closes: #597998)
* Move too-deep /usr/lib/lxc/lxc path to a proper patch
* Disable checkroot script in debian template (closes: #601001)
* Create missing tty devices under squeeze (closes: #600466)
* Restore bindmount functionality in newer kernels (closes: #604475)
* Make debian mirror configurable (closes: #601422)
* Default to cdn.debian.net as a debian mirror (closes: #600464)

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include <stdio.h>
25
25
#undef _GNU_SOURCE
26
26
#include <stdlib.h>
 
27
#include <stdarg.h>
27
28
#include <errno.h>
28
29
#include <string.h>
29
30
#include <dirent.h>
30
31
#include <mntent.h>
31
32
#include <unistd.h>
 
33
#include <sys/wait.h>
32
34
#include <pty.h>
33
35
 
 
36
#include <linux/loop.h>
 
37
 
34
38
#include <sys/types.h>
35
39
#include <sys/utsname.h>
36
40
#include <sys/param.h>
40
44
#include <sys/mman.h>
41
45
#include <sys/prctl.h>
42
46
#include <sys/capability.h>
 
47
#include <sys/personality.h>
43
48
 
44
49
#include <arpa/inet.h>
45
50
#include <fcntl.h>
89
94
 
90
95
extern int pivot_root(const char * new_root, const char * put_old);
91
96
 
92
 
typedef int (*instanciate_cb)(struct lxc_netdev *);
 
97
typedef int (*instanciate_cb)(struct lxc_handler *, struct lxc_netdev *);
93
98
 
94
99
struct mount_opt {
95
100
        char *name;
102
107
        int value;
103
108
};
104
109
 
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 *);
110
115
 
111
116
static  instanciate_cb netdev_conf[LXC_NET_MAXCONFTYPE + 1] = {
112
117
        [LXC_NET_VETH]    = instanciate_veth,
141
146
};
142
147
 
143
148
static struct caps_opt caps_opt[] = {
144
 
        { "chown",             CAP_CHOWN             },
 
149
        { "chown",             CAP_CHOWN             },
145
150
        { "dac_override",      CAP_DAC_OVERRIDE      },
146
151
        { "dac_read_search",   CAP_DAC_READ_SEARCH   },
147
152
        { "fowner",            CAP_FOWNER            },
181
186
        { "mac_admin",         CAP_MAC_ADMIN         },
182
187
};
183
188
 
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, ...)
 
191
{
 
192
        int ret;
 
193
        FILE *f;
 
194
        char *buffer, *p, *output;
 
195
        size_t size = 0;
 
196
        va_list ap;
 
197
 
 
198
        INFO("Executing script '%s' for container '%s', config section '%s'",
 
199
             script, name, section);
 
200
 
 
201
        va_start(ap, script);
 
202
        while ((p = va_arg(ap, char *)))
 
203
                size += strlen(p);
 
204
        va_end(ap);
 
205
 
 
206
        size += strlen(script);
 
207
        size += strlen(name);
 
208
        size += strlen(section);
 
209
 
 
210
        buffer = alloca(size + 1);
 
211
        if (!buffer) {
 
212
                ERROR("failed to allocate memory");
 
213
                return -1;
 
214
        }
 
215
 
 
216
        ret = sprintf(buffer, "%s %s %s", script, name, section);
 
217
 
 
218
        va_start(ap, script);
 
219
        while ((p = va_arg(ap, char *)))
 
220
                ret += sprintf(buffer + ret, " %s", p);
 
221
        va_end(ap);
 
222
 
 
223
        f = popen(buffer, "r");
 
224
        if (!f) {
 
225
                SYSERROR("popen failed");
 
226
                return -1;
 
227
        }
 
228
 
 
229
        output = malloc(LXC_LOG_BUFFER_SIZE);
 
230
        if (!output) {
 
231
                ERROR("failed to allocate memory for script output");
 
232
                return -1;
 
233
        }
 
234
 
 
235
        while(fgets(output, LXC_LOG_BUFFER_SIZE, f))
 
236
                DEBUG("script output: %s", output);
 
237
 
 
238
        free(output);
 
239
 
 
240
        if (pclose(f)) {
 
241
                ERROR("Script exited on error");
 
242
                return -1;
 
243
        }
 
244
 
 
245
        return 0;
 
246
}
 
247
 
 
248
static int find_fstype_cb(char* buffer, void *data)
186
249
{
187
250
        struct cbarg {
188
251
                const char *rootfs;
189
 
                const char *testdir;
190
 
                char *fstype;
 
252
                const char *target;
191
253
                int mntopt;
192
254
        } *cbarg = data;
193
255
 
201
263
        fstype += lxc_char_left_gc(fstype, strlen(fstype));
202
264
        fstype[lxc_char_right_gc(fstype, strlen(fstype))] = '\0';
203
265
 
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);
 
268
 
 
269
        if (mount(cbarg->rootfs, cbarg->target, fstype, cbarg->mntopt, NULL)) {
 
270
                DEBUG("mount failed with error: %s", strerror(errno));
205
271
                return 0;
 
272
        }
206
273
 
207
 
        /* found ! */
208
 
        umount(cbarg->testdir);
209
 
        strcpy(cbarg->fstype, fstype);
 
274
        INFO("mounted '%s' on '%s', with fstype '%s'",
 
275
             cbarg->rootfs, cbarg->target, fstype);
210
276
 
211
277
        return 1;
212
278
}
213
279
 
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)
216
281
{
217
 
        int i, found;
 
282
        int i;
218
283
 
219
284
        struct cbarg {
220
285
                const char *rootfs;
221
 
                const char *testdir;
222
 
                char *fstype;
 
286
                const char *target;
223
287
                int mntopt;
224
288
        } cbarg = {
225
289
                .rootfs = rootfs,
226
 
                .fstype = fstype,
 
290
                .target = target,
227
291
                .mntopt = mntopt,
228
292
        };
229
293
 
230
 
        /* first we check with /etc/filesystems, in case the modules
 
294
        /*
 
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
232
298
         */
233
299
        char *fsfile[] = {
235
301
                "/proc/filesystems",
236
302
        };
237
303
 
238
 
        cbarg.testdir = tempnam("/tmp", "lxc-");
239
 
        if (!cbarg.testdir) {
240
 
                SYSERROR("failed to build a temp name");
241
 
                return -1;
242
 
        }
243
 
 
244
 
        if (mkdir(cbarg.testdir, 0755)) {
245
 
                SYSERROR("failed to create temporary directory");
246
 
                return -1;
247
 
        }
248
 
 
249
304
        for (i = 0; i < sizeof(fsfile)/sizeof(fsfile[0]); i++) {
250
305
 
251
 
                found = lxc_file_for_each_line(fsfile[i],
252
 
                                               configure_find_fstype_cb,
253
 
                                               &cbarg);
254
 
 
255
 
                if (found < 0) {
256
 
                        SYSERROR("failed to read '%s'", fsfile[i]);
257
 
                        goto out;
 
306
                int ret;
 
307
 
 
308
                if (access(fsfile[i], F_OK))
 
309
                        continue;
 
310
 
 
311
                ret = lxc_file_for_each_line(fsfile[i], find_fstype_cb, &cbarg);
 
312
                if (ret < 0) {
 
313
                        ERROR("failed to parse '%s'", fsfile[i]);
 
314
                        return -1;
258
315
                }
259
316
 
260
 
                if (found)
261
 
                        break;
262
 
        }
263
 
 
264
 
        if (!found) {
265
 
                ERROR("failed to determine fs type for '%s'", rootfs);
266
 
                goto out;
267
 
        }
268
 
 
 
317
                if (ret)
 
318
                        return 0;
 
319
        }
 
320
 
 
321
        ERROR("failed to determine fs type for '%s'", rootfs);
 
322
        return -1;
 
323
}
 
324
 
 
325
static int mount_rootfs_dir(const char *rootfs, const char *target)
 
326
{
 
327
        return mount(rootfs, target, "none", MS_BIND | MS_REC, NULL);
 
328
}
 
329
 
 
330
static int setup_lodev(const char *rootfs, int fd, struct loop_info64 *loinfo)
 
331
{
 
332
        int rfd;
 
333
        int ret = -1;
 
334
 
 
335
        rfd = open(rootfs, O_RDWR);
 
336
        if (rfd < 0) {
 
337
                SYSERROR("failed to open '%s'", rootfs);
 
338
                return -1;
 
339
        }
 
340
 
 
341
        memset(loinfo, 0, sizeof(*loinfo));
 
342
 
 
343
        loinfo->lo_flags = LO_FLAGS_AUTOCLEAR;
 
344
 
 
345
        if (ioctl(fd, LOOP_SET_FD, rfd)) {
 
346
                SYSERROR("failed to LOOP_SET_FD");
 
347
                goto out;
 
348
        }
 
349
 
 
350
        if (ioctl(fd, LOOP_SET_STATUS64, loinfo)) {
 
351
                SYSERROR("failed to LOOP_SET_STATUS64");
 
352
                goto out;
 
353
        }
 
354
 
 
355
        ret = 0;
269
356
out:
270
 
        rmdir(cbarg.testdir);
271
 
        return found - 1;
272
 
}
273
 
 
274
 
static int configure_rootfs_dir_cb(const char *rootfs, const char *absrootfs,
275
 
                                   FILE *f)
276
 
{
277
 
        return fprintf(f, "%s %s none rbind 0 0\n", absrootfs, rootfs);
278
 
}
279
 
 
280
 
static int configure_rootfs_blk_cb(const char *rootfs, const char *absrootfs,
281
 
                                   FILE *f)
282
 
{
283
 
        char fstype[MAXPATHLEN];
284
 
 
285
 
        if (configure_find_fstype(absrootfs, fstype, 0)) {
286
 
                ERROR("failed to configure mount for block device '%s'",
287
 
                              absrootfs);
288
 
                return -1;
289
 
        }
290
 
 
291
 
        return fprintf(f, "%s %s %s defaults 0 0\n", absrootfs, rootfs, fstype);
292
 
}
293
 
 
294
 
static int configure_rootfs(const char *name, const char *rootfs)
295
 
{
 
357
        close(rfd);
 
358
 
 
359
        return ret;
 
360
}
 
361
 
 
362
static int mount_rootfs_file(const char *rootfs, const char *target)
 
363
{
 
364
        struct dirent dirent, *direntp;
 
365
        struct loop_info64 loinfo;
 
366
        int ret = -1, fd = -1;
 
367
        DIR *dir;
296
368
        char path[MAXPATHLEN];
 
369
 
 
370
        dir = opendir("/dev");
 
371
        if (!dir) {
 
372
                SYSERROR("failed to open '/dev'");
 
373
                return -1;
 
374
        }
 
375
 
 
376
        while (!readdir_r(dir, &dirent, &direntp)) {
 
377
 
 
378
                if (!direntp)
 
379
                        break;
 
380
 
 
381
                if (!strcmp(direntp->d_name, "."))
 
382
                        continue;
 
383
 
 
384
                if (!strcmp(direntp->d_name, ".."))
 
385
                        continue;
 
386
 
 
387
                if (strncmp(direntp->d_name, "loop", 4))
 
388
                        continue;
 
389
 
 
390
                sprintf(path, "/dev/%s", direntp->d_name);
 
391
                fd = open(path, O_RDWR);
 
392
                if (fd < 0)
 
393
                        continue;
 
394
 
 
395
                if (ioctl(fd, LOOP_GET_STATUS64, &loinfo) == 0) {
 
396
                        close(fd);
 
397
                        continue;
 
398
                }
 
399
 
 
400
                if (errno != ENXIO) {
 
401
                        WARN("unexpected error for ioctl on '%s': %m",
 
402
                             direntp->d_name);
 
403
                        continue;
 
404
                }
 
405
 
 
406
                DEBUG("found '%s' free lodev", path);
 
407
 
 
408
                ret = setup_lodev(rootfs, fd, &loinfo);
 
409
                if (!ret)
 
410
                        ret = mount_unknow_fs(path, target, 0);
 
411
                close(fd);
 
412
 
 
413
                break;
 
414
        }
 
415
 
 
416
        if (closedir(dir))
 
417
                WARN("failed to close directory");
 
418
 
 
419
        return ret;
 
420
}
 
421
 
 
422
static int mount_rootfs_block(const char *rootfs, const char *target)
 
423
{
 
424
        return mount_unknow_fs(rootfs, target, 0);
 
425
}
 
426
 
 
427
static int mount_rootfs(const char *rootfs, const char *target)
 
428
{
297
429
        char absrootfs[MAXPATHLEN];
298
 
        char fstab[MAXPATHLEN];
299
430
        struct stat s;
300
 
        FILE *f;
301
 
        int i, ret;
 
431
        int i;
302
432
 
303
 
        typedef int (*rootfs_cb)(const char *, const char *, FILE *);
 
433
        typedef int (*rootfs_cb)(const char *, const char *);
304
434
 
305
435
        struct rootfs_type {
306
436
                int type;
307
437
                rootfs_cb cb;
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 },
311
442
        };
312
443
 
313
444
        if (!realpath(rootfs, absrootfs)) {
315
446
                return -1;
316
447
        }
317
448
 
318
 
        snprintf(path, MAXPATHLEN, LXCPATH "/%s/rootfs", name);
319
 
 
320
 
        if (mkdir(path, 0755)) {
321
 
                SYSERROR("failed to create the '%s' directory", path);
322
 
                return -1;
323
 
        }
324
 
 
325
449
        if (access(absrootfs, F_OK)) {
326
450
                SYSERROR("'%s' is not accessible", absrootfs);
327
451
                return -1;
337
461
                if (!__S_ISTYPE(s.st_mode, rtfs_type[i].type))
338
462
                        continue;
339
463
 
340
 
                snprintf(fstab, MAXPATHLEN, LXCPATH "/%s/fstab", name);
341
 
 
342
 
                f = fopen(fstab, "a+");
343
 
                if (!f) {
344
 
                        SYSERROR("failed to open fstab file");
345
 
                        return -1;
346
 
                }
347
 
 
348
 
                ret = rtfs_type[i].cb(path, absrootfs, f);
349
 
 
350
 
                fclose(f);
351
 
 
352
 
                if (ret < 0) {
353
 
                        ERROR("failed to add rootfs mount in fstab");
354
 
                        return -1;
355
 
                }
356
 
 
357
 
                snprintf(path, MAXPATHLEN, LXCPATH "/%s/rootfs/rootfs", name);
358
 
 
359
 
                return symlink(absrootfs, path);
 
464
                return rtfs_type[i].cb(absrootfs, target);
360
465
        }
361
466
 
362
467
        ERROR("unsupported rootfs type for '%s'", absrootfs);
363
468
        return -1;
364
469
}
365
 
#endif
366
470
 
367
471
static int setup_utsname(struct utsname *utsname)
368
472
{
385
489
        char path[MAXPATHLEN];
386
490
        int i;
387
491
 
 
492
        if (!rootfs->path)
 
493
                return 0;
 
494
 
388
495
        for (i = 0; i < tty_info->nbtty; i++) {
389
496
 
390
497
                struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
391
498
 
392
499
                snprintf(path, sizeof(path), "%s/dev/tty%d",
393
 
                         rootfs->path ? rootfs->path : "", i + 1);
 
500
                         rootfs->mount, i + 1);
394
501
 
395
502
                /* At this point I can not use the "access" function
396
503
                 * to check the file is present or not because it fails
585
692
        if (remove_pivotdir && rmdir(pivotdir))
586
693
                WARN("can't remove mountpoint '%s': %m", pivotdir);
587
694
 
588
 
        INFO("pivoted to '%s'", rootfs);
589
 
 
590
695
        return 0;
591
696
}
592
697
 
593
698
static int setup_rootfs(const struct lxc_rootfs *rootfs)
594
699
{
595
 
        char *mpath = LXCROOTFSMOUNT;
596
 
 
597
700
        if (!rootfs->path)
598
701
                return 0;
599
702
 
600
 
        if (rootfs->mount)
601
 
                mpath = rootfs->mount;
602
 
 
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",
605
 
                         mpath);
606
 
                return -1;
607
 
        }
608
 
 
609
 
        if (mount(rootfs->path, mpath, "none", MS_BIND|MS_REC, NULL)) {
610
 
                SYSERROR("failed to mount '%s'->'%s'", rootfs->path, mpath);
611
 
                return -1;
612
 
        }
613
 
 
614
 
        DEBUG("mounted '%s' on '%s'", rootfs->path, mpath);
615
 
 
616
 
        if (setup_rootfs_pivot_root(mpath, rootfs->pivot)) {
 
705
                         rootfs->mount);
 
706
                return -1;
 
707
        }
 
708
 
 
709
        if (mount_rootfs(rootfs->path, rootfs->mount)) {
 
710
                ERROR("failed to mount rootfs");
 
711
                return -1;
 
712
        }
 
713
 
 
714
        DEBUG("mounted '%s' on '%s'", rootfs->path, rootfs->mount);
 
715
 
 
716
        return 0;
 
717
}
 
718
 
 
719
int setup_pivot_root(const struct lxc_rootfs *rootfs)
 
720
{
 
721
        if (!rootfs->path)
 
722
                return 0;
 
723
 
 
724
        if (setup_rootfs_pivot_root(rootfs->mount, rootfs->pivot)) {
617
725
                ERROR("failed to setup pivot root");
618
726
                return -1;
619
727
        }
631
739
                return -1;
632
740
        }
633
741
 
634
 
        if (mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL, "newinstance,ptmxmode=0666")) {
 
742
        if (mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL,
 
743
                  "newinstance,ptmxmode=0666")) {
635
744
                SYSERROR("failed to mount a new instance of '/dev/pts'");
636
745
                return -1;
637
746
        }
655
764
        return 0;
656
765
}
657
766
 
 
767
static int setup_personality(int persona)
 
768
{
 
769
        if (persona == -1)
 
770
                return 0;
 
771
 
 
772
        if (personality(persona) < 0) {
 
773
                SYSERROR("failed to set personality to '0x%x'", persona);
 
774
                return -1;
 
775
        }
 
776
 
 
777
        INFO("set personality to '0x%x'", persona);
 
778
 
 
779
        return 0;
 
780
}
 
781
 
658
782
static int setup_console(const struct lxc_rootfs *rootfs,
659
783
                         const struct lxc_console *console)
660
784
{
665
789
        if (!rootfs->path)
666
790
                return 0;
667
791
 
668
 
        snprintf(path, sizeof(path), "%s/dev/console", rootfs->path);
 
792
        snprintf(path, sizeof(path), "%s/dev/console", rootfs->mount);
669
793
 
670
794
        if (access(path, F_OK)) {
671
 
                WARN("rootfs specified but no console found");
 
795
                WARN("rootfs specified but no console found at '%s'", path);
672
796
                return 0;
673
797
        }
674
798
 
1125
1249
        }
1126
1250
        memset(new, 0, sizeof(*new));
1127
1251
 
 
1252
        new->personality = -1;
1128
1253
        new->console.path = NULL;
1129
1254
        new->console.peer = -1;
1130
1255
        new->console.master = -1;
1131
1256
        new->console.slave = -1;
1132
1257
        new->console.name[0] = '\0';
 
1258
        new->rootfs.mount = LXCROOTFSMOUNT;
1133
1259
        lxc_list_init(&new->cgroup);
1134
1260
        lxc_list_init(&new->network);
1135
1261
        lxc_list_init(&new->mount_list);
1138
1264
        return new;
1139
1265
}
1140
1266
 
1141
 
static int instanciate_veth(struct lxc_netdev *netdev)
 
1267
static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netdev)
1142
1268
{
1143
1269
        char veth1buf[IFNAMSIZ], *veth1;
1144
1270
        char veth2buf[IFNAMSIZ], *veth2;
1201
1327
                }
1202
1328
        }
1203
1329
 
 
1330
        if (netdev->upscript) {
 
1331
                err = run_script(handler->name, "net", netdev->upscript, "up",
 
1332
                                 "veth", veth1, (char*) NULL);
 
1333
                if (err)
 
1334
                        goto out_delete;
 
1335
        }
 
1336
 
1204
1337
        DEBUG("instanciated veth '%s/%s', index is '%d'",
1205
1338
              veth1, veth2, netdev->ifindex);
1206
1339
 
1211
1344
        return -1;
1212
1345
}
1213
1346
 
1214
 
static int instanciate_macvlan(struct lxc_netdev *netdev)
 
1347
static int instanciate_macvlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
1215
1348
{
1216
1349
        char peerbuf[IFNAMSIZ], *peer;
1217
1350
        int err;
1244
1377
                return -1;
1245
1378
        }
1246
1379
 
 
1380
        if (netdev->upscript) {
 
1381
                err = run_script(handler->name, "net", netdev->upscript, "up",
 
1382
                                 "macvlan", netdev->link, (char*) NULL);
 
1383
                if (err)
 
1384
                        return -1;
 
1385
        }
 
1386
 
1247
1387
        DEBUG("instanciated macvlan '%s', index is '%d' and mode '%d'",
1248
1388
              peer, netdev->ifindex, netdev->priv.macvlan_attr.mode);
1249
1389
 
1251
1391
}
1252
1392
 
1253
1393
/* XXX: merge with instanciate_macvlan */
1254
 
static int instanciate_vlan(struct lxc_netdev *netdev)
 
1394
static int instanciate_vlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
1255
1395
{
1256
1396
        char peer[IFNAMSIZ];
1257
1397
        int err;
1283
1423
        return 0;
1284
1424
}
1285
1425
 
1286
 
static int instanciate_phys(struct lxc_netdev *netdev)
 
1426
static int instanciate_phys(struct lxc_handler *handler, struct lxc_netdev *netdev)
1287
1427
{
1288
1428
        if (!netdev->link) {
1289
1429
                ERROR("no link specified for the physical interface");
1296
1436
                return -1;
1297
1437
        }
1298
1438
 
 
1439
        if (netdev->upscript) {
 
1440
                int err;
 
1441
                err = run_script(handler->name, "net", netdev->upscript,
 
1442
                                 "up", "phys", netdev->link, (char*) NULL);
 
1443
                if (err)
 
1444
                        return -1;
 
1445
        }
 
1446
 
1299
1447
        return 0;
1300
1448
}
1301
1449
 
1302
 
static int instanciate_empty(struct lxc_netdev *netdev)
 
1450
static int instanciate_empty(struct lxc_handler *handler, struct lxc_netdev *netdev)
1303
1451
{
1304
1452
        netdev->ifindex = 0;
 
1453
        if (netdev->upscript) {
 
1454
                int err;
 
1455
                err = run_script(handler->name, "net", netdev->upscript,
 
1456
                                 "up", "empty", (char*) NULL);
 
1457
                if (err)
 
1458
                        return -1;
 
1459
        }
1305
1460
        return 0;
1306
1461
}
1307
1462
 
1308
 
int lxc_create_network(struct lxc_list *network)
 
1463
int lxc_create_network(struct lxc_handler *handler)
1309
1464
{
 
1465
        struct lxc_list *network = &handler->conf->network;
1310
1466
        struct lxc_list *iterator;
1311
1467
        struct lxc_netdev *netdev;
1312
1468
 
1320
1476
                        return -1;
1321
1477
                }
1322
1478
 
1323
 
                if (netdev_conf[netdev->type](netdev)) {
 
1479
                if (netdev_conf[netdev->type](handler, netdev)) {
1324
1480
                        ERROR("failed to create netdev");
1325
1481
                        return -1;
1326
1482
                }
 
1483
 
1327
1484
        }
1328
1485
 
1329
1486
        return 0;
1440
1597
                return -1;
1441
1598
        }
1442
1599
 
1443
 
        if (setup_cgroup(name, &lxc_conf->cgroup)) {
1444
 
                ERROR("failed to setup the cgroups for '%s'", name);
1445
 
                return -1;
1446
 
        }
1447
 
 
1448
1600
        if (setup_mount(lxc_conf->fstab)) {
1449
1601
                ERROR("failed to setup the mounts for '%s'", name);
1450
1602
                return -1;
1455
1607
                return -1;
1456
1608
        }
1457
1609
 
 
1610
        if (setup_rootfs(&lxc_conf->rootfs)) {
 
1611
                ERROR("failed to setup rootfs for '%s'", name);
 
1612
                return -1;
 
1613
        }
 
1614
 
 
1615
        if (setup_cgroup(name, &lxc_conf->cgroup)) {
 
1616
                ERROR("failed to setup the cgroups for '%s'", name);
 
1617
                return -1;
 
1618
        }
 
1619
 
1458
1620
        if (setup_console(&lxc_conf->rootfs, &lxc_conf->console)) {
1459
1621
                ERROR("failed to setup the console for '%s'", name);
1460
1622
                return -1;
1465
1627
                return -1;
1466
1628
        }
1467
1629
 
1468
 
        if (setup_rootfs(&lxc_conf->rootfs)) {
 
1630
        if (setup_pivot_root(&lxc_conf->rootfs)) {
1469
1631
                ERROR("failed to set rootfs for '%s'", name);
1470
1632
                return -1;
1471
1633
        }
1475
1637
                return -1;
1476
1638
        }
1477
1639
 
 
1640
        if (setup_personality(lxc_conf->personality)) {
 
1641
                ERROR("failed to setup personality");
 
1642
                return -1;
 
1643
        }
 
1644
 
1478
1645
        if (setup_caps(&lxc_conf->caps)) {
1479
1646
                ERROR("failed to drop capabilities");
1480
1647
                return -1;