]> git.proxmox.com Git - pve-container.git/blobdiff - src/PVE/LXC.pm
added Setup::Fedora
[pve-container.git] / src / PVE / LXC.pm
index aa705c8f9aaa93b97ff171e02ddb704573a1a65b..64563ebe938bc38b29792b11273911b7e2475934 100644 (file)
@@ -902,6 +902,15 @@ sub vmstatus {
     return $list;
 }
 
+sub classify_mountpoint {
+    my ($vol) = @_;
+    if ($vol =~ m!^/!) {
+       return 'device' if $vol =~ m!^/dev/!;
+       return 'bind';
+    }
+    return 'volume';
+}
+
 sub parse_ct_mountpoint {
     my ($data, $noerr) = @_;
 
@@ -923,12 +932,15 @@ sub parse_ct_mountpoint {
        $res->{size} = $size;
     }
 
+    $res->{type} = classify_mountpoint($res->{volume});
+
     return $res;
 }
 
 sub print_ct_mountpoint {
     my ($info, $nomp) = @_;
-    my $skip = $nomp ? ['mp'] : [];
+    my $skip = [ 'type' ];
+    push @$skip, 'mp' if $nomp;
     return PVE::JSONSchema::print_property_string($info, $mp_desc, $skip);
 }
 
@@ -1060,7 +1072,7 @@ sub update_lxc_config {
     my $custom_idmap = grep { $_->[0] eq 'lxc.id_map' } @{$conf->{lxc}};
 
     my $ostype = $conf->{ostype} || die "missing 'ostype' - internal error";
-    if ($ostype =~ /^(?:debian | ubuntu | centos | archlinux)$/x) {
+    if ($ostype =~ /^(?:debian | ubuntu | centos | fedora | archlinux)$/x) {
        $raw .= "lxc.include = /usr/share/lxc/config/$ostype.common.conf\n";
        if ($unprivileged || $custom_idmap) {
            $raw .= "lxc.include = /usr/share/lxc/config/$ostype.userns.conf\n"
@@ -1069,6 +1081,8 @@ sub update_lxc_config {
        die "implement me";
     }
 
+    $raw .= "lxc.start.unshare = 1\n";
+
     # Should we read them from /etc/subuid?
     if ($unprivileged && !$custom_idmap) {
        $raw .= "lxc.id_map = u 0 100000 65536\n";
@@ -1094,6 +1108,7 @@ sub update_lxc_config {
 
     my $lxcmem = int($memory*1024*1024);
     $raw .= "lxc.cgroup.memory.limit_in_bytes = $lxcmem\n";
+    $raw .= "lxc.cgroup.memory.kmem.limit_in_bytes = $lxcmem\n";
 
     my $lxcswap = int(($memory + $swap)*1024*1024);
     $raw .= "lxc.cgroup.memory.memsw.limit_in_bytes = $lxcswap\n";
@@ -1111,6 +1126,7 @@ sub update_lxc_config {
     $mountpoint->{mp} = '/';
 
     $raw .= "lxc.rootfs = $dir/rootfs\n";
+    $raw .= "lxc.hook.stop = /usr/lib/x86_64-linux-gnu/lxc/hooks/unmount-namespace\n";
 
     my $netcount = 0;
     foreach my $k (keys %$conf) {
@@ -1168,9 +1184,6 @@ sub verify_searchdomain_list {
 sub add_unused_volume {
     my ($config, $volid) = @_;
 
-    # skip bind mounts and block devices
-    return if $volid =~ m|^/|;
-
     my $key;
     for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
        my $test = "unused$ind";
@@ -1213,6 +1226,11 @@ sub update_pct_config {
 
     if (defined($delete)) {
        foreach my $opt (@$delete) {
+           if (!exists($conf->{$opt})) {
+               warn "no such option: $opt\n";
+               next;
+           }
+
            if ($opt eq 'hostname' || $opt eq 'memory' || $opt eq 'rootfs') {
                die "unable to delete required option '$opt'\n";
            } elsif ($opt eq 'swap') {
@@ -1240,7 +1258,9 @@ sub update_pct_config {
                next if $hotplug_error->($opt);
                check_protection($conf, "can't remove CT $vmid drive '$opt'");
                my $mountpoint = parse_ct_mountpoint($conf->{$opt});
-               add_unused_volume($conf, $mountpoint->{volume});
+               if ($mountpoint->{type} eq 'volume') {
+                   add_unused_volume($conf, $mountpoint->{volume})
+               }
                delete $conf->{$opt};
            } elsif ($opt eq 'unprivileged') {
                die "unable to delete read-only option: '$opt'\n";
@@ -1407,10 +1427,7 @@ sub get_primary_ips {
 sub delete_mountpoint_volume {
     my ($storage_cfg, $vmid, $volume) = @_;
 
-    # skip bind mounts and block devices
-    if ($volume =~ m|^/|) {
-           return;
-    }
+    return if classify_mountpoint($volume) ne 'volume';
 
     my ($vtype, $name, $owner) = PVE::Storage::parse_volname($storage_cfg, $volume);
     PVE::Storage::vdisk_free($storage_cfg, $volume) if $vmid == $owner;
@@ -2105,12 +2122,27 @@ my $check_mount_path = sub {
     }
 };
 
+sub query_loopdev {
+    my ($path) = @_;
+    my $found;
+    my $parser = sub {
+       my $line = shift;
+       if ($line =~ m@^(/dev/loop\d+):@) {
+           $found = $1;
+       }
+    };
+    my $cmd = ['losetup', '--associated', $path];
+    PVE::Tools::run_command($cmd, outfunc => $parser);
+    return $found;
+}
+
 # use $rootdir = undef to just return the corresponding mount path
 sub mountpoint_mount {
     my ($mountpoint, $rootdir, $storage_cfg, $snapname) = @_;
 
     my $volid = $mountpoint->{volume};
     my $mount = $mountpoint->{mp};
+    my $type = $mountpoint->{type};
     
     return if !$volid || !$mount;
 
@@ -2172,10 +2204,10 @@ sub mountpoint_mount {
        } else {
            die "unsupported image format '$format'\n";
        }
-    } elsif ($volid =~ m|^/dev/.+|) {
+    } elsif ($type eq 'device') {
        PVE::Tools::run_command(['mount', $volid, $mount_path]) if $mount_path;
        return wantarray ? ($volid, 0) : $volid;
-    } elsif ($volid !~ m|^/dev/.+| && $volid =~ m|^/.+| && -d $volid) {
+    } elsif ($type eq 'bind' && -d $volid) {
        &$check_mount_path($volid);
        PVE::Tools::run_command(['mount', '-o', 'bind', $volid, $mount_path]) if $mount_path;
        return wantarray ? ($volid, 0) : $volid;
@@ -2196,7 +2228,7 @@ sub get_vm_volumes {
 
        my $volid = $mountpoint->{volume};
 
-        return if !$volid || $volid =~ m|^/|;
+        return if !$volid || $mountpoint->{type} ne 'volume';
 
         my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
         return if !$sid;
@@ -2305,8 +2337,9 @@ sub create_disks {
                    die "unable to create containers on storage type '$scfg->{type}'\n";
                }
                push @$vollist, $volid;
-                my $new_mountpoint = { volume => $volid, size => $size_kb*1024, mp => $mp };
-               $conf->{$ms} = print_ct_mountpoint($new_mountpoint, $ms eq 'rootfs');
+               $mountpoint->{volume} = $volid;
+               $mountpoint->{size} = $size_kb * 1024;
+               $conf->{$ms} = print_ct_mountpoint($mountpoint, $ms eq 'rootfs');
            } else {
                # use specified/existing volid
            }