119
124
cmd = virCommandNew(vmDef->os.init);
126
if (vmDef->os.initargv && vmDef->os.initargv[0])
127
virCommandAddArgSet(cmd, (const char **)vmDef->os.initargv);
121
129
virCommandAddEnvString(cmd, "PATH=/bin:/sbin");
122
130
virCommandAddEnvString(cmd, "TERM=linux");
131
virCommandAddEnvString(cmd, "container=lxc-libvirt");
132
virCommandAddEnvPair(cmd, "container_uuid", uuidstr);
123
133
virCommandAddEnvPair(cmd, "LIBVIRT_LXC_UUID", uuidstr);
124
134
virCommandAddEnvPair(cmd, "LIBVIRT_LXC_NAME", vmDef->name);
125
135
if (vmDef->os.cmdline)
430
440
/* When we want to make a bind mount readonly, for unknown reasons,
431
* it is currently neccessary to bind it once, and then remount the
441
* it is currently necessary to bind it once, and then remount the
432
442
* bind with the readonly flag. If this is not done, then the original
433
443
* mount point in the main OS becomes readonly too which is not what
434
444
* we want. Hence some things have two entries here.
436
{ true, false, "devfs", "/dev", "tmpfs", "mode=755", MS_NOSUID },
437
{ false, false, "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
438
{ false, false, "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND },
439
{ false, false, "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
440
{ false, true, "/sys", "/sys", NULL, NULL, MS_BIND },
441
{ false, true, "/sys", "/sys", NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
442
{ false, true, "/selinux", "/selinux", NULL, NULL, MS_BIND },
443
{ false, true, "/selinux", "/selinux", NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
446
{ false, "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
447
{ false, "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND },
448
{ false, "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
449
{ true, "/sys", "/sys", NULL, NULL, MS_BIND },
450
{ true, "/sys", "/sys", NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
452
{ true, SELINUX_MOUNT, SELINUX_MOUNT, NULL, NULL, MS_BIND },
453
{ true, SELINUX_MOUNT, SELINUX_MOUNT, NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
459
security_context_t con;
447
462
VIR_DEBUG("Mounting basic filesystems %s pivotRoot=%d", NULLSTR(srcprefix), pivotRoot);
509
if (getfilecon("/", &con) < 0 &&
511
virReportSystemError(errno, "%s",
512
_("Failed to query file context on /"));
517
* tmpfs is limited to 64kb, since we only have device nodes in there
518
* and don't want to DOS the entire OS RAM usage
523
ignore_value(virAsprintf(&opts,
524
"mode=755,size=65536,context=\"%s\"",
528
opts = strdup("mode=755,size=65536");
535
VIR_DEBUG("Mount devfs on /dev type=tmpfs flags=%x, opts=%s",
537
if (mount("devfs", "/dev", "tmpfs", MS_NOSUID, opts) < 0) {
538
virReportSystemError(errno,
539
_("Failed to mount %s on %s type %s"),
540
"devfs", "/dev", "tmpfs");
495
548
VIR_DEBUG("rc=%d", rc);
500
static int lxcContainerMountDevFS(virDomainFSDefPtr root)
554
static int lxcContainerMountFSDevPTS(virDomainFSDefPtr root)
502
556
char *devpts = NULL;
543
597
{ LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_RANDOM, 0666, "/dev/random" },
544
598
{ LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_URANDOM, 0666, "/dev/urandom" },
604
{ "/proc/self/fd/0", "/dev/stdin" },
605
{ "/proc/self/fd/1", "/dev/stdout" },
606
{ "/proc/self/fd/2", "/dev/stderr" },
607
{ "/proc/self/fd", "/dev/fd" },
547
610
/* Populate /dev/ with a few important bits */
548
611
for (i = 0 ; i < ARRAY_CARDINALITY(devs) ; i++) {
559
dev_t dev = makedev(LXC_DEV_MAJ_TTY, LXC_DEV_MIN_PTMX);
560
if (mknod("/dev/ptmx", S_IFCHR, dev) < 0 ||
561
chmod("/dev/ptmx", 0666)) {
562
virReportSystemError(errno, "%s",
563
_("Failed to make device /dev/ptmx"));
622
for (i = 0 ; i < ARRAY_CARDINALITY(links) ; i++) {
623
if (symlink(links[i].src, links[i].dst) < 0) {
624
virReportSystemError(errno,
625
_("Failed to symlink device %s to %s"),
626
links[i].dst, links[i].src);
567
631
if (access("/dev/pts/ptmx", W_OK) == 0) {
632
/* We have private devpts capability, so bind that */
633
if (virFileTouch("/dev/ptmx", 0666) < 0)
568
636
if (mount("/dev/pts/ptmx", "/dev/ptmx", "ptmx", MS_BIND, NULL) < 0) {
569
637
virReportSystemError(errno, "%s",
570
_("Failed to bind-mount /dev/ptmx to /dev/pts/ptmx"));
638
_("Failed to bind /dev/pts/ptmx on to /dev/ptmx"));
642
/* Legacy devpts, so we need to just use shared one */
643
dev_t dev = makedev(LXC_DEV_MAJ_TTY, LXC_DEV_MIN_PTMX);
644
if (mknod("/dev/ptmx", S_IFCHR, dev) < 0 ||
645
chmod("/dev/ptmx", 0666)) {
646
virReportSystemError(errno, "%s",
647
_("Failed to make device /dev/ptmx"));
1193
static int lxcContainerResolveSymlinks(virDomainDefPtr vmDef)
1198
for (i = 0 ; i < vmDef->nfss ; i++) {
1199
virDomainFSDefPtr fs = vmDef->fss[i];
1200
if (virFileResolveAllLinks(fs->src, &newroot) < 0)
1203
VIR_DEBUG("Resolved '%s' to %s", fs->src, newroot);
1115
1212
static int lxcContainerSetupMounts(virDomainDefPtr vmDef,
1116
1213
virDomainFSDefPtr root,
1117
1214
char **ttyPaths,
1118
1215
size_t nttyPaths)
1217
if (lxcContainerResolveSymlinks(vmDef) < 0)
1121
1221
return lxcContainerSetupPivotRoot(vmDef, root, ttyPaths, nttyPaths);