~ubuntu-branches/ubuntu/maverick/libvirt/maverick

« back to all changes in this revision

Viewing changes to src/lxc_container.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2009-02-11 01:01:42 UTC
  • mto: (3.4.1 sid) (1.2.1 upstream) (0.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: james.westby@ubuntu.com-20090211010142-wk9mgtbw8bmp3zcb
Tags: upstream-0.6.0
ImportĀ upstreamĀ versionĀ 0.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
#include "memory.h"
49
49
#include "veth.h"
50
50
 
 
51
#define VIR_FROM_THIS VIR_FROM_LXC
 
52
 
51
53
/*
52
54
 * GLibc headers are behind the kernel, so we define these
53
55
 * constants if they're not present already.
118
120
    int open_max, i;
119
121
 
120
122
    if (setsid() < 0) {
121
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
122
 
                 _("setsid failed: %s"), strerror(errno));
 
123
        virReportSystemError(NULL, errno, "%s",
 
124
                             _("setsid failed"));
123
125
        goto cleanup;
124
126
    }
125
127
 
126
128
    if (ioctl(ttyfd, TIOCSCTTY, NULL) < 0) {
127
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
128
 
                 _("ioctl(TIOCSTTY) failed: %s"), strerror(errno));
 
129
        virReportSystemError(NULL, errno, "%s",
 
130
                             _("ioctl(TIOCSTTY) failed"));
129
131
        goto cleanup;
130
132
    }
131
133
 
137
139
            close(i);
138
140
 
139
141
    if (dup2(ttyfd, 0) < 0) {
140
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
141
 
                 _("dup2(stdin) failed: %s"), strerror(errno));
 
142
        virReportSystemError(NULL, errno, "%s",
 
143
                             _("dup2(stdin) failed"));
142
144
        goto cleanup;
143
145
    }
144
146
 
145
147
    if (dup2(ttyfd, 1) < 0) {
146
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
147
 
                 _("dup2(stdout) failed: %s"), strerror(errno));
 
148
        virReportSystemError(NULL, errno, "%s",
 
149
                             _("dup2(stdout) failed"));
148
150
        goto cleanup;
149
151
    }
150
152
 
151
153
    if (dup2(ttyfd, 2) < 0) {
152
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
153
 
                 _("dup2(stderr) failed: %s"), strerror(errno));
 
154
        virReportSystemError(NULL, errno, "%s",
 
155
                             _("dup2(stderr) failed"));
154
156
        goto cleanup;
155
157
    }
156
158
 
177
179
 
178
180
    writeCount = safewrite(control, &msg, sizeof(msg));
179
181
    if (writeCount != sizeof(msg)) {
180
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
181
 
                 _("unable to send container continue message: %s"),
182
 
                 strerror(errno));
 
182
        virReportSystemError(NULL, errno, "%s",
 
183
                             _("unable to send container continue message"));
183
184
        goto error_out;
184
185
    }
185
186
 
207
208
    readLen = saferead(control, &msg, sizeof(msg));
208
209
    if (readLen != sizeof(msg) ||
209
210
        msg != LXC_CONTINUE_MSG) {
210
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
211
 
                 _("Failed to read the container continue message: %s"),
212
 
                 strerror(errno));
 
211
        virReportSystemError(NULL, errno, "%s",
 
212
                             _("Failed to read the container continue message"));
213
213
        return -1;
214
214
    }
215
215
    close(control);
266
266
 
267
267
static int lxcContainerPivotRoot(virDomainFSDefPtr root)
268
268
{
 
269
    int rc;
269
270
    char *oldroot;
270
271
 
271
272
    /* First step is to ensure the new root itself is
272
273
       a mount point */
273
274
    if (mount(root->src, root->src, NULL, MS_BIND, NULL) < 0) {
274
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
275
 
                 _("failed to bind new root %s: %s"),
276
 
                 root->src, strerror(errno));
277
 
        return -1;
278
 
    }
279
 
 
280
 
    if (asprintf(&oldroot, "%s/.oldroot", root->src) < 0) {
281
 
        oldroot = NULL;
282
 
        lxcError(NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
283
 
        return -1;
284
 
    }
285
 
 
286
 
    if (virFileMakePath(oldroot) < 0) {
 
275
        virReportSystemError(NULL, errno,
 
276
                             _("failed to bind new root %s"),
 
277
                             root->src);
 
278
        return -1;
 
279
    }
 
280
 
 
281
    if (virAsprintf(&oldroot, "%s/.oldroot", root->src) < 0) {
 
282
        virReportOOMError(NULL);
 
283
        return -1;
 
284
    }
 
285
 
 
286
    if ((rc = virFileMakePath(oldroot)) < 0) {
287
287
        VIR_FREE(oldroot);
288
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
289
 
                 _("failed to create %s: %s"),
290
 
                 oldroot, strerror(errno));
 
288
        virReportSystemError(NULL, rc,
 
289
                             _("failed to create %s"),
 
290
                             oldroot);
291
291
        return -1;
292
292
    }
