]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/QemuServer.pm
implement shared file locks
[qemu-server.git] / PVE / QemuServer.pm
index 6bab01614455bd0dec9cd746f53993c6ce9d9343..853fd4202fce9eba34a03dc8c2174b3d974b23e9 100644 (file)
@@ -21,7 +21,7 @@ use PVE::SafeSyslog;
 use Storable qw(dclone);
 use PVE::Exception qw(raise raise_param_exc);
 use PVE::Storage;
-use PVE::Tools qw(run_command lock_file file_read_firstline);
+use PVE::Tools qw(run_command lock_file lock_file_full file_read_firstline);
 use PVE::JSONSchema qw(get_standard_option);
 use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
 use PVE::INotify;
@@ -358,6 +358,12 @@ EODESC
        typetext => '[[order=]\d+] [,up=\d+] [,down=\d+] ',
        description => "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.",
     },
+    template => {
+       optional => 1,
+       type => 'boolean',
+       description => "Enable/disable Template.",
+       default => 0,
+    },
     args => {
        optional => 1,
        type => 'string',
@@ -398,7 +404,7 @@ EODESCR
        description => "Emulated CPU type.",
        type => 'string',
        enum => [ qw(486 athlon pentium pentium2 pentium3 coreduo core2duo kvm32 kvm64 qemu32 qemu64 phenom Conroe Penryn Nehalem Westmere SandyBridge Haswell Opteron_G1 Opteron_G2 Opteron_G3 Opteron_G4 Opteron_G5 host) ],
-       default => 'qemu64',
+       default => 'kvm64',
     },
     parent => get_standard_option('pve-snapshot-name', {
        optional => 1,
@@ -1106,6 +1112,8 @@ sub print_drive_full {
        }
     }
 
+    $opts .= ",cache=none" if !$drive->{cache} && !drive_is_cdrom($drive);
+
     my $pathinfo = $path ? "file=$path," : '';
 
     return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
@@ -1191,7 +1199,7 @@ sub parse_net {
 
        if ($kvp =~ m/^(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
            my $model = lc($1);
-           my $mac = uc($3) || PVE::Tools::random_ether_addr();
+           my $mac = defined($3) ? uc($3) : PVE::Tools::random_ether_addr();
            $res->{model} = $model;
            $res->{macaddr} = $mac;
        } elsif ($kvp =~ m/^bridge=(\S+)$/) {
@@ -1471,6 +1479,18 @@ sub lock_config_full {
     return $res;
 }
 
+sub lock_config_shared {
+    my ($vmid, $timeout, $code, @param) = @_;
+
+    my $filename = config_file_lock($vmid);
+
+    my $res = lock_file_full($filename, $timeout, 1, $code, @param);
+
+    die $@ if $@;
+
+    return $res;
+}
+
 sub lock_config {
     my ($vmid, $code, @param) = @_;
 
@@ -2603,9 +2623,9 @@ sub vm_deviceunplug {
     die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
 
     if ($deviceid =~ m/^(virtio)(\d+)$/) {
-        return undef if !qemu_drivedel($vmid, $deviceid);
         qemu_devicedel($vmid, $deviceid);
         return undef if !qemu_devicedelverify($vmid, $deviceid);
+        return undef if !qemu_drivedel($vmid, $deviceid);
     }
 
     if ($deviceid =~ m/^(lsi)(\d+)$/) {
@@ -2618,9 +2638,9 @@ sub vm_deviceunplug {
     }
 
     if ($deviceid =~ m/^(net)(\d+)$/) {
-        return undef if !qemu_netdevdel($vmid, $deviceid);
         qemu_devicedel($vmid, $deviceid);
         return undef if !qemu_devicedelverify($vmid, $deviceid);
+        return undef if !qemu_netdevdel($vmid, $deviceid);
     }
 
     return 1;
@@ -3620,7 +3640,13 @@ sub rescan {
            
        check_lock($conf);
 
-       my $changes = update_disksize($vmid, $conf, $volid_hash);
+       my $vm_volids = {};
+       foreach my $volid (keys %$volid_hash) {
+           my $info = $volid_hash->{$volid};
+           $vm_volids->{$volid} = $info if $info->{vmid} && $info->{vmid} == $vmid;
+       }
+
+       my $changes = update_disksize($vmid, $conf, $vm_volids);
 
        update_config_nolock($vmid, $conf, 1) if $changes;
     };
@@ -3772,7 +3798,8 @@ sub restore_vma_archive {
 
            my $write_zeros = 1;
            # fixme: what other storages types initialize volumes with zero?
-           if ($scfg->{type} eq 'dir' || $scfg->{type} eq 'nfs') {
+           if ($scfg->{type} eq 'dir' || $scfg->{type} eq 'nfs' || 
+               $scfg->{type} eq 'sheepdog' || $scfg->{type} eq 'rbd') {
                $write_zeros = 0;
            }
 
@@ -4426,11 +4453,7 @@ sub has_feature {
 sub template_create {
     my ($vmid, $conf, $disk) = @_;
 
-    my $running = check_running($vmid);
-    die "you can't convert a vm to template if vm is running vm\n" if $running;
-
     my $storecfg = PVE::Storage::config();
-    my $i = 0;
 
     foreach_drive($conf, sub {
        my ($ds, $drive) = @_;
@@ -4439,52 +4462,19 @@ sub template_create {
        return if $disk && $ds ne $disk;
 
        my $volid = $drive->{file};
-       die "volume '$volid' does not support template/clone\n" 
-           if !PVE::Storage::volume_has_feature($storecfg, 'template', $volid);
-    });
-
-    foreach_drive($conf, sub {
-       my ($ds, $drive) = @_;
+       return if !PVE::Storage::volume_has_feature($storecfg, 'template', $volid);
 
-       return if drive_is_cdrom($drive);
-       return if $disk && $ds ne $disk;
-
-       my $volid = $drive->{file};
        my $voliddst = PVE::Storage::vdisk_create_base($storecfg, $volid);
        $drive->{file} = $voliddst;
        $conf->{$ds} = PVE::QemuServer::print_drive($vmid, $drive);
        PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
-
     });
-    if($conf->{snapshots}){
-       delete $conf->{parent};
-       delete $conf->{snapshots};
-       PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
-       #fixme : do we need to delete disks snapshots ?
-    }
 }
 
 sub is_template {
     my ($conf) = @_;
 
-    my $baseimagecount = 0;
-    my $totalvolumecount = 0;
-    my $storecfg = PVE::Storage::config();
-
-    foreach_drive($conf, sub {
-       my ($ds, $drive) = @_;
-       return if drive_is_cdrom($drive);
-       $totalvolumecount++;
-       my $volid = $drive->{file};
-       if (PVE::Storage::volume_is_base($storecfg, $volid)){
-           $baseimagecount++;
-       }
-
-    });
-
-    return 0 if $baseimagecount == 0;
-    return 1 if $baseimagecount == $totalvolumecount; #full template
-    return 2 if $baseimagecount < $totalvolumecount; #semi-template
+    return 1 if defined $conf->{template} && $conf->{template} == 1;
 }
 
 1;