293
293
 
295
295
     * this and will soon be unmounted completely */
296
296
    if (pivot_root(root->src, oldroot) < 0) {
297
297
        VIR_FREE(oldroot);
298
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
299
 
                 _("failed to pivot root %s to %s: %s"),
300
 
                 oldroot, root->src, strerror(errno));
 
298
        virReportSystemError(NULL, errno,
 
299
                             _("failed to pivot root %s to %s"),
 
300
                             oldroot, root->src);
301
301
        return -1;
302
302
    }
303
303
    VIR_FREE(oldroot);
313
313
static int lxcContainerPopulateDevices(void)
314
314
{
315
315
    int i;
 
316
    int rc;
316
317
    const struct {
317
318
        int maj;
318
319
        int min;
327
328
        { LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_URANDOM, 0666, "/dev/urandom" },
328
329
    };
329
330
 
330
 
    if (virFileMakePath("/dev") < 0 ||
331
 
        mount("none", "/dev", "tmpfs", 0, NULL) < 0) {
332
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
333
 
                 _("failed to mount /dev tmpfs for container: %s"),
334
 
                 strerror(errno));
 
331
    if ((rc = virFileMakePath("/dev")) < 0) {
 
332
        virReportSystemError(NULL, rc, "%s",
 
333
                             _("cannot create /dev/"));
 
334
        return -1;
 
335
    }
 
336
    if (mount("none", "/dev", "tmpfs", 0, NULL) < 0) {
 
337
        virReportSystemError(NULL, errno, "%s",
 
338
                             _("failed to mount /dev tmpfs"));
335
339
        return -1;
336
340
    }
337
341
    /* Move old devpts into container, since we have to
340
344
       XXX This sucks, we need to figure out how to get our
341
345
       own private devpts for isolation
342
346
    */
343
 
    if (virFileMakePath("/dev/pts") < 0 ||
344
 
        mount("/.oldroot/dev/pts", "/dev/pts", NULL,
 
347
    if ((rc = virFileMakePath("/dev/pts") < 0)) {
 
348
        virReportSystemError(NULL, rc, "%s",
 
349
                             _("cannot create /dev/pts"));
 
350
        return -1;
 
351
    }
 
352
    if (mount("/.oldroot/dev/pts", "/dev/pts", NULL,
345
353
              MS_MOVE, NULL) < 0) {
346
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
347
 
                 _("failed to move /dev/pts into container: %s"),
348
 
                 strerror(errno));
 
354
        virReportSystemError(NULL, errno, "%s",
 
355
                             _("failed to move /dev/pts into container"));
349
356
        return -1;
350
357
    }
351
358
 
354
361
        dev_t dev = makedev(devs[i].maj, devs[i].min);
355
362
        if (mknod(devs[i].path, 0, dev) < 0 ||
356
363
            chmod(devs[i].path, devs[i].mode)) {
357
 
            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
358
 
                     _("failed to make device %s: %s"),
359
 
                     devs[i].path, strerror(errno));
 
364
            virReportSystemError(NULL, errno,
 
365
                                 _("failed to make device %s"),
 
366
                                 devs[i].path);
360
367
            return -1;
361
368
        }
362
369
    }
378
385
        if (vmDef->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
379
386
            continue;
380
387
 
381
 
        if (asprintf(&src, "/.oldroot/%s", vmDef->fss[i]->src) < 0) {
382
 
            lxcError(NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
 
388
        if (virAsprintf(&src, "/.oldroot/%s", vmDef->fss[i]->src) < 0) {
 
389
            virReportOOMError(NULL);
383
390
            return -1;
384
391
        }
385
392
 
386
 
        if (virFileMakePath(vmDef->fss[i]->dst) < 0 ||
387
 
            mount(src, vmDef->fss[i]->dst, NULL, MS_BIND, NULL) < 0) {
388
 
            VIR_FREE(src);
389
 
            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
390
 
                     _("failed to mount %s at %s for container: %s"),
391
 
                     vmDef->fss[i]->src, vmDef->fss[i]->dst, strerror(errno));
 
393
        if (virFileMakePath(vmDef->fss[i]->dst) < 0) {
 
394
            virReportSystemError(NULL, errno,
 
395
                                 _("failed to create %s"),
 
396
                                 vmDef->fss[i]->dst);
 
397
            VIR_FREE(src);
 
398
            return -1;
 
399
        }
 
400
        if (mount(src, vmDef->fss[i]->dst, NULL, MS_BIND, NULL) < 0) {
 
401
            VIR_FREE(src);
 
402
            virReportSystemError(NULL, errno,
 
403
                                 _("failed to mount %s at %s"),
 
404
                                 vmDef->fss[i]->src,
 
405
                                 vmDef->fss[i]->dst);
392
406
            return -1;
393
407
        }
394
408
        VIR_FREE(src);
400
414
 
401
415
static int lxcContainerUnmountOldFS(void)
402
416
{
403
 
    struct mntent *mntent;
 
417
    struct mntent mntent;
404
418
    char **mounts = NULL;
405
419
    int nmounts = 0;
406
420
    FILE *procmnt;
407
421
    int i;
 
422
    char mntbuf[1024];
408
423
 
409
424
    if (!(procmnt = setmntent("/proc/mounts", "r"))) {
410
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
411
 
                 _("failed to read /proc/mounts: %s"),
412
 
                 strerror(errno));
 
425
        virReportSystemError(NULL, errno, "%s",
 
426
                             _("failed to read /proc/mounts"));
413
427
        return -1;
414
428
    }
415
 
    while ((mntent = getmntent(procmnt)) != NULL) {
416
 
        if (!STRPREFIX(mntent->mnt_dir, "/.oldroot"))
 
429
    while (getmntent_r(procmnt, &mntent, mntbuf, sizeof(mntbuf)) != NULL) {
 
430
        if (!STRPREFIX(mntent.mnt_dir, "/.oldroot"))
417
431
            continue;
418
432
 
419
433
        if (VIR_REALLOC_N(mounts, nmounts+1) < 0) {
420
434
            endmntent(procmnt);
421
 
            lxcError(NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
 
435
            virReportOOMError(NULL);
422
436
            return -1;
423
437
        }
424
 
        if (!(mounts[nmounts++] = strdup(mntent->mnt_dir))) {
 
438
        if (!(mounts[nmounts++] = strdup(mntent.mnt_dir))) {
425
439
            endmntent(procmnt);
426
 
            lxcError(NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
 
440
            virReportOOMError(NULL);
427
441
            return -1;
428
442
        }
429
443
    }
434
448
 
435
449
    for (i = 0 ; i < nmounts ; i++) {
436
450
        if (umount(mounts[i]) < 0) {
437
 
            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
438
 
                     _("failed to unmount %s: %s"),
439
 
                     mounts[i], strerror(errno));
 
451
            virReportSystemError(NULL, errno,
 
452
                                 _("failed to unmount '%s'"),
 
453
                                 mounts[i]);
440
454
            return -1;
441
455
        }
442
456
        VIR_FREE(mounts[i]);
459
473
 
460
474
    if (virFileMakePath("/proc") < 0 ||
461
475
        mount("none", "/proc", "proc", 0, NULL) < 0) {
462
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
463
 
                 _("failed to mount /proc for container: %s"),
464
 
                 strerror(errno));
 
476
        virReportSystemError(NULL, errno, "%s",
 
477
                             _("failed to mount /proc"));
465
478
        return -1;
466
479
    }
467
480
 
493
506
                  NULL,
494
507
                  MS_BIND,
495
508
                  NULL) < 0) {
496
 
            lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
497
 
                     _("failed to mount %s at %s for container: %s"),
498
 
                     vmDef->fss[i]->src, vmDef->fss[i]->dst, strerror(errno));
 
509
            virReportSystemError(NULL, errno,
 
510
                                 _("failed to mount %s at %s"),
 
511
                                 vmDef->fss[i]->src,
 
512
                                 vmDef->fss[i]->dst);
499
513
            return -1;
500
514
        }
501
515
    }
502
516
 
503
517
    /* mount /proc */
504
518
    if (mount("lxcproc", "/proc", "proc", 0, NULL) < 0) {
505
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
506
 
                 _("failed to mount /proc for container: %s"),
507
 
                 strerror(errno));
 
519
        virReportSystemError(NULL, errno, "%s",
 
520
                             _("failed to mount /proc"));
508
521
        return -1;
509
522
    }
510
523
 
558
571
 
559
572
    ttyfd = open(argv->ttyPath, O_RDWR|O_NOCTTY);
560
573
    if (ttyfd < 0) {
561
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
562
 
                 _("open(%s) failed: %s"), argv->ttyPath, strerror(errno));
 
574
        virReportSystemError(NULL, errno,
 
575
                             _("failed to open %s"),
 
576
                             argv->ttyPath);
563
577
        return -1;
564
578
    }
565
579
 
604
618
 
605
619
    /* allocate a stack for the container */
606
620
    if (VIR_ALLOC_N(stack, stacksize) < 0) {
607
 
        lxcError(NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
 
621
        virReportOOMError(NULL);
608
622
        return -1;
609
623
    }
610
624
    stacktop = stack + stacksize;
619
633
    DEBUG("clone() returned, %d", pid);
620
634
 
621
635
    if (pid < 0) {
622
 
        lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
623
 
                 _("clone() failed, %s"), strerror(errno));
 
636
        virReportSystemError(NULL, errno, "%s",
 
637
                             _("failed to run clone container"));
624
638
        return -1;
625
639
    }
626
640