1 package PVE
::QemuServer
;
21 use Storable
qw(dclone);
22 use PVE
::Exception
qw(raise raise_param_exc);
24 use PVE
::Tools
qw(run_command lock_file lock_file_full file_read_firstline);
25 use PVE
::JSONSchema
qw(get_standard_option);
26 use PVE
::Cluster
qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
30 use PVE
::RPCEnvironment
;
31 use Time
::HiRes
qw(gettimeofday);
33 my $cpuinfo = PVE
::ProcFSTools
::read_cpuinfo
();
35 # Note about locking: we use flock on the config file protect
36 # against concurent actions.
37 # Aditionaly, we have a 'lock' setting in the config file. This
38 # can be set to 'migrate', 'backup', 'snapshot' or 'rollback'. Most actions are not
39 # allowed when such lock is set. But you can ignore this kind of
40 # lock with the --skiplock flag.
42 cfs_register_file
('/qemu-server/',
46 PVE
::JSONSchema
::register_standard_option
('skiplock', {
47 description
=> "Ignore locks - only root is allowed to use this option.",
52 PVE
::JSONSchema
::register_standard_option
('pve-qm-stateuri', {
53 description
=> "Some command save/restore state from this location.",
59 PVE
::JSONSchema
::register_standard_option
('pve-snapshot-name', {
60 description
=> "The name of the snapshot.",
61 type
=> 'string', format
=> 'pve-configid',
65 #no warnings 'redefine';
67 unless(defined(&_VZSYSCALLS_H_
)) {
68 eval 'sub _VZSYSCALLS_H_ () {1;}' unless defined(&_VZSYSCALLS_H_
);
69 require 'sys/syscall.ph';
70 if(defined(&__x86_64__
)) {
71 eval 'sub __NR_fairsched_vcpus () {499;}' unless defined(&__NR_fairsched_vcpus
);
72 eval 'sub __NR_fairsched_mknod () {504;}' unless defined(&__NR_fairsched_mknod
);
73 eval 'sub __NR_fairsched_rmnod () {505;}' unless defined(&__NR_fairsched_rmnod
);
74 eval 'sub __NR_fairsched_chwt () {506;}' unless defined(&__NR_fairsched_chwt
);
75 eval 'sub __NR_fairsched_mvpr () {507;}' unless defined(&__NR_fairsched_mvpr
);
76 eval 'sub __NR_fairsched_rate () {508;}' unless defined(&__NR_fairsched_rate
);
77 eval 'sub __NR_setluid () {501;}' unless defined(&__NR_setluid
);
78 eval 'sub __NR_setublimit () {502;}' unless defined(&__NR_setublimit
);
80 elsif(defined( &__i386__
) ) {
81 eval 'sub __NR_fairsched_mknod () {500;}' unless defined(&__NR_fairsched_mknod
);
82 eval 'sub __NR_fairsched_rmnod () {501;}' unless defined(&__NR_fairsched_rmnod
);
83 eval 'sub __NR_fairsched_chwt () {502;}' unless defined(&__NR_fairsched_chwt
);
84 eval 'sub __NR_fairsched_mvpr () {503;}' unless defined(&__NR_fairsched_mvpr
);
85 eval 'sub __NR_fairsched_rate () {504;}' unless defined(&__NR_fairsched_rate
);
86 eval 'sub __NR_fairsched_vcpus () {505;}' unless defined(&__NR_fairsched_vcpus
);
87 eval 'sub __NR_setluid () {511;}' unless defined(&__NR_setluid
);
88 eval 'sub __NR_setublimit () {512;}' unless defined(&__NR_setublimit
);
90 die("no fairsched syscall for this arch");
92 require 'asm/ioctl.ph';
93 eval 'sub KVM_GET_API_VERSION () { &_IO(0xAE, 0x);}' unless defined(&KVM_GET_API_VERSION
);
97 my ($parent, $weight, $desired) = @_;
99 return syscall(&__NR_fairsched_mknod
, int($parent), int($weight), int($desired));
102 sub fairsched_rmnod
{
105 return syscall(&__NR_fairsched_rmnod
, int($id));
109 my ($pid, $newid) = @_;
111 return syscall(&__NR_fairsched_mvpr
, int($pid), int($newid));
114 sub fairsched_vcpus
{
115 my ($id, $vcpus) = @_;
117 return syscall(&__NR_fairsched_vcpus
, int($id), int($vcpus));
121 my ($id, $op, $rate) = @_;
123 return syscall(&__NR_fairsched_rate
, int($id), int($op), int($rate));
126 use constant FAIRSCHED_SET_RATE
=> 0;
127 use constant FAIRSCHED_DROP_RATE
=> 1;
128 use constant FAIRSCHED_GET_RATE
=> 2;
130 sub fairsched_cpulimit
{
131 my ($id, $limit) = @_;
133 my $cpulim1024 = int($limit * 1024 / 100);
134 my $op = $cpulim1024 ? FAIRSCHED_SET_RATE
: FAIRSCHED_DROP_RATE
;
136 return fairsched_rate
($id, $op, $cpulim1024);
139 my $nodename = PVE
::INotify
::nodename
();
141 mkdir "/etc/pve/nodes/$nodename";
142 my $confdir = "/etc/pve/nodes/$nodename/qemu-server";
145 my $var_run_tmpdir = "/var/run/qemu-server";
146 mkdir $var_run_tmpdir;
148 my $lock_dir = "/var/lock/qemu-server";
151 my $pcisysfs = "/sys/bus/pci";
157 description
=> "Specifies whether a VM will be started during system bootup.",
163 description
=> "Automatic restart after crash (currently ignored).",
169 description
=> "Allow hotplug for disk and network device",
175 description
=> "Allow reboot. If set to '0' the VM exit on reboot.",
181 description
=> "Lock/unlock the VM.",
182 enum
=> [qw(migrate backup snapshot rollback)],
187 description
=> "Limit of CPU usage in per cent. Note if the computer has 2 CPUs, it has total of 200% CPU time. Value '0' indicates no CPU limit.\n\nNOTE: This option is currently ignored.",
194 description
=> "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs.\n\nNOTE: You can disable fair-scheduler configuration by setting this to 0.",
202 description
=> "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.",
209 description
=> "Amount of target RAM for the VM in MB. Using zero disables the ballon driver.",
215 description
=> "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning",
223 description
=> "Keybord layout for vnc server. Default is read from the datacenter configuration file.",
224 enum
=> PVE
::Tools
::kvmkeymaplist
(),
229 type
=> 'string', format
=> 'dns-name',
230 description
=> "Set a name for the VM. Only used on the configuration web interface.",
235 description
=> "scsi controller model",
236 enum
=> [qw(lsi virtio-scsi-pci megasas)],
242 description
=> "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.",
247 enum
=> [qw(other wxp w2k w2k3 w2k8 wvista win7 win8 l24 l26)],
248 description
=> <<EODESC,
249 Used to enable special optimization/features for specific
252 other => unspecified OS
253 wxp => Microsoft Windows XP
254 w2k => Microsoft Windows 2000
255 w2k3 => Microsoft Windows 2003
256 w2k8 => Microsoft Windows 2008
257 wvista => Microsoft Windows Vista
258 win7 => Microsoft Windows 7
259 win8 => Microsoft Windows 8/2012
260 l24 => Linux 2.4 Kernel
261 l26 => Linux 2.6/3.X Kernel
263 other|l24|l26 ... no special behaviour
264 wxp|w2k|w2k3|w2k8|wvista|win7|win8 ... use --localtime switch
270 description
=> "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n).",
271 pattern
=> '[acdn]{1,4}',
276 type
=> 'string', format
=> 'pve-qm-bootdisk',
277 description
=> "Enable booting from specified disk.",
278 pattern
=> '(ide|sata|scsi|virtio)\d+',
283 description
=> "The number of CPUs. Please use option -sockets instead.",
290 description
=> "The number of CPU sockets.",
297 description
=> "The number of cores per socket.",
304 description
=> "Enable/disable ACPI.",
310 description
=> "Enable/disable Qemu GuestAgent.",
316 description
=> "Enable/disable KVM hardware virtualization.",
322 description
=> "Enable/disable time drift fix.",
328 description
=> "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
333 description
=> "Freeze CPU at startup (use 'c' monitor command to start execution).",
338 description
=> "Select VGA type. If you want to use high resolution modes (>= 1280x1024x16) then you should use option 'std' or 'vmware'. Default is 'std' for win8/win7/w2k8, and 'cirrur' for other OS types. Option 'qxl' enables the SPICE display sever.",
339 enum
=> [qw(std cirrus vmware qxl)],
343 type
=> 'string', format
=> 'pve-qm-watchdog',
344 typetext
=> '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
345 description
=> "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the guest will be restarted (or execute the action specified)",
350 typetext
=> "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
351 description
=> "Set the initial date of the real time clock. Valid format for date are: 'now' or '2006-06-17T16:01:21' or '2006-06-17'.",
352 pattern
=> '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
357 type
=> 'string', format
=> 'pve-qm-startup',
358 typetext
=> '[[order=]\d+] [,up=\d+] [,down=\d+] ',
359 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.",
364 description
=> "Enable/disable Template.",
370 description
=> <<EODESCR,
371 Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
373 args: -no-reboot -no-hpet
380 description
=> "Enable/disable the usb tablet device. This device is usually needed to allow absolute mouse positioning. Else the mouse runs out of sync with normal vnc clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches.",
385 description
=> "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
389 migrate_downtime
=> {
392 description
=> "Set maximum tolerated downtime (in seconds) for migrations.",
398 type
=> 'string', format
=> 'pve-qm-drive',
399 typetext
=> 'volume',
400 description
=> "This is an alias for option -ide2",
404 description
=> "Emulated CPU type.",
406 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) ],
409 parent
=> get_standard_option
('pve-snapshot-name', {
411 description
=> "Parent snapshot name. This is used internally, and should not be modified.",
415 description
=> "Timestamp for snapshots.",
421 type
=> 'string', format
=> 'pve-volume-id',
422 description
=> "Reference to a volume which stores the VM state. This is used internally for snapshots.",
425 description
=> "Specific the Qemu machine type.",
427 pattern
=> '(pc|pc(-i440fx)?-\d+\.\d+|q35|pc-q35-\d+\.\d+)',
433 # what about other qemu settings ?
435 #machine => 'string',
448 ##soundhw => 'string',
450 while (my ($k, $v) = each %$confdesc) {
451 PVE
::JSONSchema
::register_standard_option
("pve-qm-$k", $v);
454 my $MAX_IDE_DISKS = 4;
455 my $MAX_SCSI_DISKS = 14;
456 my $MAX_VIRTIO_DISKS = 16;
457 my $MAX_SATA_DISKS = 6;
458 my $MAX_USB_DEVICES = 5;
460 my $MAX_UNUSED_DISKS = 8;
461 my $MAX_HOSTPCI_DEVICES = 2;
462 my $MAX_SERIAL_PORTS = 4;
463 my $MAX_PARALLEL_PORTS = 3;
465 my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
466 'ne2k_isa', 'i82551', 'i82557b', 'i82559er'];
467 my $nic_model_list_txt = join(' ', sort @$nic_model_list);
471 type
=> 'string', format
=> 'pve-qm-net',
472 typetext
=> "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,rate=<mbps>][,tag=<vlanid>]",
473 description
=> <<EODESCR,
474 Specify network devices.
476 MODEL is one of: $nic_model_list_txt
478 XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
479 automatically generated if not specified.
481 The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
483 Option 'rate' is used to limit traffic bandwidth from and to this interface. It is specified as floating point number, unit is 'Megabytes per second'.
485 If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
491 The DHCP server assign addresses to the guest starting from 10.0.2.15.
495 PVE
::JSONSchema
::register_standard_option
("pve-qm-net", $netdesc);
497 for (my $i = 0; $i < $MAX_NETS; $i++) {
498 $confdesc->{"net$i"} = $netdesc;
505 type
=> 'string', format
=> 'pve-qm-drive',
506 typetext
=> '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback|unsafe|directsync] [,format=f] [,backup=yes|no] [,rerror=ignore|report|stop] [,werror=enospc|ignore|report|stop] [,aio=native|threads]',
507 description
=> "Use volume as IDE hard disk or CD-ROM (n is 0 to " .($MAX_IDE_DISKS -1) . ").",
509 PVE
::JSONSchema
::register_standard_option
("pve-qm-ide", $idedesc);
513 type
=> 'string', format
=> 'pve-qm-drive',
514 typetext
=> '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback|unsafe|directsync] [,format=f] [,backup=yes|no] [,rerror=ignore|report|stop] [,werror=enospc|ignore|report|stop] [,aio=native|threads]',
515 description
=> "Use volume as SCSI hard disk or CD-ROM (n is 0 to " . ($MAX_SCSI_DISKS - 1) . ").",
517 PVE
::JSONSchema
::register_standard_option
("pve-qm-scsi", $scsidesc);
521 type
=> 'string', format
=> 'pve-qm-drive',
522 typetext
=> '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback|unsafe|directsync] [,format=f] [,backup=yes|no] [,rerror=ignore|report|stop] [,werror=enospc|ignore|report|stop] [,aio=native|threads]',
523 description
=> "Use volume as SATA hard disk or CD-ROM (n is 0 to " . ($MAX_SATA_DISKS - 1). ").",
525 PVE
::JSONSchema
::register_standard_option
("pve-qm-sata", $satadesc);
529 type
=> 'string', format
=> 'pve-qm-drive',
530 typetext
=> '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback|unsafe|directsync] [,format=f] [,backup=yes|no] [,rerror=ignore|report|stop] [,werror=enospc|ignore|report|stop] [,aio=native|threads]',
531 description
=> "Use volume as VIRTIO hard disk (n is 0 to " . ($MAX_VIRTIO_DISKS - 1) . ").",
533 PVE
::JSONSchema
::register_standard_option
("pve-qm-virtio", $virtiodesc);
537 type
=> 'string', format
=> 'pve-qm-usb-device',
538 typetext
=> 'host=HOSTUSBDEVICE|spice',
539 description
=> <<EODESCR,
540 Configure an USB device (n is 0 to 4). This can be used to
541 pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
543 'bus-port(.port)*' (decimal numbers) or
544 'vendor_id:product_id' (hexadeciaml numbers)
546 You can use the 'lsusb -t' command to list existing usb devices.
548 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
550 The value 'spice' can be used to add a usb redirection devices for spice.
554 PVE
::JSONSchema
::register_standard_option
("pve-qm-usb", $usbdesc);
558 type
=> 'string', format
=> 'pve-qm-hostpci',
559 typetext
=> "HOSTPCIDEVICE",
560 description
=> <<EODESCR,
561 Map host pci devices. HOSTPCIDEVICE syntax is:
563 'bus:dev.func' (hexadecimal numbers)
565 You can us the 'lspci' command to list existing pci devices.
567 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
569 Experimental: user reported problems with this option.
572 PVE
::JSONSchema
::register_standard_option
("pve-qm-hostpci", $hostpcidesc);
577 pattern
=> '/dev/ttyS\d+',
578 description
=> <<EODESCR,
579 Map host serial devices (n is 0 to 3).
581 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
583 Experimental: user reported problems with this option.
590 pattern
=> '/dev/parport\d+',
591 description
=> <<EODESCR,
592 Map host parallel devices (n is 0 to 2).
594 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
596 Experimental: user reported problems with this option.
600 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
601 $confdesc->{"parallel$i"} = $paralleldesc;
604 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
605 $confdesc->{"serial$i"} = $serialdesc;
608 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
609 $confdesc->{"hostpci$i"} = $hostpcidesc;
612 for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
613 $drivename_hash->{"ide$i"} = 1;
614 $confdesc->{"ide$i"} = $idedesc;
617 for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
618 $drivename_hash->{"sata$i"} = 1;
619 $confdesc->{"sata$i"} = $satadesc;
622 for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
623 $drivename_hash->{"scsi$i"} = 1;
624 $confdesc->{"scsi$i"} = $scsidesc ;
627 for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
628 $drivename_hash->{"virtio$i"} = 1;
629 $confdesc->{"virtio$i"} = $virtiodesc;
632 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
633 $confdesc->{"usb$i"} = $usbdesc;
638 type
=> 'string', format
=> 'pve-volume-id',
639 description
=> "Reference to unused volumes.",
642 for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
643 $confdesc->{"unused$i"} = $unuseddesc;
646 my $kvm_api_version = 0;
650 return $kvm_api_version if $kvm_api_version;
652 my $fh = IO
::File-
>new("</dev/kvm") ||
655 if (my $v = $fh->ioctl(KVM_GET_API_VERSION
(), 0)) {
656 $kvm_api_version = $v;
661 return $kvm_api_version;
664 my $kvm_user_version;
666 sub kvm_user_version
{
668 return $kvm_user_version if $kvm_user_version;
670 $kvm_user_version = 'unknown';
672 my $tmp = `kvm -help 2>/dev/null`;
674 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?)[,\s]/) {
675 $kvm_user_version = $2;
678 return $kvm_user_version;
682 my $kernel_has_vhost_net = -c
'/dev/vhost-net';
685 # order is important - used to autoselect boot disk
686 return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
687 (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
688 (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
689 (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
692 sub valid_drivename
{
695 return defined($drivename_hash->{$dev});
700 return defined($confdesc->{$key});
704 return $nic_model_list;
707 sub os_list_description
{
712 w2k
=> 'Windows 2000',
713 w2k3
=>, 'Windows 2003',
714 w2k8
=> 'Windows 2008',
715 wvista
=> 'Windows Vista',
717 win8
=> 'Windows 8/2012',
727 return $cdrom_path if $cdrom_path;
729 return $cdrom_path = "/dev/cdrom" if -l
"/dev/cdrom";
730 return $cdrom_path = "/dev/cdrom1" if -l
"/dev/cdrom1";
731 return $cdrom_path = "/dev/cdrom2" if -l
"/dev/cdrom2";
735 my ($storecfg, $vmid, $cdrom) = @_;
737 if ($cdrom eq 'cdrom') {
738 return get_cdrom_path
();
739 } elsif ($cdrom eq 'none') {
741 } elsif ($cdrom =~ m
|^/|) {
744 return PVE
::Storage
::path
($storecfg, $cdrom);
748 # try to convert old style file names to volume IDs
749 sub filename_to_volume_id
{
750 my ($vmid, $file, $media) = @_;
752 if (!($file eq 'none' || $file eq 'cdrom' ||
753 $file =~ m
|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
755 return undef if $file =~ m
|/|;
757 if ($media && $media eq 'cdrom') {
758 $file = "local:iso/$file";
760 $file = "local:$vmid/$file";
767 sub verify_media_type
{
768 my ($opt, $vtype, $media) = @_;
773 if ($media eq 'disk') {
775 } elsif ($media eq 'cdrom') {
778 die "internal error";
781 return if ($vtype eq $etype);
783 raise_param_exc
({ $opt => "unexpected media type ($vtype != $etype)" });
786 sub cleanup_drive_path
{
787 my ($opt, $storecfg, $drive) = @_;
789 # try to convert filesystem paths to volume IDs
791 if (($drive->{file
} !~ m/^(cdrom|none)$/) &&
792 ($drive->{file
} !~ m
|^/dev/.+|) &&
793 ($drive->{file
} !~ m/^([^:]+):(.+)$/) &&
794 ($drive->{file
} !~ m/^\d+$/)) {
795 my ($vtype, $volid) = PVE
::Storage
::path_to_volume_id
($storecfg, $drive->{file
});
796 raise_param_exc
({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
797 $drive->{media
} = 'cdrom' if !$drive->{media
} && $vtype eq 'iso';
798 verify_media_type
($opt, $vtype, $drive->{media
});
799 $drive->{file
} = $volid;
802 $drive->{media
} = 'cdrom' if !$drive->{media
} && $drive->{file
} =~ m/^(cdrom|none)$/;
805 sub create_conf_nolock
{
806 my ($vmid, $settings) = @_;
808 my $filename = config_file
($vmid);
810 die "configuration file '$filename' already exists\n" if -f
$filename;
812 my $defaults = load_defaults
();
814 $settings->{name
} = "vm$vmid" if !$settings->{name
};
815 $settings->{memory
} = $defaults->{memory
} if !$settings->{memory
};
818 foreach my $opt (keys %$settings) {
819 next if !$confdesc->{$opt};
821 my $value = $settings->{$opt};
824 $data .= "$opt: $value\n";
827 PVE
::Tools
::file_set_contents
($filename, $data);
830 my $parse_size = sub {
833 return undef if $value !~ m/^(\d+(\.\d+)?)([KMG])?$/;
834 my ($size, $unit) = ($1, $3);
837 $size = $size * 1024;
838 } elsif ($unit eq 'M') {
839 $size = $size * 1024 * 1024;
840 } elsif ($unit eq 'G') {
841 $size = $size * 1024 * 1024 * 1024;
847 my $format_size = sub {
852 my $kb = int($size/1024);
853 return $size if $kb*1024 != $size;
855 my $mb = int($kb/1024);
856 return "${kb}K" if $mb*1024 != $kb;
858 my $gb = int($mb/1024);
859 return "${mb}M" if $gb*1024 != $mb;
864 # ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
865 # [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
866 # [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
867 # [,aio=native|threads]
870 my ($key, $data) = @_;
874 # $key may be undefined - used to verify JSON parameters
875 if (!defined($key)) {
876 $res->{interface
} = 'unknown'; # should not harm when used to verify parameters
878 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
879 $res->{interface
} = $1;
885 foreach my $p (split (/,/, $data)) {
886 next if $p =~ m/^\s*$/;
888 if ($p =~ m/^(file|volume|cyls|heads|secs|trans|media|snapshot|cache|format|rerror|werror|backup|aio|bps|mbps|bps_rd|mbps_rd|bps_wr|mbps_wr|iops|iops_rd|iops_wr|size)=(.+)$/) {
889 my ($k, $v) = ($1, $2);
891 $k = 'file' if $k eq 'volume';
893 return undef if defined $res->{$k};
895 if ($k eq 'bps' || $k eq 'bps_rd' || $k eq 'bps_wr') {
896 return undef if !$v || $v !~ m/^\d+/;
898 $v = sprintf("%.3f", $v / (1024*1024));
902 if (!$res->{file
} && $p !~ m/=/) {
910 return undef if !$res->{file
};
912 if($res->{file
} =~ m/\.(raw|cow|qcow|qcow2|vmdk|cloop)$/){
916 return undef if $res->{cache
} &&
917 $res->{cache
} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
918 return undef if $res->{snapshot
} && $res->{snapshot
} !~ m/^(on|off)$/;
919 return undef if $res->{cyls
} && $res->{cyls
} !~ m/^\d+$/;
920 return undef if $res->{heads
} && $res->{heads
} !~ m/^\d+$/;
921 return undef if $res->{secs
} && $res->{secs
} !~ m/^\d+$/;
922 return undef if $res->{media
} && $res->{media
} !~ m/^(disk|cdrom)$/;
923 return undef if $res->{trans
} && $res->{trans
} !~ m/^(none|lba|auto)$/;
924 return undef if $res->{format
} && $res->{format
} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
925 return undef if $res->{rerror
} && $res->{rerror
} !~ m/^(ignore|report|stop)$/;
926 return undef if $res->{werror
} && $res->{werror
} !~ m/^(enospc|ignore|report|stop)$/;
927 return undef if $res->{backup
} && $res->{backup
} !~ m/^(yes|no)$/;
928 return undef if $res->{aio
} && $res->{aio
} !~ m/^(native|threads)$/;
931 return undef if $res->{mbps_rd
} && $res->{mbps
};
932 return undef if $res->{mbps_wr
} && $res->{mbps
};
934 return undef if $res->{mbps
} && $res->{mbps
} !~ m/^\d+(\.\d+)?$/;
935 return undef if $res->{mbps_rd
} && $res->{mbps_rd
} !~ m/^\d+(\.\d+)?$/;
936 return undef if $res->{mbps_wr
} && $res->{mbps_wr
} !~ m/^\d+(\.\d+)?$/;
938 return undef if $res->{iops_rd
} && $res->{iops
};
939 return undef if $res->{iops_wr
} && $res->{iops
};
940 return undef if $res->{iops
} && $res->{iops
} !~ m/^\d+$/;
941 return undef if $res->{iops_rd
} && $res->{iops_rd
} !~ m/^\d+$/;
942 return undef if $res->{iops_wr
} && $res->{iops_wr
} !~ m/^\d+$/;
946 return undef if !defined($res->{size
} = &$parse_size($res->{size
}));
949 if ($res->{media
} && ($res->{media
} eq 'cdrom')) {
950 return undef if $res->{snapshot
} || $res->{trans
} || $res->{format
};
951 return undef if $res->{heads
} || $res->{secs
} || $res->{cyls
};
952 return undef if $res->{interface
} eq 'virtio';
955 # rerror does not work with scsi drives
956 if ($res->{rerror
}) {
957 return undef if $res->{interface
} eq 'scsi';
963 my @qemu_drive_options = qw(heads secs cyls trans media format cache snapshot rerror werror aio iops iops_rd iops_wr);
966 my ($vmid, $drive) = @_;
969 foreach my $o (@qemu_drive_options, 'mbps', 'mbps_rd', 'mbps_wr', 'backup') {
970 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
973 if ($drive->{size
}) {
974 $opts .= ",size=" . &$format_size($drive->{size
});
977 return "$drive->{file}$opts";
981 my($fh, $noerr) = @_;
984 my $SG_GET_VERSION_NUM = 0x2282;
986 my $versionbuf = "\x00" x
8;
987 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
989 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
992 my $version = unpack("I", $versionbuf);
993 if ($version < 30000) {
994 die "scsi generic interface too old\n" if !$noerr;
998 my $buf = "\x00" x
36;
999 my $sensebuf = "\x00" x
8;
1000 my $cmd = pack("C x3 C x1", 0x12, 36);
1002 # see /usr/include/scsi/sg.h
1003 my $sg_io_hdr_t = "i i C C s I P P P I I i P C C C C S S i I I";
1005 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
1006 length($sensebuf), 0, length($buf), $buf,
1007 $cmd, $sensebuf, 6000);
1009 $ret = ioctl($fh, $SG_IO, $packet);
1011 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
1015 my @res = unpack($sg_io_hdr_t, $packet);
1016 if ($res[17] || $res[18]) {
1017 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
1022 (my $byte0, my $byte1, $res->{vendor
},
1023 $res->{product
}, $res->{revision
}) = unpack("C C x6 A8 A16 A4", $buf);
1025 $res->{removable
} = $byte1 & 128 ?
1 : 0;
1026 $res->{type
} = $byte0 & 31;
1034 my $fh = IO
::File-
>new("+<$path") || return undef;
1035 my $res = scsi_inquiry
($fh, 1);
1041 sub print_drivedevice_full
{
1042 my ($storecfg, $conf, $vmid, $drive, $bridges) = @_;
1047 if ($drive->{interface
} eq 'virtio') {
1048 my $pciaddr = print_pci_addr
("$drive->{interface}$drive->{index}", $bridges);
1049 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
1050 } elsif ($drive->{interface
} eq 'scsi') {
1051 $maxdev = ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi') ?
256 : 7;
1052 my $controller = int($drive->{index} / $maxdev);
1053 my $unit = $drive->{index} % $maxdev;
1054 my $devicetype = 'hd';
1056 if (drive_is_cdrom
($drive)) {
1059 if ($drive->{file
} =~ m
|^/|) {
1060 $path = $drive->{file
};
1062 $path = PVE
::Storage
::path
($storecfg, $drive->{file
});
1065 if($path =~ m/^iscsi\:\/\
//){
1066 $devicetype = 'generic';
1068 if (my $info = path_is_scsi
($path)) {
1069 if ($info->{type
} == 0) {
1070 $devicetype = 'block';
1071 } elsif ($info->{type
} == 1) { # tape
1072 $devicetype = 'generic';
1078 if (!$conf->{scsihw
} || $conf->{scsihw
} eq 'lsi'){
1079 $device = "scsi-$devicetype,bus=scsihw$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}" if !$conf->{scsihw
} || $conf->{scsihw
} eq 'lsi';
1081 $device = "scsi-$devicetype,bus=scsihw$controller.0,channel=0,scsi-id=0,lun=$drive->{index},drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1084 } elsif ($drive->{interface
} eq 'ide'){
1086 my $controller = int($drive->{index} / $maxdev);
1087 my $unit = $drive->{index} % $maxdev;
1088 my $devicetype = ($drive->{media
} && $drive->{media
} eq 'cdrom') ?
"cd" : "hd";
1090 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1091 } elsif ($drive->{interface
} eq 'sata'){
1092 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
1093 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1094 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1095 } elsif ($drive->{interface
} eq 'usb') {
1097 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1099 die "unsupported interface type";
1102 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex
};
1107 sub print_drive_full
{
1108 my ($storecfg, $vmid, $drive) = @_;
1111 foreach my $o (@qemu_drive_options) {
1112 next if $o eq 'bootindex';
1113 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
1116 foreach my $o (qw(bps bps_rd bps_wr)) {
1117 my $v = $drive->{"m$o"};
1118 $opts .= ",$o=" . int($v*1024*1024) if $v;
1121 # use linux-aio by default (qemu default is threads)
1122 $opts .= ",aio=native" if !$drive->{aio
};
1125 my $volid = $drive->{file
};
1126 if (drive_is_cdrom
($drive)) {
1127 $path = get_iso_path
($storecfg, $vmid, $volid);
1129 if ($volid =~ m
|^/|) {
1132 $path = PVE
::Storage
::path
($storecfg, $volid);
1136 $opts .= ",cache=none" if !$drive->{cache
} && !drive_is_cdrom
($drive);
1138 my $pathinfo = $path ?
"file=$path," : '';
1140 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1143 sub print_netdevice_full
{
1144 my ($vmid, $conf, $net, $netid, $bridges) = @_;
1146 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
1148 my $device = $net->{model
};
1149 if ($net->{model
} eq 'virtio') {
1150 $device = 'virtio-net-pci';
1153 # qemu > 0.15 always try to boot from network - we disable that by
1154 # not loading the pxe rom file
1155 my $extra = ($bootorder !~ m/n/) ?
"romfile=," : '';
1156 my $pciaddr = print_pci_addr
("$netid", $bridges);
1157 my $tmpstr = "$device,${extra}mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
1158 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex
} ;
1162 sub print_netdev_full
{
1163 my ($vmid, $conf, $net, $netid) = @_;
1166 if ($netid =~ m/^net(\d+)$/) {
1170 die "got strange net id '$i'\n" if $i >= ${MAX_NETS
};
1172 my $ifname = "tap${vmid}i$i";
1174 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1175 die "interface name '$ifname' is too long (max 15 character)\n"
1176 if length($ifname) >= 16;
1178 my $vhostparam = '';
1179 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model
} eq 'virtio';
1181 my $vmname = $conf->{name
} || "vm$vmid";
1183 if ($net->{bridge
}) {
1184 return "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge$vhostparam";
1186 return "type=user,id=$netid,hostname=$vmname";
1190 sub drive_is_cdrom
{
1193 return $drive && $drive->{media
} && ($drive->{media
} eq 'cdrom');
1200 return undef if !$value;
1204 if ($value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/) {
1205 $res->{pciid
} = $value;
1213 # netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1219 foreach my $kvp (split(/,/, $data)) {
1221 if ($kvp =~ m/^(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
1223 my $mac = defined($3) ?
uc($3) : PVE
::Tools
::random_ether_addr
();
1224 $res->{model
} = $model;
1225 $res->{macaddr
} = $mac;
1226 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1227 $res->{bridge
} = $1;
1228 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1230 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1238 return undef if !$res->{model
};
1246 my $res = "$net->{model}";
1247 $res .= "=$net->{macaddr}" if $net->{macaddr
};
1248 $res .= ",bridge=$net->{bridge}" if $net->{bridge
};
1249 $res .= ",rate=$net->{rate}" if $net->{rate
};
1250 $res .= ",tag=$net->{tag}" if $net->{tag
};
1255 sub add_random_macs
{
1256 my ($settings) = @_;
1258 foreach my $opt (keys %$settings) {
1259 next if $opt !~ m/^net(\d+)$/;
1260 my $net = parse_net
($settings->{$opt});
1262 $settings->{$opt} = print_net
($net);
1266 sub add_unused_volume
{
1267 my ($config, $volid) = @_;
1270 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1271 my $test = "unused$ind";
1272 if (my $vid = $config->{$test}) {
1273 return if $vid eq $volid; # do not add duplicates
1279 die "To many unused volume - please delete them first.\n" if !$key;
1281 $config->{$key} = $volid;
1286 PVE
::JSONSchema
::register_format
('pve-qm-bootdisk', \
&verify_bootdisk
);
1287 sub verify_bootdisk
{
1288 my ($value, $noerr) = @_;
1290 return $value if valid_drivename
($value);
1292 return undef if $noerr;
1294 die "invalid boot disk '$value'\n";
1297 PVE
::JSONSchema
::register_format
('pve-qm-net', \
&verify_net
);
1299 my ($value, $noerr) = @_;
1301 return $value if parse_net
($value);
1303 return undef if $noerr;
1305 die "unable to parse network options\n";
1308 PVE
::JSONSchema
::register_format
('pve-qm-drive', \
&verify_drive
);
1310 my ($value, $noerr) = @_;
1312 return $value if parse_drive
(undef, $value);
1314 return undef if $noerr;
1316 die "unable to parse drive options\n";
1319 PVE
::JSONSchema
::register_format
('pve-qm-hostpci', \
&verify_hostpci
);
1320 sub verify_hostpci
{
1321 my ($value, $noerr) = @_;
1323 return $value if parse_hostpci
($value);
1325 return undef if $noerr;
1327 die "unable to parse pci id\n";
1330 PVE
::JSONSchema
::register_format
('pve-qm-watchdog', \
&verify_watchdog
);
1331 sub verify_watchdog
{
1332 my ($value, $noerr) = @_;
1334 return $value if parse_watchdog
($value);
1336 return undef if $noerr;
1338 die "unable to parse watchdog options\n";
1341 sub parse_watchdog
{
1344 return undef if !$value;
1348 foreach my $p (split(/,/, $value)) {
1349 next if $p =~ m/^\s*$/;
1351 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1353 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1354 $res->{action
} = $2;
1363 PVE
::JSONSchema
::register_format
('pve-qm-startup', \
&verify_startup
);
1364 sub verify_startup
{
1365 my ($value, $noerr) = @_;
1367 return $value if parse_startup
($value);
1369 return undef if $noerr;
1371 die "unable to parse startup options\n";
1377 return undef if !$value;
1381 foreach my $p (split(/,/, $value)) {
1382 next if $p =~ m/^\s*$/;
1384 if ($p =~ m/^(order=)?(\d+)$/) {
1386 } elsif ($p =~ m/^up=(\d+)$/) {
1388 } elsif ($p =~ m/^down=(\d+)$/) {
1398 sub parse_usb_device
{
1401 return undef if !$value;
1403 my @dl = split(/,/, $value);
1407 foreach my $v (@dl) {
1408 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1410 $res->{vendorid
} = $2;
1411 $res->{productid
} = $4;
1412 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1414 $res->{hostbus
} = $1;
1415 $res->{hostport
} = $2;
1416 } elsif ($v =~ m/^spice$/) {
1423 return undef if !$found;
1428 PVE
::JSONSchema
::register_format
('pve-qm-usb-device', \
&verify_usb_device
);
1429 sub verify_usb_device
{
1430 my ($value, $noerr) = @_;
1432 return $value if parse_usb_device
($value);
1434 return undef if $noerr;
1436 die "unable to parse usb device\n";
1439 # add JSON properties for create and set function
1440 sub json_config_properties
{
1443 foreach my $opt (keys %$confdesc) {
1444 next if $opt eq 'parent' || $opt eq 'snaptime' || $opt eq 'vmstate';
1445 $prop->{$opt} = $confdesc->{$opt};
1452 my ($key, $value) = @_;
1454 die "unknown setting '$key'\n" if !$confdesc->{$key};
1456 my $type = $confdesc->{$key}->{type
};
1458 if (!defined($value)) {
1459 die "got undefined value\n";
1462 if ($value =~ m/[\n\r]/) {
1463 die "property contains a line feed\n";
1466 if ($type eq 'boolean') {
1467 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1468 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1469 die "type check ('boolean') failed - got '$value'\n";
1470 } elsif ($type eq 'integer') {
1471 return int($1) if $value =~ m/^(\d+)$/;
1472 die "type check ('integer') failed - got '$value'\n";
1473 } elsif ($type eq 'number') {
1474 return $value if $value =~ m/^(\d+)(\.\d+)?$/;
1475 die "type check ('number') failed - got '$value'\n";
1476 } elsif ($type eq 'string') {
1477 if (my $fmt = $confdesc->{$key}->{format
}) {
1478 if ($fmt eq 'pve-qm-drive') {
1479 # special case - we need to pass $key to parse_drive()
1480 my $drive = parse_drive
($key, $value);
1481 return $value if $drive;
1482 die "unable to parse drive options\n";
1484 PVE
::JSONSchema
::check_format
($fmt, $value);
1487 $value =~ s/^\"(.*)\"$/$1/;
1490 die "internal error"
1494 sub lock_config_full
{
1495 my ($vmid, $timeout, $code, @param) = @_;
1497 my $filename = config_file_lock
($vmid);
1499 my $res = lock_file
($filename, $timeout, $code, @param);
1506 sub lock_config_mode
{
1507 my ($vmid, $timeout, $shared, $code, @param) = @_;
1509 my $filename = config_file_lock
($vmid);
1511 my $res = lock_file_full
($filename, $timeout, $shared, $code, @param);
1519 my ($vmid, $code, @param) = @_;
1521 return lock_config_full
($vmid, 10, $code, @param);
1524 sub cfs_config_path
{
1525 my ($vmid, $node) = @_;
1527 $node = $nodename if !$node;
1528 return "nodes/$node/qemu-server/$vmid.conf";
1531 sub check_iommu_support
{
1532 #fixme : need to check IOMMU support
1533 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1541 my ($vmid, $node) = @_;
1543 my $cfspath = cfs_config_path
($vmid, $node);
1544 return "/etc/pve/$cfspath";
1547 sub config_file_lock
{
1550 return "$lock_dir/lock-$vmid.conf";
1556 my $conf = config_file
($vmid);
1557 utime undef, undef, $conf;
1561 my ($storecfg, $vmid, $keep_empty_config) = @_;
1563 my $conffile = config_file
($vmid);
1565 my $conf = load_config
($vmid);
1569 # only remove disks owned by this VM
1570 foreach_drive
($conf, sub {
1571 my ($ds, $drive) = @_;
1573 return if drive_is_cdrom
($drive);
1575 my $volid = $drive->{file
};
1577 return if !$volid || $volid =~ m
|^/|;
1579 my ($path, $owner) = PVE
::Storage
::path
($storecfg, $volid);
1580 return if !$path || !$owner || ($owner != $vmid);
1582 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1585 if ($keep_empty_config) {
1586 PVE
::Tools
::file_set_contents
($conffile, "memory: 128\n");
1591 # also remove unused disk
1593 my $dl = PVE
::Storage
::vdisk_list
($storecfg, undef, $vmid);
1596 PVE
::Storage
::foreach_volid
($dl, sub {
1597 my ($volid, $sid, $volname, $d) = @_;
1598 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1608 my ($vmid, $node) = @_;
1610 my $cfspath = cfs_config_path
($vmid, $node);
1612 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath);
1614 die "no such VM ('$vmid')\n" if !defined($conf);
1619 sub parse_vm_config
{
1620 my ($filename, $raw) = @_;
1622 return undef if !defined($raw);
1625 digest
=> Digest
::SHA
::sha1_hex
($raw),
1629 $filename =~ m
|/qemu-server/(\d
+)\
.conf
$|
1630 || die "got strange filename '$filename'";
1637 my @lines = split(/\n/, $raw);
1638 foreach my $line (@lines) {
1639 next if $line =~ m/^\s*$/;
1641 if ($line =~ m/^\[([a-z][a-z0-9_\-]+)\]\s*$/i) {
1643 $conf->{description
} = $descr if $descr;
1645 $conf = $res->{snapshots
}->{$snapname} = {};
1649 if ($line =~ m/^\#(.*)\s*$/) {
1650 $descr .= PVE
::Tools
::decode_text
($1) . "\n";
1654 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
1655 $descr .= PVE
::Tools
::decode_text
($2);
1656 } elsif ($line =~ m/snapstate:\s*(prepare|delete)\s*$/) {
1657 $conf->{snapstate
} = $1;
1658 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1661 $conf->{$key} = $value;
1662 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1665 eval { $value = check_type
($key, $value); };
1667 warn "vm $vmid - unable to parse value of '$key' - $@";
1669 my $fmt = $confdesc->{$key}->{format
};
1670 if ($fmt && $fmt eq 'pve-qm-drive') {
1671 my $v = parse_drive
($key, $value);
1672 if (my $volid = filename_to_volume_id
($vmid, $v->{file
}, $v->{media
})) {
1673 $v->{file
} = $volid;
1674 $value = print_drive
($vmid, $v);
1676 warn "vm $vmid - unable to parse value of '$key'\n";
1681 if ($key eq 'cdrom') {
1682 $conf->{ide2
} = $value;
1684 $conf->{$key} = $value;
1690 $conf->{description
} = $descr if $descr;
1692 delete $res->{snapstate
}; # just to be sure
1697 sub write_vm_config
{
1698 my ($filename, $conf) = @_;
1700 delete $conf->{snapstate
}; # just to be sure
1702 if ($conf->{cdrom
}) {
1703 die "option ide2 conflicts with cdrom\n" if $conf->{ide2
};
1704 $conf->{ide2
} = $conf->{cdrom
};
1705 delete $conf->{cdrom
};
1708 # we do not use 'smp' any longer
1709 if ($conf->{sockets
}) {
1710 delete $conf->{smp
};
1711 } elsif ($conf->{smp
}) {
1712 $conf->{sockets
} = $conf->{smp
};
1713 delete $conf->{cores
};
1714 delete $conf->{smp
};
1717 my $used_volids = {};
1719 my $cleanup_config = sub {
1720 my ($cref, $snapname) = @_;
1722 foreach my $key (keys %$cref) {
1723 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots' ||
1724 $key eq 'snapstate';
1725 my $value = $cref->{$key};
1726 eval { $value = check_type
($key, $value); };
1727 die "unable to parse value of '$key' - $@" if $@;
1729 $cref->{$key} = $value;
1731 if (!$snapname && valid_drivename
($key)) {
1732 my $drive = parse_drive
($key, $value);
1733 $used_volids->{$drive->{file
}} = 1 if $drive && $drive->{file
};
1738 &$cleanup_config($conf);
1739 foreach my $snapname (keys %{$conf->{snapshots
}}) {
1740 &$cleanup_config($conf->{snapshots
}->{$snapname}, $snapname);
1743 # remove 'unusedX' settings if we re-add a volume
1744 foreach my $key (keys %$conf) {
1745 my $value = $conf->{$key};
1746 if ($key =~ m/^unused/ && $used_volids->{$value}) {
1747 delete $conf->{$key};
1751 my $generate_raw_config = sub {
1756 # add description as comment to top of file
1757 my $descr = $conf->{description
} || '';
1758 foreach my $cl (split(/\n/, $descr)) {
1759 $raw .= '#' . PVE
::Tools
::encode_text
($cl) . "\n";
1762 foreach my $key (sort keys %$conf) {
1763 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots';
1764 $raw .= "$key: $conf->{$key}\n";
1769 my $raw = &$generate_raw_config($conf);
1770 foreach my $snapname (sort keys %{$conf->{snapshots
}}) {
1771 $raw .= "\n[$snapname]\n";
1772 $raw .= &$generate_raw_config($conf->{snapshots
}->{$snapname});
1778 sub update_config_nolock
{
1779 my ($vmid, $conf, $skiplock) = @_;
1781 check_lock
($conf) if !$skiplock;
1783 my $cfspath = cfs_config_path
($vmid);
1785 PVE
::Cluster
::cfs_write_file
($cfspath, $conf);
1789 my ($vmid, $conf, $skiplock) = @_;
1791 lock_config
($vmid, &update_config_nolock
, $conf, $skiplock);
1798 # we use static defaults from our JSON schema configuration
1799 foreach my $key (keys %$confdesc) {
1800 if (defined(my $default = $confdesc->{$key}->{default})) {
1801 $res->{$key} = $default;
1805 my $conf = PVE
::Cluster
::cfs_read_file
('datacenter.cfg');
1806 $res->{keyboard
} = $conf->{keyboard
} if $conf->{keyboard
};
1812 my $vmlist = PVE
::Cluster
::get_vmlist
();
1814 return $res if !$vmlist || !$vmlist->{ids
};
1815 my $ids = $vmlist->{ids
};
1817 foreach my $vmid (keys %$ids) {
1818 my $d = $ids->{$vmid};
1819 next if !$d->{node
} || $d->{node
} ne $nodename;
1820 next if !$d->{type
} || $d->{type
} ne 'qemu';
1821 $res->{$vmid}->{exists} = 1;
1826 # test if VM uses local resources (to prevent migration)
1827 sub check_local_resources
{
1828 my ($conf, $noerr) = @_;
1832 $loc_res = 1 if $conf->{hostusb
}; # old syntax
1833 $loc_res = 1 if $conf->{hostpci
}; # old syntax
1835 foreach my $k (keys %$conf) {
1836 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
1839 die "VM uses local resources\n" if $loc_res && !$noerr;
1844 # check if used storages are available on all nodes (use by migrate)
1845 sub check_storage_availability
{
1846 my ($storecfg, $conf, $node) = @_;
1848 foreach_drive
($conf, sub {
1849 my ($ds, $drive) = @_;
1851 my $volid = $drive->{file
};
1854 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
1857 # check if storage is available on both nodes
1858 my $scfg = PVE
::Storage
::storage_check_node
($storecfg, $sid);
1859 PVE
::Storage
::storage_check_node
($storecfg, $sid, $node);
1863 # list nodes where all VM images are available (used by has_feature API)
1865 my ($conf, $storecfg) = @_;
1867 my $nodelist = PVE
::Cluster
::get_nodelist
();
1868 my $nodehash = { map { $_ => 1 } @$nodelist };
1869 my $nodename = PVE
::INotify
::nodename
();
1871 foreach_drive
($conf, sub {
1872 my ($ds, $drive) = @_;
1874 my $volid = $drive->{file
};
1877 my ($storeid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
1879 my $scfg = PVE
::Storage
::storage_config
($storecfg, $storeid);
1880 if ($scfg->{disable
}) {
1882 } elsif (my $avail = $scfg->{nodes
}) {
1883 foreach my $node (keys %$nodehash) {
1884 delete $nodehash->{$node} if !$avail->{$node};
1886 } elsif (!$scfg->{shared
}) {
1887 foreach my $node (keys %$nodehash) {
1888 delete $nodehash->{$node} if $node ne $nodename
1900 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1904 my ($pidfile, $pid) = @_;
1906 my $fh = IO
::File-
>new("/proc/$pid/cmdline", "r");
1910 return undef if !$line;
1911 my @param = split(/\0/, $line);
1913 my $cmd = $param[0];
1914 return if !$cmd || ($cmd !~ m
|kvm
$| && $cmd !~ m
|qemu-system-x86_64
$|);
1916 for (my $i = 0; $i < scalar (@param); $i++) {
1919 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1920 my $p = $param[$i+1];
1921 return 1 if $p && ($p eq $pidfile);
1930 my ($vmid, $nocheck, $node) = @_;
1932 my $filename = config_file
($vmid, $node);
1934 die "unable to find configuration file for VM $vmid - no such machine\n"
1935 if !$nocheck && ! -f
$filename;
1937 my $pidfile = pidfile_name
($vmid);
1939 if (my $fd = IO
::File-
>new("<$pidfile")) {
1944 my $mtime = $st->mtime;
1945 if ($mtime > time()) {
1946 warn "file '$filename' modified in future\n";
1949 if ($line =~ m/^(\d+)$/) {
1951 if (check_cmdline
($pidfile, $pid)) {
1952 if (my $pinfo = PVE
::ProcFSTools
::check_process_running
($pid)) {
1964 my $vzlist = config_list
();
1966 my $fd = IO
::Dir-
>new($var_run_tmpdir) || return $vzlist;
1968 while (defined(my $de = $fd->read)) {
1969 next if $de !~ m/^(\d+)\.pid$/;
1971 next if !defined($vzlist->{$vmid});
1972 if (my $pid = check_running
($vmid)) {
1973 $vzlist->{$vmid}->{pid
} = $pid;
1981 my ($storecfg, $conf) = @_;
1983 my $bootdisk = $conf->{bootdisk
};
1984 return undef if !$bootdisk;
1985 return undef if !valid_drivename
($bootdisk);
1987 return undef if !$conf->{$bootdisk};
1989 my $drive = parse_drive
($bootdisk, $conf->{$bootdisk});
1990 return undef if !defined($drive);
1992 return undef if drive_is_cdrom
($drive);
1994 my $volid = $drive->{file
};
1995 return undef if !$volid;
1997 return $drive->{size
};
2000 my $last_proc_pid_stat;
2002 # get VM status information
2003 # This must be fast and should not block ($full == false)
2004 # We only query KVM using QMP if $full == true (this can be slow)
2006 my ($opt_vmid, $full) = @_;
2010 my $storecfg = PVE
::Storage
::config
();
2012 my $list = vzlist
();
2013 my ($uptime) = PVE
::ProcFSTools
::read_proc_uptime
(1);
2015 my $cpucount = $cpuinfo->{cpus
} || 1;
2017 foreach my $vmid (keys %$list) {
2018 next if $opt_vmid && ($vmid ne $opt_vmid);
2020 my $cfspath = cfs_config_path
($vmid);
2021 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath) || {};
2024 $d->{pid
} = $list->{$vmid}->{pid
};
2026 # fixme: better status?
2027 $d->{status
} = $list->{$vmid}->{pid
} ?
'running' : 'stopped';
2029 my $size = disksize
($storecfg, $conf);
2030 if (defined($size)) {
2031 $d->{disk
} = 0; # no info available
2032 $d->{maxdisk
} = $size;
2038 $d->{cpus
} = ($conf->{sockets
} || 1) * ($conf->{cores
} || 1);
2039 $d->{cpus
} = $cpucount if $d->{cpus
} > $cpucount;
2041 $d->{name
} = $conf->{name
} || "VM $vmid";
2042 $d->{maxmem
} = $conf->{memory
} ?
$conf->{memory
}*(1024*1024) : 0;
2044 if ($conf->{balloon
}) {
2045 $d->{balloon_min
} = $conf->{balloon
}*(1024*1024);
2046 $d->{shares
} = defined($conf->{shares
}) ?
$conf->{shares
} : 1000;
2057 $d->{diskwrite
} = 0;
2059 $d->{template
} = is_template
($conf);
2064 my $netdev = PVE
::ProcFSTools
::read_proc_net_dev
();
2065 foreach my $dev (keys %$netdev) {
2066 next if $dev !~ m/^tap([1-9]\d*)i/;
2068 my $d = $res->{$vmid};
2071 $d->{netout
} += $netdev->{$dev}->{receive
};
2072 $d->{netin
} += $netdev->{$dev}->{transmit
};
2075 my $ctime = gettimeofday
;
2077 foreach my $vmid (keys %$list) {
2079 my $d = $res->{$vmid};
2080 my $pid = $d->{pid
};
2083 my $pstat = PVE
::ProcFSTools
::read_proc_pid_stat
($pid);
2084 next if !$pstat; # not running
2086 my $used = $pstat->{utime} + $pstat->{stime
};
2088 $d->{uptime
} = int(($uptime - $pstat->{starttime
})/$cpuinfo->{user_hz
});
2090 if ($pstat->{vsize
}) {
2091 $d->{mem
} = int(($pstat->{rss
}/$pstat->{vsize
})*$d->{maxmem
});
2094 my $old = $last_proc_pid_stat->{$pid};
2096 $last_proc_pid_stat->{$pid} = {
2104 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz
};
2106 if ($dtime > 1000) {
2107 my $dutime = $used - $old->{used
};
2109 $d->{cpu
} = (($dutime/$dtime)* $cpucount) / $d->{cpus
};
2110 $last_proc_pid_stat->{$pid} = {
2116 $d->{cpu
} = $old->{cpu
};
2120 return $res if !$full;
2122 my $qmpclient = PVE
::QMPClient-
>new();
2124 my $ballooncb = sub {
2125 my ($vmid, $resp) = @_;
2127 my $info = $resp->{'return'};
2128 return if !$info->{max_mem
};
2130 my $d = $res->{$vmid};
2132 # use memory assigned to VM
2133 $d->{maxmem
} = $info->{max_mem
};
2134 $d->{balloon
} = $info->{actual
};
2136 if (defined($info->{total_mem
}) && defined($info->{free_mem
})) {
2137 $d->{mem
} = $info->{total_mem
} - $info->{free_mem
};
2138 $d->{freemem
} = $info->{free_mem
};
2143 my $blockstatscb = sub {
2144 my ($vmid, $resp) = @_;
2145 my $data = $resp->{'return'} || [];
2146 my $totalrdbytes = 0;
2147 my $totalwrbytes = 0;
2148 for my $blockstat (@$data) {
2149 $totalrdbytes = $totalrdbytes + $blockstat->{stats
}->{rd_bytes
};
2150 $totalwrbytes = $totalwrbytes + $blockstat->{stats
}->{wr_bytes
};
2152 $res->{$vmid}->{diskread
} = $totalrdbytes;
2153 $res->{$vmid}->{diskwrite
} = $totalwrbytes;
2156 my $statuscb = sub {
2157 my ($vmid, $resp) = @_;
2159 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
2160 # this fails if ballon driver is not loaded, so this must be
2161 # the last commnand (following command are aborted if this fails).
2162 $qmpclient->queue_cmd($vmid, $ballooncb, 'query-balloon');
2164 my $status = 'unknown';
2165 if (!defined($status = $resp->{'return'}->{status
})) {
2166 warn "unable to get VM status\n";
2170 $res->{$vmid}->{qmpstatus
} = $resp->{'return'}->{status
};
2173 foreach my $vmid (keys %$list) {
2174 next if $opt_vmid && ($vmid ne $opt_vmid);
2175 next if !$res->{$vmid}->{pid
}; # not running
2176 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2179 $qmpclient->queue_execute();
2181 foreach my $vmid (keys %$list) {
2182 next if $opt_vmid && ($vmid ne $opt_vmid);
2183 $res->{$vmid}->{qmpstatus
} = $res->{$vmid}->{status
} if !$res->{$vmid}->{qmpstatus
};
2190 my ($conf, $func) = @_;
2192 foreach my $ds (keys %$conf) {
2193 next if !valid_drivename
($ds);
2195 my $drive = parse_drive
($ds, $conf->{$ds});
2198 &$func($ds, $drive);
2203 my ($conf, $func) = @_;
2207 my $test_volid = sub {
2208 my ($volid, $is_cdrom) = @_;
2212 $volhash->{$volid} = $is_cdrom || 0;
2215 foreach_drive
($conf, sub {
2216 my ($ds, $drive) = @_;
2217 &$test_volid($drive->{file
}, drive_is_cdrom
($drive));
2220 foreach my $snapname (keys %{$conf->{snapshots
}}) {
2221 my $snap = $conf->{snapshots
}->{$snapname};
2222 &$test_volid($snap->{vmstate
}, 0);
2223 foreach_drive
($snap, sub {
2224 my ($ds, $drive) = @_;
2225 &$test_volid($drive->{file
}, drive_is_cdrom
($drive));
2229 foreach my $volid (keys %$volhash) {
2230 &$func($volid, $volhash->{$volid});
2234 sub config_to_command
{
2235 my ($storecfg, $vmid, $conf, $defaults, $forcemachine) = @_;
2238 my $globalFlags = [];
2239 my $machineFlags = [];
2245 my $kvmver = kvm_user_version
();
2246 my $vernum = 0; # unknown
2247 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2248 $vernum = $1*1000000+$2*1000;
2249 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
2250 $vernum = $1*1000000+$2*1000+$3;
2253 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
2255 my $have_ovz = -f
'/proc/vz/vestat';
2257 push @$cmd, '/usr/bin/kvm';
2259 push @$cmd, '-id', $vmid;
2263 my $qmpsocket = qmp_socket
($vmid);
2264 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2265 push @$cmd, '-mon', "chardev=qmp,mode=control";
2267 my $socket = vnc_socket
($vmid);
2268 push @$cmd, '-vnc', "unix:$socket,x509,password";
2270 push @$cmd, '-pidfile' , pidfile_name
($vmid);
2272 push @$cmd, '-daemonize';
2274 $pciaddr = print_pci_addr
("piix3", $bridges);
2275 push @$devices, '-device', "piix3-usb-uhci,id=uhci$pciaddr.0x2";
2278 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2279 next if !$conf->{"usb$i"};
2282 # include usb device config
2283 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
2285 # enable absolute mouse coordinates (needed by vnc)
2286 my $tablet = defined($conf->{tablet
}) ?
$conf->{tablet
} : $defaults->{tablet
};
2287 push @$devices, '-device', 'usb-tablet,id=tablet,bus=uhci.0,port=1' if $tablet;
2290 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2291 my $d = parse_hostpci
($conf->{"hostpci$i"});
2293 $pciaddr = print_pci_addr
("hostpci$i", $bridges);
2294 push @$devices, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
2298 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2299 my $d = parse_usb_device
($conf->{"usb$i"});
2301 if ($d->{vendorid
} && $d->{productid
}) {
2302 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
2303 } elsif (defined($d->{hostbus
}) && defined($d->{hostport
})) {
2304 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
2305 } elsif ($d->{spice
}) {
2306 # usb redir support for spice
2307 push @$devices, '-chardev', "spicevmc,id=usbredirchardev$i,name=usbredir";
2308 push @$devices, '-device', "usb-redir,chardev=usbredirchardev$i,id=usbredirdev$i,bus=ehci.0";
2313 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
2314 if (my $path = $conf->{"serial$i"}) {
2315 die "no such serial device\n" if ! -c
$path;
2316 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2317 push @$devices, '-device', "isa-serial,chardev=serial$i";
2322 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
2323 if (my $path = $conf->{"parallel$i"}) {
2324 die "no such parallel device\n" if ! -c
$path;
2325 push @$devices, '-chardev', "parport,id=parallel$i,path=$path";
2326 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
2330 my $vmname = $conf->{name
} || "vm$vmid";
2332 push @$cmd, '-name', $vmname;
2335 $sockets = $conf->{smp
} if $conf->{smp
}; # old style - no longer iused
2336 $sockets = $conf->{sockets
} if $conf->{sockets
};
2338 my $cores = $conf->{cores
} || 1;
2339 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2341 push @$cmd, '-nodefaults';
2343 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
2345 my $bootindex_hash = {};
2347 foreach my $o (split(//, $bootorder)) {
2348 $bootindex_hash->{$o} = $i*100;
2352 push @$cmd, '-boot', "menu=on";
2354 push @$cmd, '-no-acpi' if defined($conf->{acpi
}) && $conf->{acpi
} == 0;
2356 push @$cmd, '-no-reboot' if defined($conf->{reboot
}) && $conf->{reboot
} == 0;
2358 my $vga = $conf->{vga
};
2360 if ($conf->{ostype
} && ($conf->{ostype
} eq 'win8' || $conf->{ostype
} eq 'win7' || $conf->{ostype
} eq 'w2k8')) {
2367 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2370 my $tdf = defined($conf->{tdf
}) ?
$conf->{tdf
} : $defaults->{tdf
};
2372 my $nokvm = defined($conf->{kvm
}) && $conf->{kvm
} == 0 ?
1 : 0;
2373 my $useLocaltime = $conf->{localtime};
2375 if (my $ost = $conf->{ostype
}) {
2376 # other, wxp, w2k, w2k3, w2k8, wvista, win7, win8, l24, l26
2378 if ($ost =~ m/^w/) { # windows
2379 $useLocaltime = 1 if !defined($conf->{localtime});
2381 # use time drift fix when acpi is enabled
2382 if (!(defined($conf->{acpi
}) && $conf->{acpi
} == 0)) {
2383 $tdf = 1 if !defined($conf->{tdf
});
2387 if ($ost eq 'win7' || $ost eq 'win8' || $ost eq 'w2k8' ||
2389 push @$globalFlags, 'kvm-pit.lost_tick_policy=discard';
2390 push @$cmd, '-no-hpet';
2391 #push @$cpuFlags , 'hv_vapic" if !$nokvm; #fixme, my win2008R2 hang at boot with this
2392 push @$cpuFlags , 'hv_spinlocks=0xffff' if !$nokvm;
2395 if ($ost eq 'win7' || $ost eq 'win8') {
2396 push @$cpuFlags , 'hv_relaxed' if !$nokvm;
2400 push @$rtcFlags, 'driftfix=slew' if $tdf;
2403 push @$machineFlags, 'accel=tcg';
2405 die "No accelerator found!\n" if !$cpuinfo->{hvm
};
2408 my $machine_type = $forcemachine || $conf->{machine
};
2409 if ($machine_type) {
2410 push @$machineFlags, "type=${machine_type}";
2413 if ($conf->{startdate
}) {
2414 push @$rtcFlags, "base=$conf->{startdate}";
2415 } elsif ($useLocaltime) {
2416 push @$rtcFlags, 'base=localtime';
2419 my $cpu = $nokvm ?
"qemu64" : "kvm64";
2420 $cpu = $conf->{cpu
} if $conf->{cpu
};
2422 push @$cpuFlags , '+x2apic' if !$nokvm;
2424 push @$cpuFlags, '+sep' if $cpu eq 'kvm64' || $cpu eq 'kvm32';
2426 $cpu .= "," . join(',', @$cpuFlags) if scalar(@$cpuFlags);
2428 push @$cmd, '-cpu', $cpu;
2430 push @$cmd, '-S' if $conf->{freeze
};
2432 # set keyboard layout
2433 my $kb = $conf->{keyboard
} || $defaults->{keyboard
};
2434 push @$cmd, '-k', $kb if $kb;
2437 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2438 #push @$cmd, '-soundhw', 'es1370';
2439 #push @$cmd, '-soundhw', $soundhw if $soundhw;
2441 if($conf->{agent
}) {
2442 my $qgasocket = qga_socket
($vmid);
2443 my $pciaddr = print_pci_addr
("qga0", $bridges);
2444 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
2445 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
2446 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
2449 if ($vga eq 'qxl') {
2450 my $pciaddr = print_pci_addr
("spice", $bridges);
2452 my $x509 = "x509-key-file=/etc/pve/local/pve-ssl.key" .
2453 ",x509-cert-file=/etc/pve/local/pve-ssl.pem" .
2454 ",x509-cacert-file=/etc/pve/pve-root-ca.pem";
2456 my $port = PVE
::Tools
::next_unused_port
(61000, 61099);
2458 push @$cmd, '-spice', "tls-port=$port,addr=127.0.0.1,$x509,tls-ciphers=DES-CBC3-SHA";
2461 push @$cmd, '-device', "virtio-serial,id=spice$pciaddr";
2462 push @$cmd, '-chardev', "spicevmc,id=vdagent,name=vdagent";
2463 push @$cmd, '-device', "virtserialport,chardev=vdagent,name=com.redhat.spice.0";
2466 # enable balloon by default, unless explicitly disabled
2467 if (!defined($conf->{balloon
}) || $conf->{balloon
}) {
2468 $pciaddr = print_pci_addr
("balloon0", $bridges);
2469 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr";
2472 if ($conf->{watchdog
}) {
2473 my $wdopts = parse_watchdog
($conf->{watchdog
});
2474 $pciaddr = print_pci_addr
("watchdog", $bridges);
2475 my $watchdog = $wdopts->{model
} || 'i6300esb';
2476 push @$devices, '-device', "$watchdog$pciaddr";
2477 push @$devices, '-watchdog-action', $wdopts->{action
} if $wdopts->{action
};
2481 my $scsicontroller = {};
2482 my $ahcicontroller = {};
2483 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : $defaults->{scsihw
};
2485 foreach_drive
($conf, sub {
2486 my ($ds, $drive) = @_;
2488 if (PVE
::Storage
::parse_volume_id
($drive->{file
}, 1)) {
2489 push @$vollist, $drive->{file
};
2492 $use_virtio = 1 if $ds =~ m/^virtio/;
2494 if (drive_is_cdrom
($drive)) {
2495 if ($bootindex_hash->{d
}) {
2496 $drive->{bootindex
} = $bootindex_hash->{d
};
2497 $bootindex_hash->{d
} += 1;
2500 if ($bootindex_hash->{c
}) {
2501 $drive->{bootindex
} = $bootindex_hash->{c
} if $conf->{bootdisk
} && ($conf->{bootdisk
} eq $ds);
2502 $bootindex_hash->{c
} += 1;
2506 if ($drive->{interface
} eq 'scsi') {
2508 my $maxdev = ($scsihw ne 'lsi') ?
256 : 7;
2509 my $controller = int($drive->{index} / $maxdev);
2510 $pciaddr = print_pci_addr
("scsihw$controller", $bridges);
2511 push @$devices, '-device', "$scsihw,id=scsihw$controller$pciaddr" if !$scsicontroller->{$controller};
2512 $scsicontroller->{$controller}=1;
2515 if ($drive->{interface
} eq 'sata') {
2516 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
2517 $pciaddr = print_pci_addr
("ahci$controller", $bridges);
2518 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
2519 $ahcicontroller->{$controller}=1;
2522 push @$devices, '-drive',print_drive_full
($storecfg, $vmid, $drive);
2523 push @$devices, '-device',print_drivedevice_full
($storecfg, $conf, $vmid, $drive, $bridges);
2526 push @$cmd, '-m', $conf->{memory
} || $defaults->{memory
};
2528 for (my $i = 0; $i < $MAX_NETS; $i++) {
2529 next if !$conf->{"net$i"};
2530 my $d = parse_net
($conf->{"net$i"});
2533 $use_virtio = 1 if $d->{model
} eq 'virtio';
2535 if ($bootindex_hash->{n
}) {
2536 $d->{bootindex
} = $bootindex_hash->{n
};
2537 $bootindex_hash->{n
} += 1;
2540 my $netdevfull = print_netdev_full
($vmid,$conf,$d,"net$i");
2541 push @$devices, '-netdev', $netdevfull;
2543 my $netdevicefull = print_netdevice_full
($vmid,$conf,$d,"net$i",$bridges);
2544 push @$devices, '-device', $netdevicefull;
2548 while (my ($k, $v) = each %$bridges) {
2549 $pciaddr = print_pci_addr
("pci.$k");
2550 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
2554 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2555 # when the VM uses virtio devices.
2556 if (!$use_virtio && $have_ovz) {
2558 my $cpuunits = defined($conf->{cpuunits
}) ?
2559 $conf->{cpuunits
} : $defaults->{cpuunits
};
2561 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2563 # fixme: cpulimit is currently ignored
2564 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2568 if ($conf->{args
}) {
2569 my $aa = PVE
::Tools
::split_args
($conf->{args
});
2573 push @$cmd, @$devices;
2574 push @$cmd, '-rtc', join(',', @$rtcFlags)
2575 if scalar(@$rtcFlags);
2576 push @$cmd, '-machine', join(',', @$machineFlags)
2577 if scalar(@$machineFlags);
2578 push @$cmd, '-global', join(',', @$globalFlags)
2579 if scalar(@$globalFlags);
2581 return wantarray ?
($cmd, $vollist) : $cmd;
2586 return "${var_run_tmpdir}/$vmid.vnc";
2592 my $res = vm_mon_cmd
($vmid, 'query-spice');
2594 return $res->{'tls-port'} || $res->{'port'} || die "no spice port\n";
2599 return "${var_run_tmpdir}/$vmid.qmp";
2604 return "${var_run_tmpdir}/$vmid.qga";
2609 return "${var_run_tmpdir}/$vmid.pid";
2612 sub vm_devices_list
{
2615 my $res = vm_mon_cmd
($vmid, 'query-pci');
2618 foreach my $pcibus (@$res) {
2619 foreach my $device (@{$pcibus->{devices
}}) {
2620 next if !$device->{'qdev_id'};
2621 $devices->{$device->{'qdev_id'}} = $device;
2629 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
2631 return 1 if !check_running
($vmid);
2633 if ($deviceid eq 'tablet') {
2634 my $devicefull = "usb-tablet,id=tablet,bus=uhci.0,port=1";
2635 qemu_deviceadd
($vmid, $devicefull);
2639 return 1 if !$conf->{hotplug
};
2641 my $devices_list = vm_devices_list
($vmid);
2642 return 1 if defined($devices_list->{$deviceid});
2644 qemu_bridgeadd
($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
2646 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2647 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2648 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
2649 qemu_deviceadd
($vmid, $devicefull);
2650 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2651 qemu_drivedel
($vmid, $deviceid);
2656 if ($deviceid =~ m/^(scsihw)(\d+)$/) {
2657 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : "lsi";
2658 my $pciaddr = print_pci_addr
($deviceid);
2659 my $devicefull = "$scsihw,id=$deviceid$pciaddr";
2660 qemu_deviceadd
($vmid, $devicefull);
2661 return undef if(!qemu_deviceaddverify
($vmid, $deviceid));
2664 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2665 return 1 if ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi'); #virtio-scsi not yet support hotplug
2666 return undef if !qemu_findorcreatescsihw
($storecfg,$conf, $vmid, $device);
2667 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2668 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
2669 if(!qemu_deviceadd
($vmid, $devicefull)) {
2670 qemu_drivedel
($vmid, $deviceid);
2675 if ($deviceid =~ m/^(net)(\d+)$/) {
2676 return undef if !qemu_netdevadd
($vmid, $conf, $device, $deviceid);
2677 my $netdevicefull = print_netdevice_full
($vmid, $conf, $device, $deviceid);
2678 qemu_deviceadd
($vmid, $netdevicefull);
2679 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2680 qemu_netdevdel
($vmid, $deviceid);
2685 if ($deviceid =~ m/^(pci\.)(\d+)$/) {
2687 my $pciaddr = print_pci_addr
($deviceid);
2688 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
2689 qemu_deviceadd
($vmid, $devicefull);
2690 return undef if !qemu_deviceaddverify
($vmid, $deviceid);
2696 sub vm_deviceunplug
{
2697 my ($vmid, $conf, $deviceid) = @_;
2699 return 1 if !check_running
($vmid);
2701 if ($deviceid eq 'tablet') {
2702 qemu_devicedel
($vmid, $deviceid);
2706 return 1 if !$conf->{hotplug
};
2708 my $devices_list = vm_devices_list
($vmid);
2709 return 1 if !defined($devices_list->{$deviceid});
2711 die "can't unplug bootdisk" if $conf->{bootdisk
} && $conf->{bootdisk
} eq $deviceid;
2713 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2714 qemu_devicedel
($vmid, $deviceid);
2715 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2716 return undef if !qemu_drivedel
($vmid, $deviceid);
2719 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2720 return undef if !qemu_devicedel
($vmid, $deviceid);
2723 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2724 return undef if !qemu_devicedel
($vmid, $deviceid);
2725 return undef if !qemu_drivedel
($vmid, $deviceid);
2728 if ($deviceid =~ m/^(net)(\d+)$/) {
2729 qemu_devicedel
($vmid, $deviceid);
2730 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2731 return undef if !qemu_netdevdel
($vmid, $deviceid);
2737 sub qemu_deviceadd
{
2738 my ($vmid, $devicefull) = @_;
2740 $devicefull = "driver=".$devicefull;
2741 my %options = split(/[=,]/, $devicefull);
2743 vm_mon_cmd
($vmid, "device_add" , %options);
2747 sub qemu_devicedel
{
2748 my($vmid, $deviceid) = @_;
2749 my $ret = vm_mon_cmd
($vmid, "device_del", id
=> $deviceid);
2754 my($storecfg, $vmid, $device) = @_;
2756 my $drive = print_drive_full
($storecfg, $vmid, $device);
2757 my $ret = vm_human_monitor_command
($vmid, "drive_add auto $drive");
2758 # If the command succeeds qemu prints: "OK"
2759 if ($ret !~ m/OK/s) {
2760 syslog
("err", "adding drive failed: $ret");
2767 my($vmid, $deviceid) = @_;
2769 my $ret = vm_human_monitor_command
($vmid, "drive_del drive-$deviceid");
2771 if ($ret =~ m/Device \'.*?\' not found/s) {
2772 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
2774 elsif ($ret ne "") {
2775 syslog
("err", "deleting drive $deviceid failed : $ret");
2781 sub qemu_deviceaddverify
{
2782 my ($vmid,$deviceid) = @_;
2784 for (my $i = 0; $i <= 5; $i++) {
2785 my $devices_list = vm_devices_list
($vmid);
2786 return 1 if defined($devices_list->{$deviceid});
2789 syslog
("err", "error on hotplug device $deviceid");
2794 sub qemu_devicedelverify
{
2795 my ($vmid,$deviceid) = @_;
2797 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2798 for (my $i = 0; $i <= 5; $i++) {
2799 my $devices_list = vm_devices_list
($vmid);
2800 return 1 if !defined($devices_list->{$deviceid});
2803 syslog
("err", "error on hot-unplugging device $deviceid");
2807 sub qemu_findorcreatescsihw
{
2808 my ($storecfg, $conf, $vmid, $device) = @_;
2810 my $maxdev = ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi') ?
256 : 7;
2811 my $controller = int($device->{index} / $maxdev);
2812 my $scsihwid="scsihw$controller";
2813 my $devices_list = vm_devices_list
($vmid);
2815 if(!defined($devices_list->{$scsihwid})) {
2816 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $scsihwid);
2821 sub qemu_bridgeadd
{
2822 my ($storecfg, $conf, $vmid, $device) = @_;
2825 my $bridgeid = undef;
2826 print_pci_addr
($device, $bridges);
2828 while (my ($k, $v) = each %$bridges) {
2831 return if !$bridgeid || $bridgeid < 1;
2832 my $bridge = "pci.$bridgeid";
2833 my $devices_list = vm_devices_list
($vmid);
2835 if(!defined($devices_list->{$bridge})) {
2836 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $bridge);
2841 sub qemu_netdevadd
{
2842 my ($vmid, $conf, $device, $deviceid) = @_;
2844 my $netdev = print_netdev_full
($vmid, $conf, $device, $deviceid);
2845 my %options = split(/[=,]/, $netdev);
2847 vm_mon_cmd
($vmid, "netdev_add", %options);
2851 sub qemu_netdevdel
{
2852 my ($vmid, $deviceid) = @_;
2854 vm_mon_cmd
($vmid, "netdev_del", id
=> $deviceid);
2858 sub qemu_block_set_io_throttle
{
2859 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2861 return if !check_running
($vmid) ;
2863 vm_mon_cmd
($vmid, "block_set_io_throttle", device
=> $deviceid, bps
=> int($bps), bps_rd
=> int($bps_rd), bps_wr
=> int($bps_wr), iops
=> int($iops), iops_rd
=> int($iops_rd), iops_wr
=> int($iops_wr));
2867 # old code, only used to shutdown old VM after update
2869 my ($fh, $timeout) = @_;
2871 my $sel = new IO
::Select
;
2878 while (scalar (@ready = $sel->can_read($timeout))) {
2880 if ($count = $fh->sysread($buf, 8192)) {
2881 if ($buf =~ /^(.*)\(qemu\) $/s) {
2888 if (!defined($count)) {
2895 die "monitor read timeout\n" if !scalar(@ready);
2900 # old code, only used to shutdown old VM after update
2901 sub vm_monitor_command
{
2902 my ($vmid, $cmdstr, $nocheck) = @_;
2907 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
2909 my $sname = "${var_run_tmpdir}/$vmid.mon";
2911 my $sock = IO
::Socket
::UNIX-
>new( Peer
=> $sname ) ||
2912 die "unable to connect to VM $vmid socket - $!\n";
2916 # hack: migrate sometime blocks the monitor (when migrate_downtime
2918 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2919 $timeout = 60*60; # 1 hour
2923 my $data = __read_avail
($sock, $timeout);
2925 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2926 die "got unexpected qemu monitor banner\n";
2929 my $sel = new IO
::Select
;
2932 if (!scalar(my @ready = $sel->can_write($timeout))) {
2933 die "monitor write error - timeout";
2936 my $fullcmd = "$cmdstr\r";
2938 # syslog('info', "VM $vmid monitor command: $cmdstr");
2941 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
2942 die "monitor write error - $!";
2945 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2949 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2950 $timeout = 60*60; # 1 hour
2951 } elsif ($cmdstr =~ m/^(eject|change)/) {
2952 $timeout = 60; # note: cdrom mount command is slow
2954 if ($res = __read_avail
($sock, $timeout)) {
2956 my @lines = split("\r?\n", $res);
2958 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
2960 $res = join("\n", @lines);
2968 syslog
("err", "VM $vmid monitor command failed - $err");
2975 sub qemu_block_resize
{
2976 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
2978 my $running = check_running
($vmid);
2980 return if !PVE
::Storage
::volume_resize
($storecfg, $volid, $size, $running);
2982 return if !$running;
2984 vm_mon_cmd
($vmid, "block_resize", device
=> $deviceid, size
=> int($size));
2988 sub qemu_volume_snapshot
{
2989 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
2991 my $running = check_running
($vmid);
2993 return if !PVE
::Storage
::volume_snapshot
($storecfg, $volid, $snap, $running);
2995 return if !$running;
2997 vm_mon_cmd
($vmid, "snapshot-drive", device
=> $deviceid, name
=> $snap);
3001 sub qemu_volume_snapshot_delete
{
3002 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3004 my $running = check_running
($vmid);
3006 return if !PVE
::Storage
::volume_snapshot_delete
($storecfg, $volid, $snap, $running);
3008 return if !$running;
3010 vm_mon_cmd
($vmid, "delete-drive-snapshot", device
=> $deviceid, name
=> $snap);
3016 #need to impplement call to qemu-ga
3019 sub qga_unfreezefs
{
3022 #need to impplement call to qemu-ga
3026 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine) = @_;
3028 lock_config
($vmid, sub {
3029 my $conf = load_config
($vmid, $migratedfrom);
3031 die "you can't start a vm if it's a template\n" if is_template
($conf);
3033 check_lock
($conf) if !$skiplock;
3035 die "VM $vmid already running\n" if check_running
($vmid, undef, $migratedfrom);
3037 my $defaults = load_defaults
();
3039 # set environment variable useful inside network script
3040 $ENV{PVE_MIGRATED_FROM
} = $migratedfrom if $migratedfrom;
3042 my ($cmd, $vollist) = config_to_command
($storecfg, $vmid, $conf, $defaults, $forcemachine);
3044 my $migrate_port = 0;
3047 if ($statefile eq 'tcp') {
3048 $migrate_port = PVE
::Tools
::next_migrate_port
();
3049 my $migrate_uri = "tcp:localhost:${migrate_port}";
3050 push @$cmd, '-incoming', $migrate_uri;
3053 push @$cmd, '-loadstate', $statefile;
3060 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
3061 my $d = parse_hostpci
($conf->{"hostpci$i"});
3063 my $info = pci_device_info
("0000:$d->{pciid}");
3064 die "IOMMU not present\n" if !check_iommu_support
();
3065 die "no pci device info for device '$d->{pciid}'\n" if !$info;
3066 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub
($info);
3067 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset
($info);
3070 PVE
::Storage
::activate_volumes
($storecfg, $vollist);
3072 eval { run_command
($cmd, timeout
=> $statefile ?
undef : 30,
3075 die "start failed: $err" if $err;
3077 print "migration listens on port $migrate_port\n" if $migrate_port;
3079 if ($statefile && $statefile ne 'tcp') {
3080 eval { vm_mon_cmd_nocheck
($vmid, "cont"); };
3085 my $capabilities = {};
3086 $capabilities->{capability
} = "xbzrle";
3087 $capabilities->{state} = JSON
::true
;
3088 eval { vm_mon_cmd_nocheck
($vmid, "migrate-set-capabilities", capabilities
=> [$capabilities]); };
3092 if (!$statefile && (!defined($conf->{balloon
}) || $conf->{balloon
})) {
3093 vm_mon_cmd_nocheck
($vmid, "balloon", value
=> $conf->{balloon
}*1024*1024)
3094 if $conf->{balloon
};
3095 vm_mon_cmd_nocheck
($vmid, 'qom-set',
3096 path
=> "machine/peripheral/balloon0",
3097 property
=> "guest-stats-polling-interval",
3105 my ($vmid, $execute, %params) = @_;
3107 my $cmd = { execute
=> $execute, arguments
=> \
%params };
3108 vm_qmp_command
($vmid, $cmd);
3111 sub vm_mon_cmd_nocheck
{
3112 my ($vmid, $execute, %params) = @_;
3114 my $cmd = { execute
=> $execute, arguments
=> \
%params };
3115 vm_qmp_command
($vmid, $cmd, 1);
3118 sub vm_qmp_command
{
3119 my ($vmid, $cmd, $nocheck) = @_;
3124 if ($cmd->{arguments
} && $cmd->{arguments
}->{timeout
}) {
3125 $timeout = $cmd->{arguments
}->{timeout
};
3126 delete $cmd->{arguments
}->{timeout
};
3130 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
3131 my $sname = qmp_socket
($vmid);
3133 my $qmpclient = PVE
::QMPClient-
>new();
3135 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
3136 } elsif (-e
"${var_run_tmpdir}/$vmid.mon") {
3137 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
3138 if scalar(%{$cmd->{arguments
}});
3139 vm_monitor_command
($vmid, $cmd->{execute
}, $nocheck);
3141 die "unable to open monitor socket\n";
3145 syslog
("err", "VM $vmid qmp command failed - $err");
3152 sub vm_human_monitor_command
{
3153 my ($vmid, $cmdline) = @_;
3158 execute
=> 'human-monitor-command',
3159 arguments
=> { 'command-line' => $cmdline},
3162 return vm_qmp_command
($vmid, $cmd);
3165 sub vm_commandline
{
3166 my ($storecfg, $vmid) = @_;
3168 my $conf = load_config
($vmid);
3170 my $defaults = load_defaults
();
3172 my $cmd = config_to_command
($storecfg, $vmid, $conf, $defaults);
3174 return join(' ', @$cmd);
3178 my ($vmid, $skiplock) = @_;
3180 lock_config
($vmid, sub {
3182 my $conf = load_config
($vmid);
3184 check_lock
($conf) if !$skiplock;
3186 vm_mon_cmd
($vmid, "system_reset");
3190 sub get_vm_volumes
{
3194 foreach_volid
($conf, sub {
3195 my ($volid, $is_cdrom) = @_;
3197 return if $volid =~ m
|^/|;
3199 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
3202 push @$vollist, $volid;
3208 sub vm_stop_cleanup
{
3209 my ($storecfg, $vmid, $conf, $keepActive) = @_;
3212 fairsched_rmnod
($vmid); # try to destroy group
3215 my $vollist = get_vm_volumes
($conf);
3216 PVE
::Storage
::deactivate_volumes
($storecfg, $vollist);
3219 foreach my $ext (qw(mon qmp pid vnc qga)) {
3220 unlink "/var/run/qemu-server/${vmid}.$ext";
3223 warn $@ if $@; # avoid errors - just warn
3226 # Note: use $nockeck to skip tests if VM configuration file exists.
3227 # We need that when migration VMs to other nodes (files already moved)
3228 # Note: we set $keepActive in vzdump stop mode - volumes need to stay active
3230 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
3232 $force = 1 if !defined($force) && !$shutdown;
3235 my $pid = check_running
($vmid, $nocheck, $migratedfrom);
3236 kill 15, $pid if $pid;
3237 my $conf = load_config
($vmid, $migratedfrom);
3238 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive);
3242 lock_config
($vmid, sub {
3244 my $pid = check_running
($vmid, $nocheck);
3249 $conf = load_config
($vmid);
3250 check_lock
($conf) if !$skiplock;
3251 if (!defined($timeout) && $shutdown && $conf->{startup
}) {
3252 my $opts = parse_startup
($conf->{startup
});
3253 $timeout = $opts->{down
} if $opts->{down
};
3257 $timeout = 60 if !defined($timeout);
3261 $nocheck ? vm_mon_cmd_nocheck
($vmid, "system_powerdown") : vm_mon_cmd
($vmid, "system_powerdown");
3264 $nocheck ? vm_mon_cmd_nocheck
($vmid, "quit") : vm_mon_cmd
($vmid, "quit");
3271 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
3276 if ($count >= $timeout) {
3278 warn "VM still running - terminating now with SIGTERM\n";
3281 die "VM quit/powerdown failed - got timeout\n";
3284 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
3289 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
3292 die "VM quit/powerdown failed\n";
3300 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
3305 if ($count >= $timeout) {
3306 warn "VM still running - terminating now with SIGKILL\n";
3311 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
3316 my ($vmid, $skiplock) = @_;
3318 lock_config
($vmid, sub {
3320 my $conf = load_config
($vmid);
3322 check_lock
($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
3324 vm_mon_cmd
($vmid, "stop");
3329 my ($vmid, $skiplock) = @_;
3331 lock_config
($vmid, sub {
3333 my $conf = load_config
($vmid);
3335 check_lock
($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
3337 vm_mon_cmd
($vmid, "cont");
3342 my ($vmid, $skiplock, $key) = @_;
3344 lock_config
($vmid, sub {
3346 my $conf = load_config
($vmid);
3348 # there is no qmp command, so we use the human monitor command
3349 vm_human_monitor_command
($vmid, "sendkey $key");
3354 my ($storecfg, $vmid, $skiplock) = @_;
3356 lock_config
($vmid, sub {
3358 my $conf = load_config
($vmid);
3360 check_lock
($conf) if !$skiplock;
3362 if (!check_running
($vmid)) {
3363 fairsched_rmnod
($vmid); # try to destroy group
3364 destroy_vm
($storecfg, $vmid);
3366 die "VM $vmid is running - destroy failed\n";
3374 my ($filename, $buf) = @_;
3376 my $fh = IO
::File-
>new($filename, "w");
3377 return undef if !$fh;
3379 my $res = print $fh $buf;
3386 sub pci_device_info
{
3391 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
3392 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
3394 my $irq = file_read_firstline
("$pcisysfs/devices/$name/irq");
3395 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3397 my $vendor = file_read_firstline
("$pcisysfs/devices/$name/vendor");
3398 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3400 my $product = file_read_firstline
("$pcisysfs/devices/$name/device");
3401 return undef if !defined($product) || $product !~ s/^0x//;
3406 product
=> $product,
3412 has_fl_reset
=> -f
"$pcisysfs/devices/$name/reset" || 0,
3421 my $name = $dev->{name
};
3423 my $fn = "$pcisysfs/devices/$name/reset";
3425 return file_write
($fn, "1");
3428 sub pci_dev_bind_to_stub
{
3431 my $name = $dev->{name
};
3433 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3434 return 1 if -d
$testdir;
3436 my $data = "$dev->{vendor} $dev->{product}";
3437 return undef if !file_write
("$pcisysfs/drivers/pci-stub/new_id", $data);
3439 my $fn = "$pcisysfs/devices/$name/driver/unbind";
3440 if (!file_write
($fn, $name)) {
3441 return undef if -f
$fn;
3444 $fn = "$pcisysfs/drivers/pci-stub/bind";
3445 if (! -d
$testdir) {
3446 return undef if !file_write
($fn, $name);
3452 sub print_pci_addr
{
3453 my ($id, $bridges) = @_;
3457 piix3
=> { bus
=> 0, addr
=> 1 },
3458 #addr2 : first videocard
3459 balloon0
=> { bus
=> 0, addr
=> 3 },
3460 watchdog
=> { bus
=> 0, addr
=> 4 },
3461 scsihw0
=> { bus
=> 0, addr
=> 5 },
3462 scsihw1
=> { bus
=> 0, addr
=> 6 },
3463 ahci0
=> { bus
=> 0, addr
=> 7 },
3464 qga0
=> { bus
=> 0, addr
=> 8 },
3465 spice
=> { bus
=> 0, addr
=> 9 },
3466 virtio0
=> { bus
=> 0, addr
=> 10 },
3467 virtio1
=> { bus
=> 0, addr
=> 11 },
3468 virtio2
=> { bus
=> 0, addr
=> 12 },
3469 virtio3
=> { bus
=> 0, addr
=> 13 },
3470 virtio4
=> { bus
=> 0, addr
=> 14 },
3471 virtio5
=> { bus
=> 0, addr
=> 15 },
3472 hostpci0
=> { bus
=> 0, addr
=> 16 },
3473 hostpci1
=> { bus
=> 0, addr
=> 17 },
3474 net0
=> { bus
=> 0, addr
=> 18 },
3475 net1
=> { bus
=> 0, addr
=> 19 },
3476 net2
=> { bus
=> 0, addr
=> 20 },
3477 net3
=> { bus
=> 0, addr
=> 21 },
3478 net4
=> { bus
=> 0, addr
=> 22 },
3479 net5
=> { bus
=> 0, addr
=> 23 },
3480 #addr29 : usb-host (pve-usb.cfg)
3481 'pci.1' => { bus
=> 0, addr
=> 30 },
3482 'pci.2' => { bus
=> 0, addr
=> 31 },
3483 'net6' => { bus
=> 1, addr
=> 1 },
3484 'net7' => { bus
=> 1, addr
=> 2 },
3485 'net8' => { bus
=> 1, addr
=> 3 },
3486 'net9' => { bus
=> 1, addr
=> 4 },
3487 'net10' => { bus
=> 1, addr
=> 5 },
3488 'net11' => { bus
=> 1, addr
=> 6 },
3489 'net12' => { bus
=> 1, addr
=> 7 },
3490 'net13' => { bus
=> 1, addr
=> 8 },
3491 'net14' => { bus
=> 1, addr
=> 9 },
3492 'net15' => { bus
=> 1, addr
=> 10 },
3493 'net16' => { bus
=> 1, addr
=> 11 },
3494 'net17' => { bus
=> 1, addr
=> 12 },
3495 'net18' => { bus
=> 1, addr
=> 13 },
3496 'net19' => { bus
=> 1, addr
=> 14 },
3497 'net20' => { bus
=> 1, addr
=> 15 },
3498 'net21' => { bus
=> 1, addr
=> 16 },
3499 'net22' => { bus
=> 1, addr
=> 17 },
3500 'net23' => { bus
=> 1, addr
=> 18 },
3501 'net24' => { bus
=> 1, addr
=> 19 },
3502 'net25' => { bus
=> 1, addr
=> 20 },
3503 'net26' => { bus
=> 1, addr
=> 21 },
3504 'net27' => { bus
=> 1, addr
=> 22 },
3505 'net28' => { bus
=> 1, addr
=> 23 },
3506 'net29' => { bus
=> 1, addr
=> 24 },
3507 'net30' => { bus
=> 1, addr
=> 25 },
3508 'net31' => { bus
=> 1, addr
=> 26 },
3509 'virtio6' => { bus
=> 2, addr
=> 1 },
3510 'virtio7' => { bus
=> 2, addr
=> 2 },
3511 'virtio8' => { bus
=> 2, addr
=> 3 },
3512 'virtio9' => { bus
=> 2, addr
=> 4 },
3513 'virtio10' => { bus
=> 2, addr
=> 5 },
3514 'virtio11' => { bus
=> 2, addr
=> 6 },
3515 'virtio12' => { bus
=> 2, addr
=> 7 },
3516 'virtio13' => { bus
=> 2, addr
=> 8 },
3517 'virtio14' => { bus
=> 2, addr
=> 9 },
3518 'virtio15' => { bus
=> 2, addr
=> 10 },
3521 if (defined($devices->{$id}->{bus
}) && defined($devices->{$id}->{addr
})) {
3522 my $addr = sprintf("0x%x", $devices->{$id}->{addr
});
3523 my $bus = $devices->{$id}->{bus
};
3524 $res = ",bus=pci.$bus,addr=$addr";
3525 $bridges->{$bus} = 1 if $bridges;
3531 # vzdump restore implementaion
3533 sub tar_archive_read_firstfile
{
3534 my $archive = shift;
3536 die "ERROR: file '$archive' does not exist\n" if ! -f
$archive;
3538 # try to detect archive type first
3539 my $pid = open (TMP
, "tar tf '$archive'|") ||
3540 die "unable to open file '$archive'\n";
3541 my $firstfile = <TMP
>;
3545 die "ERROR: archive contaions no data\n" if !$firstfile;
3551 sub tar_restore_cleanup
{
3552 my ($storecfg, $statfile) = @_;
3554 print STDERR
"starting cleanup\n";
3556 if (my $fd = IO
::File-
>new($statfile, "r")) {
3557 while (defined(my $line = <$fd>)) {
3558 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3561 if ($volid =~ m
|^/|) {
3562 unlink $volid || die 'unlink failed\n';
3564 PVE
::Storage
::vdisk_free
($storecfg, $volid);
3566 print STDERR
"temporary volume '$volid' sucessfuly removed\n";
3568 print STDERR
"unable to cleanup '$volid' - $@" if $@;
3570 print STDERR
"unable to parse line in statfile - $line";
3577 sub restore_archive
{
3578 my ($archive, $vmid, $user, $opts) = @_;
3580 my $format = $opts->{format
};
3583 if ($archive =~ m/\.tgz$/ || $archive =~ m/\.tar\.gz$/) {
3584 $format = 'tar' if !$format;
3586 } elsif ($archive =~ m/\.tar$/) {
3587 $format = 'tar' if !$format;
3588 } elsif ($archive =~ m/.tar.lzo$/) {
3589 $format = 'tar' if !$format;
3591 } elsif ($archive =~ m/\.vma$/) {
3592 $format = 'vma' if !$format;
3593 } elsif ($archive =~ m/\.vma\.gz$/) {
3594 $format = 'vma' if !$format;
3596 } elsif ($archive =~ m/\.vma\.lzo$/) {
3597 $format = 'vma' if !$format;
3600 $format = 'vma' if !$format; # default
3603 # try to detect archive format
3604 if ($format eq 'tar') {
3605 return restore_tar_archive
($archive, $vmid, $user, $opts);
3607 return restore_vma_archive
($archive, $vmid, $user, $opts, $comp);
3611 sub restore_update_config_line
{
3612 my ($outfd, $cookie, $vmid, $map, $line, $unique) = @_;
3614 return if $line =~ m/^\#qmdump\#/;
3615 return if $line =~ m/^\#vzdump\#/;
3616 return if $line =~ m/^lock:/;
3617 return if $line =~ m/^unused\d+:/;
3618 return if $line =~ m/^parent:/;
3619 return if $line =~ m/^template:/; # restored VM is never a template
3621 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3622 # try to convert old 1.X settings
3623 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3624 foreach my $devconfig (PVE
::Tools
::split_list
($ethcfg)) {
3625 my ($model, $macaddr) = split(/\=/, $devconfig);
3626 $macaddr = PVE
::Tools
::random_ether_addr
() if !$macaddr || $unique;
3629 bridge
=> "vmbr$ind",
3630 macaddr
=> $macaddr,
3632 my $netstr = print_net
($net);
3634 print $outfd "net$cookie->{netcount}: $netstr\n";
3635 $cookie->{netcount
}++;
3637 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && $unique) {
3638 my ($id, $netstr) = ($1, $2);
3639 my $net = parse_net
($netstr);
3640 $net->{macaddr
} = PVE
::Tools
::random_ether_addr
() if $net->{macaddr
};
3641 $netstr = print_net
($net);
3642 print $outfd "$id: $netstr\n";
3643 } elsif ($line =~ m/^((ide|scsi|virtio|sata)\d+):\s*(\S+)\s*$/) {
3646 if ($line =~ m/backup=no/) {
3647 print $outfd "#$line";
3648 } elsif ($virtdev && $map->{$virtdev}) {
3649 my $di = parse_drive
($virtdev, $value);
3650 delete $di->{format
}; # format can change on restore
3651 $di->{file
} = $map->{$virtdev};
3652 $value = print_drive
($vmid, $di);
3653 print $outfd "$virtdev: $value\n";
3663 my ($cfg, $vmid) = @_;
3665 my $info = PVE
::Storage
::vdisk_list
($cfg, undef, $vmid);
3667 my $volid_hash = {};
3668 foreach my $storeid (keys %$info) {
3669 foreach my $item (@{$info->{$storeid}}) {
3670 next if !($item->{volid
} && $item->{size
});
3671 $item->{path
} = PVE
::Storage
::path
($cfg, $item->{volid
});
3672 $volid_hash->{$item->{volid
}} = $item;
3679 sub get_used_paths
{
3680 my ($vmid, $storecfg, $conf, $scan_snapshots, $skip_drive) = @_;
3684 my $scan_config = sub {
3685 my ($cref, $snapname) = @_;
3687 foreach my $key (keys %$cref) {
3688 my $value = $cref->{$key};
3689 if (valid_drivename
($key)) {
3690 next if $skip_drive && $key eq $skip_drive;
3691 my $drive = parse_drive
($key, $value);
3692 next if !$drive || !$drive->{file
} || drive_is_cdrom
($drive);
3693 if ($drive->{file
} =~ m!^/!) {
3694 $used_path->{$drive->{file
}}++; # = 1;
3696 my ($storeid, $volname) = PVE
::Storage
::parse_volume_id
($drive->{file
}, 1);
3698 my $scfg = PVE
::Storage
::storage_config
($storecfg, $storeid, 1);
3700 my $path = PVE
::Storage
::path
($storecfg, $drive->{file
}, $snapname);
3701 $used_path->{$path}++; # = 1;
3707 &$scan_config($conf);
3711 if ($scan_snapshots) {
3712 foreach my $snapname (keys %{$conf->{snapshots
}}) {
3713 &$scan_config($conf->{snapshots
}->{$snapname}, $snapname);
3720 sub update_disksize
{
3721 my ($vmid, $conf, $volid_hash) = @_;
3727 # Note: it is allowed to define multiple storages with same path (alias), so
3728 # we need to check both 'volid' and real 'path' (two different volid can point
3729 # to the same path).
3734 foreach my $opt (keys %$conf) {
3735 if (valid_drivename
($opt)) {
3736 my $drive = parse_drive
($opt, $conf->{$opt});
3737 my $volid = $drive->{file
};
3740 $used->{$volid} = 1;
3741 if ($volid_hash->{$volid} &&
3742 (my $path = $volid_hash->{$volid}->{path
})) {
3743 $usedpath->{$path} = 1;
3746 next if drive_is_cdrom
($drive);
3747 next if !$volid_hash->{$volid};
3749 $drive->{size
} = $volid_hash->{$volid}->{size
};
3750 my $new = print_drive
($vmid, $drive);
3751 if ($new ne $conf->{$opt}) {
3753 $conf->{$opt} = $new;
3758 # remove 'unusedX' entry if volume is used
3759 foreach my $opt (keys %$conf) {
3760 next if $opt !~ m/^unused\d+$/;
3761 my $volid = $conf->{$opt};
3762 my $path = $volid_hash->{$volid}->{path
} if $volid_hash->{$volid};
3763 if ($used->{$volid} || ($path && $usedpath->{$path})) {
3765 delete $conf->{$opt};
3769 foreach my $volid (sort keys %$volid_hash) {
3770 next if $volid =~ m/vm-$vmid-state-/;
3771 next if $used->{$volid};
3772 my $path = $volid_hash->{$volid}->{path
};
3773 next if !$path; # just to be sure
3774 next if $usedpath->{$path};
3776 add_unused_volume
($conf, $volid);
3777 $usedpath->{$path} = 1; # avoid to add more than once (aliases)
3784 my ($vmid, $nolock) = @_;
3786 my $cfg = PVE
::Cluster
::cfs_read_file
("storage.cfg");
3788 my $volid_hash = scan_volids
($cfg, $vmid);
3790 my $updatefn = sub {
3793 my $conf = load_config
($vmid);
3798 foreach my $volid (keys %$volid_hash) {
3799 my $info = $volid_hash->{$volid};
3800 $vm_volids->{$volid} = $info if $info->{vmid
} && $info->{vmid
} == $vmid;
3803 my $changes = update_disksize
($vmid, $conf, $vm_volids);
3805 update_config_nolock
($vmid, $conf, 1) if $changes;
3808 if (defined($vmid)) {
3812 lock_config
($vmid, $updatefn, $vmid);
3815 my $vmlist = config_list
();
3816 foreach my $vmid (keys %$vmlist) {
3820 lock_config
($vmid, $updatefn, $vmid);
3826 sub restore_vma_archive
{
3827 my ($archive, $vmid, $user, $opts, $comp) = @_;
3829 my $input = $archive eq '-' ?
"<&STDIN" : undef;
3830 my $readfrom = $archive;
3835 my $qarchive = PVE
::Tools
::shellquote
($archive);
3836 if ($comp eq 'gzip') {
3837 $uncomp = "zcat $qarchive|";
3838 } elsif ($comp eq 'lzop') {
3839 $uncomp = "lzop -d -c $qarchive|";
3841 die "unknown compression method '$comp'\n";
3846 my $tmpdir = "/var/tmp/vzdumptmp$$";
3849 # disable interrupts (always do cleanups)
3850 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
3851 warn "got interrupt - ignored\n";
3854 my $mapfifo = "/var/tmp/vzdumptmp$$.fifo";
3855 POSIX
::mkfifo
($mapfifo, 0600);
3858 my $openfifo = sub {
3859 open($fifofh, '>', $mapfifo) || die $!;
3862 my $cmd = "${uncomp}vma extract -v -r $mapfifo $readfrom $tmpdir";
3869 my $rpcenv = PVE
::RPCEnvironment
::get
();
3871 my $conffile = config_file
($vmid);
3872 my $tmpfn = "$conffile.$$.tmp";
3874 # Note: $oldconf is undef if VM does not exists
3875 my $oldconf = PVE
::Cluster
::cfs_read_file
(cfs_config_path
($vmid));
3877 my $print_devmap = sub {
3878 my $virtdev_hash = {};
3880 my $cfgfn = "$tmpdir/qemu-server.conf";
3882 # we can read the config - that is already extracted
3883 my $fh = IO
::File-
>new($cfgfn, "r") ||
3884 "unable to read qemu-server.conf - $!\n";
3886 while (defined(my $line = <$fh>)) {
3887 if ($line =~ m/^\#qmdump\#map:(\S+):(\S+):(\S*):(\S*):$/) {
3888 my ($virtdev, $devname, $storeid, $format) = ($1, $2, $3, $4);
3889 die "archive does not contain data for drive '$virtdev'\n"
3890 if !$devinfo->{$devname};
3891 if (defined($opts->{storage
})) {
3892 $storeid = $opts->{storage
} || 'local';
3893 } elsif (!$storeid) {
3896 $format = 'raw' if !$format;
3897 $devinfo->{$devname}->{devname
} = $devname;
3898 $devinfo->{$devname}->{virtdev
} = $virtdev;
3899 $devinfo->{$devname}->{format
} = $format;
3900 $devinfo->{$devname}->{storeid
} = $storeid;
3902 # check permission on storage
3903 my $pool = $opts->{pool
}; # todo: do we need that?
3904 if ($user ne 'root@pam') {
3905 $rpcenv->check($user, "/storage/$storeid", ['Datastore.AllocateSpace']);
3908 $virtdev_hash->{$virtdev} = $devinfo->{$devname};
3912 foreach my $devname (keys %$devinfo) {
3913 die "found no device mapping information for device '$devname'\n"
3914 if !$devinfo->{$devname}->{virtdev
};
3917 my $cfg = cfs_read_file
('storage.cfg');
3919 # create empty/temp config
3921 PVE
::Tools
::file_set_contents
($conffile, "memory: 128\n");
3922 foreach_drive
($oldconf, sub {
3923 my ($ds, $drive) = @_;
3925 return if drive_is_cdrom
($drive);
3927 my $volid = $drive->{file
};
3929 return if !$volid || $volid =~ m
|^/|;
3931 my ($path, $owner) = PVE
::Storage
::path
($cfg, $volid);
3932 return if !$path || !$owner || ($owner != $vmid);
3934 # Note: only delete disk we want to restore
3935 # other volumes will become unused
3936 if ($virtdev_hash->{$ds}) {
3937 PVE
::Storage
::vdisk_free
($cfg, $volid);
3943 foreach my $virtdev (sort keys %$virtdev_hash) {
3944 my $d = $virtdev_hash->{$virtdev};
3945 my $alloc_size = int(($d->{size
} + 1024 - 1)/1024);
3946 my $scfg = PVE
::Storage
::storage_config
($cfg, $d->{storeid
});
3948 # test if requested format is supported
3949 my ($defFormat, $validFormats) = PVE
::Storage
::storage_default_format
($cfg, $d->{storeid
});
3950 my $supported = grep { $_ eq $d->{format
} } @$validFormats;
3951 $d->{format
} = $defFormat if !$supported;
3953 my $volid = PVE
::Storage
::vdisk_alloc
($cfg, $d->{storeid
}, $vmid,
3954 $d->{format
}, undef, $alloc_size);
3955 print STDERR
"new volume ID is '$volid'\n";
3956 $d->{volid
} = $volid;
3957 my $path = PVE
::Storage
::path
($cfg, $volid);
3959 my $write_zeros = 1;
3960 # fixme: what other storages types initialize volumes with zero?
3961 if ($scfg->{type
} eq 'dir' || $scfg->{type
} eq 'nfs' ||
3962 $scfg->{type
} eq 'sheepdog' || $scfg->{type
} eq 'rbd') {
3966 print $fifofh "${write_zeros}:$d->{devname}=$path\n";
3968 print "map '$d->{devname}' to '$path' (write zeros = ${write_zeros})\n";
3969 $map->{$virtdev} = $volid;
3972 $fh->seek(0, 0) || die "seek failed - $!\n";
3974 my $outfd = new IO
::File
($tmpfn, "w") ||
3975 die "unable to write config for VM $vmid\n";
3977 my $cookie = { netcount
=> 0 };
3978 while (defined(my $line = <$fh>)) {
3979 restore_update_config_line
($outfd, $cookie, $vmid, $map, $line, $opts->{unique
});
3988 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
3989 die "interrupted by signal\n";
3991 local $SIG{ALRM
} = sub { die "got timeout\n"; };
3993 $oldtimeout = alarm($timeout);
4000 if ($line =~ m/^DEV:\sdev_id=(\d+)\ssize:\s(\d+)\sdevname:\s(\S+)$/) {
4001 my ($dev_id, $size, $devname) = ($1, $2, $3);
4002 $devinfo->{$devname} = { size
=> $size, dev_id
=> $dev_id };
4003 } elsif ($line =~ m/^CTIME: /) {
4005 print $fifofh "done\n";
4006 my $tmp = $oldtimeout || 0;
4007 $oldtimeout = undef;
4013 print "restore vma archive: $cmd\n";
4014 run_command
($cmd, input
=> $input, outfunc
=> $parser, afterfork
=> $openfifo);
4018 alarm($oldtimeout) if $oldtimeout;
4026 my $cfg = cfs_read_file
('storage.cfg');
4027 foreach my $devname (keys %$devinfo) {
4028 my $volid = $devinfo->{$devname}->{volid
};
4031 if ($volid =~ m
|^/|) {
4032 unlink $volid || die 'unlink failed\n';
4034 PVE
::Storage
::vdisk_free
($cfg, $volid);
4036 print STDERR
"temporary volume '$volid' sucessfuly removed\n";
4038 print STDERR
"unable to cleanup '$volid' - $@" if $@;
4045 rename($tmpfn, $conffile) ||
4046 die "unable to commit configuration file '$conffile'\n";
4048 PVE
::Cluster
::cfs_update
(); # make sure we read new file
4050 eval { rescan
($vmid, 1); };
4054 sub restore_tar_archive
{
4055 my ($archive, $vmid, $user, $opts) = @_;
4057 if ($archive ne '-') {
4058 my $firstfile = tar_archive_read_firstfile
($archive);
4059 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
4060 if $firstfile ne 'qemu-server.conf';
4063 my $storecfg = cfs_read_file
('storage.cfg');
4065 # destroy existing data - keep empty config
4066 my $vmcfgfn = PVE
::QemuServer
::config_file
($vmid);
4067 destroy_vm
($storecfg, $vmid, 1) if -f
$vmcfgfn;
4069 my $tocmd = "/usr/lib/qemu-server/qmextract";
4071 $tocmd .= " --storage " . PVE
::Tools
::shellquote
($opts->{storage
}) if $opts->{storage
};
4072 $tocmd .= " --pool " . PVE
::Tools
::shellquote
($opts->{pool
}) if $opts->{pool
};
4073 $tocmd .= ' --prealloc' if $opts->{prealloc
};
4074 $tocmd .= ' --info' if $opts->{info
};
4076 # tar option "xf" does not autodetect compression when read from STDIN,
4077 # so we pipe to zcat
4078 my $cmd = "zcat -f|tar xf " . PVE
::Tools
::shellquote
($archive) . " " .
4079 PVE
::Tools
::shellquote
("--to-command=$tocmd");
4081 my $tmpdir = "/var/tmp/vzdumptmp$$";
4084 local $ENV{VZDUMP_TMPDIR
} = $tmpdir;
4085 local $ENV{VZDUMP_VMID
} = $vmid;
4086 local $ENV{VZDUMP_USER
} = $user;
4088 my $conffile = config_file
($vmid);
4089 my $tmpfn = "$conffile.$$.tmp";
4091 # disable interrupts (always do cleanups)
4092 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
4093 print STDERR
"got interrupt - ignored\n";
4098 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
4099 die "interrupted by signal\n";
4102 if ($archive eq '-') {
4103 print "extracting archive from STDIN\n";
4104 run_command
($cmd, input
=> "<&STDIN");
4106 print "extracting archive '$archive'\n";
4110 return if $opts->{info
};
4114 my $statfile = "$tmpdir/qmrestore.stat";
4115 if (my $fd = IO
::File-
>new($statfile, "r")) {
4116 while (defined (my $line = <$fd>)) {
4117 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
4118 $map->{$1} = $2 if $1;
4120 print STDERR
"unable to parse line in statfile - $line\n";
4126 my $confsrc = "$tmpdir/qemu-server.conf";
4128 my $srcfd = new IO
::File
($confsrc, "r") ||
4129 die "unable to open file '$confsrc'\n";
4131 my $outfd = new IO
::File
($tmpfn, "w") ||
4132 die "unable to write config for VM $vmid\n";
4134 my $cookie = { netcount
=> 0 };
4135 while (defined (my $line = <$srcfd>)) {
4136 restore_update_config_line
($outfd, $cookie, $vmid, $map, $line, $opts->{unique
});
4148 tar_restore_cleanup
($storecfg, "$tmpdir/qmrestore.stat") if !$opts->{info
};
4155 rename $tmpfn, $conffile ||
4156 die "unable to commit configuration file '$conffile'\n";
4158 PVE
::Cluster
::cfs_update
(); # make sure we read new file
4160 eval { rescan
($vmid, 1); };
4165 # Internal snapshots
4167 # NOTE: Snapshot create/delete involves several non-atomic
4168 # action, and can take a long time.
4169 # So we try to avoid locking the file and use 'lock' variable
4170 # inside the config file instead.
4172 my $snapshot_copy_config = sub {
4173 my ($source, $dest) = @_;
4175 foreach my $k (keys %$source) {
4176 next if $k eq 'snapshots';
4177 next if $k eq 'snapstate';
4178 next if $k eq 'snaptime';
4179 next if $k eq 'vmstate';
4180 next if $k eq 'lock';
4181 next if $k eq 'digest';
4182 next if $k eq 'description';
4183 next if $k =~ m/^unused\d+$/;
4185 $dest->{$k} = $source->{$k};
4189 my $snapshot_apply_config = sub {
4190 my ($conf, $snap) = @_;
4192 # copy snapshot list
4194 snapshots
=> $conf->{snapshots
},
4197 # keep description and list of unused disks
4198 foreach my $k (keys %$conf) {
4199 next if !($k =~ m/^unused\d+$/ || $k eq 'description');
4200 $newconf->{$k} = $conf->{$k};
4203 &$snapshot_copy_config($snap, $newconf);
4208 sub foreach_writable_storage
{
4209 my ($conf, $func) = @_;
4213 foreach my $ds (keys %$conf) {
4214 next if !valid_drivename
($ds);
4216 my $drive = parse_drive
($ds, $conf->{$ds});
4218 next if drive_is_cdrom
($drive);
4220 my $volid = $drive->{file
};
4222 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
4223 $sidhash->{$sid} = $sid if $sid;
4226 foreach my $sid (sort keys %$sidhash) {
4231 my $alloc_vmstate_volid = sub {
4232 my ($storecfg, $vmid, $conf, $snapname) = @_;
4234 # Note: we try to be smart when selecting a $target storage
4238 # search shared storage first
4239 foreach_writable_storage
($conf, sub {
4241 my $scfg = PVE
::Storage
::storage_config
($storecfg, $sid);
4242 return if !$scfg->{shared
};
4244 $target = $sid if !$target || $scfg->{path
}; # prefer file based storage
4248 # now search local storage
4249 foreach_writable_storage
($conf, sub {
4251 my $scfg = PVE
::Storage
::storage_config
($storecfg, $sid);
4252 return if $scfg->{shared
};
4254 $target = $sid if !$target || $scfg->{path
}; # prefer file based storage;
4258 $target = 'local' if !$target;
4260 my $driver_state_size = 500; # assume 32MB is enough to safe all driver state;
4261 # we abort live save after $conf->{memory}, so we need at max twice that space
4262 my $size = $conf->{memory
}*2 + $driver_state_size;
4264 my $name = "vm-$vmid-state-$snapname";
4265 my $scfg = PVE
::Storage
::storage_config
($storecfg, $target);
4266 $name .= ".raw" if $scfg->{path
}; # add filename extension for file base storage
4267 my $volid = PVE
::Storage
::vdisk_alloc
($storecfg, $target, $vmid, 'raw', $name, $size*1024);
4272 my $snapshot_prepare = sub {
4273 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
4277 my $updatefn = sub {
4279 my $conf = load_config
($vmid);
4281 die "you can't take a snapshot if it's a template\n"
4282 if is_template
($conf);
4286 $conf->{lock} = 'snapshot';
4288 die "snapshot name '$snapname' already used\n"
4289 if defined($conf->{snapshots
}->{$snapname});
4291 my $storecfg = PVE
::Storage
::config
();
4292 die "snapshot feature is not available" if !has_feature
('snapshot', $conf, $storecfg);
4294 $snap = $conf->{snapshots
}->{$snapname} = {};
4296 if ($save_vmstate && check_running
($vmid)) {
4297 $snap->{vmstate
} = &$alloc_vmstate_volid($storecfg, $vmid, $conf, $snapname);
4300 &$snapshot_copy_config($conf, $snap);
4302 $snap->{snapstate
} = "prepare";
4303 $snap->{snaptime
} = time();
4304 $snap->{description
} = $comment if $comment;
4306 # always overwrite machine if we save vmstate. This makes sure we
4307 # can restore it later using correct machine type
4308 $snap->{machine
} = get_current_qemu_machine
($vmid) if $snap->{vmstate
};
4310 update_config_nolock
($vmid, $conf, 1);
4313 lock_config
($vmid, $updatefn);
4318 my $snapshot_commit = sub {
4319 my ($vmid, $snapname) = @_;
4321 my $updatefn = sub {
4323 my $conf = load_config
($vmid);
4325 die "missing snapshot lock\n"
4326 if !($conf->{lock} && $conf->{lock} eq 'snapshot');
4328 my $snap = $conf->{snapshots
}->{$snapname};
4330 die "snapshot '$snapname' does not exist\n" if !defined($snap);
4332 die "wrong snapshot state\n"
4333 if !($snap->{snapstate
} && $snap->{snapstate
} eq "prepare");
4335 delete $snap->{snapstate
};
4336 delete $conf->{lock};
4338 my $newconf = &$snapshot_apply_config($conf, $snap);
4340 $newconf->{parent
} = $snapname;
4342 update_config_nolock
($vmid, $newconf, 1);
4345 lock_config
($vmid, $updatefn);
4348 sub snapshot_rollback
{
4349 my ($vmid, $snapname) = @_;
4355 my $storecfg = PVE
::Storage
::config
();
4357 my $updatefn = sub {
4359 my $conf = load_config
($vmid);
4361 die "you can't rollback if vm is a template\n" if is_template
($conf);
4363 $snap = $conf->{snapshots
}->{$snapname};
4365 die "snapshot '$snapname' does not exist\n" if !defined($snap);
4367 die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
4368 if $snap->{snapstate
};
4372 vm_stop
($storecfg, $vmid, undef, undef, 5, undef, undef);
4375 die "unable to rollback vm $vmid: vm is running\n"
4376 if check_running
($vmid);
4379 $conf->{lock} = 'rollback';
4381 die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
4382 delete $conf->{lock};
4388 my $has_machine_config = defined($conf->{machine
});
4390 # copy snapshot config to current config
4391 $conf = &$snapshot_apply_config($conf, $snap);
4392 $conf->{parent
} = $snapname;
4394 # Note: old code did not store 'machine', so we try to be smart
4395 # and guess the snapshot was generated with kvm 1.4 (pc-i440fx-1.4).
4396 $forcemachine = $conf->{machine
} || 'pc-i440fx-1.4';
4397 # we remove the 'machine' configuration if not explicitly specified
4398 # in the original config.
4399 delete $conf->{machine
} if $snap->{vmstate
} && !$has_machine_config;
4402 update_config_nolock
($vmid, $conf, 1);
4404 if (!$prepare && $snap->{vmstate
}) {
4405 my $statefile = PVE
::Storage
::path
($storecfg, $snap->{vmstate
});
4406 vm_start
($storecfg, $vmid, $statefile, undef, undef, undef, $forcemachine);
4410 lock_config
($vmid, $updatefn);
4412 foreach_drive
($snap, sub {
4413 my ($ds, $drive) = @_;
4415 return if drive_is_cdrom
($drive);
4417 my $volid = $drive->{file
};
4418 my $device = "drive-$ds";
4420 PVE
::Storage
::volume_snapshot_rollback
($storecfg, $volid, $snapname);
4424 lock_config
($vmid, $updatefn);
4427 my $savevm_wait = sub {
4431 my $stat = vm_mon_cmd_nocheck
($vmid, "query-savevm");
4432 if (!$stat->{status
}) {
4433 die "savevm not active\n";
4434 } elsif ($stat->{status
} eq 'active') {
4437 } elsif ($stat->{status
} eq 'completed') {
4440 die "query-savevm returned status '$stat->{status}'\n";
4445 sub snapshot_create
{
4446 my ($vmid, $snapname, $save_vmstate, $freezefs, $comment) = @_;
4448 my $snap = &$snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
4450 $freezefs = $save_vmstate = 0 if !$snap->{vmstate
}; # vm is not running
4454 my $running = check_running
($vmid);
4457 # create internal snapshots of all drives
4459 my $storecfg = PVE
::Storage
::config
();
4462 if ($snap->{vmstate
}) {
4463 my $path = PVE
::Storage
::path
($storecfg, $snap->{vmstate
});
4464 vm_mon_cmd
($vmid, "savevm-start", statefile
=> $path);
4465 &$savevm_wait($vmid);
4467 vm_mon_cmd
($vmid, "savevm-start");
4471 qga_freezefs
($vmid) if $running && $freezefs;
4473 foreach_drive
($snap, sub {
4474 my ($ds, $drive) = @_;
4476 return if drive_is_cdrom
($drive);
4478 my $volid = $drive->{file
};
4479 my $device = "drive-$ds";
4481 qemu_volume_snapshot
($vmid, $device, $storecfg, $volid, $snapname);
4482 $drivehash->{$ds} = 1;
4487 eval { qga_unfreezefs
($vmid) if $running && $freezefs; };
4490 eval { vm_mon_cmd
($vmid, "savevm-end") if $running; };
4494 warn "snapshot create failed: starting cleanup\n";
4495 eval { snapshot_delete
($vmid, $snapname, 0, $drivehash); };
4500 &$snapshot_commit($vmid, $snapname);
4503 # Note: $drivehash is only set when called from snapshot_create.
4504 sub snapshot_delete
{
4505 my ($vmid, $snapname, $force, $drivehash) = @_;
4512 my $unlink_parent = sub {
4513 my ($confref, $new_parent) = @_;
4515 if ($confref->{parent
} && $confref->{parent
} eq $snapname) {
4517 $confref->{parent
} = $new_parent;
4519 delete $confref->{parent
};
4524 my $updatefn = sub {
4525 my ($remove_drive) = @_;
4527 my $conf = load_config
($vmid);
4531 die "you can't delete a snapshot if vm is a template\n"
4532 if is_template
($conf);
4535 $snap = $conf->{snapshots
}->{$snapname};
4537 die "snapshot '$snapname' does not exist\n" if !defined($snap);
4539 # remove parent refs
4540 &$unlink_parent($conf, $snap->{parent
});
4541 foreach my $sn (keys %{$conf->{snapshots
}}) {
4542 next if $sn eq $snapname;
4543 &$unlink_parent($conf->{snapshots
}->{$sn}, $snap->{parent
});
4546 if ($remove_drive) {
4547 if ($remove_drive eq 'vmstate') {
4548 delete $snap->{$remove_drive};
4550 my $drive = parse_drive
($remove_drive, $snap->{$remove_drive});
4551 my $volid = $drive->{file
};
4552 delete $snap->{$remove_drive};
4553 add_unused_volume
($conf, $volid);
4558 $snap->{snapstate
} = 'delete';
4560 delete $conf->{snapshots
}->{$snapname};
4561 delete $conf->{lock} if $drivehash;
4562 foreach my $volid (@$unused) {
4563 add_unused_volume
($conf, $volid);
4567 update_config_nolock
($vmid, $conf, 1);
4570 lock_config
($vmid, $updatefn);
4572 # now remove vmstate file
4574 my $storecfg = PVE
::Storage
::config
();
4576 if ($snap->{vmstate
}) {
4577 eval { PVE
::Storage
::vdisk_free
($storecfg, $snap->{vmstate
}); };
4579 die $err if !$force;
4582 # save changes (remove vmstate from snapshot)
4583 lock_config
($vmid, $updatefn, 'vmstate') if !$force;
4586 # now remove all internal snapshots
4587 foreach_drive
($snap, sub {
4588 my ($ds, $drive) = @_;
4590 return if drive_is_cdrom
($drive);
4592 my $volid = $drive->{file
};
4593 my $device = "drive-$ds";
4595 if (!$drivehash || $drivehash->{$ds}) {
4596 eval { qemu_volume_snapshot_delete
($vmid, $device, $storecfg, $volid, $snapname); };
4598 die $err if !$force;
4603 # save changes (remove drive fron snapshot)
4604 lock_config
($vmid, $updatefn, $ds) if !$force;
4605 push @$unused, $volid;
4608 # now cleanup config
4610 lock_config
($vmid, $updatefn);
4614 my ($feature, $conf, $storecfg, $snapname, $running) = @_;
4617 foreach_drive
($conf, sub {
4618 my ($ds, $drive) = @_;
4620 return if drive_is_cdrom
($drive);
4621 my $volid = $drive->{file
};
4622 $err = 1 if !PVE
::Storage
::volume_has_feature
($storecfg, $feature, $volid, $snapname, $running);
4625 return $err ?
0 : 1;
4628 sub template_create
{
4629 my ($vmid, $conf, $disk) = @_;
4631 my $storecfg = PVE
::Storage
::config
();
4633 foreach_drive
($conf, sub {
4634 my ($ds, $drive) = @_;
4636 return if drive_is_cdrom
($drive);
4637 return if $disk && $ds ne $disk;
4639 my $volid = $drive->{file
};
4640 return if !PVE
::Storage
::volume_has_feature
($storecfg, 'template', $volid);
4642 my $voliddst = PVE
::Storage
::vdisk_create_base
($storecfg, $volid);
4643 $drive->{file
} = $voliddst;
4644 $conf->{$ds} = print_drive
($vmid, $drive);
4645 update_config_nolock
($vmid, $conf, 1);
4652 return 1 if defined $conf->{template
} && $conf->{template
} == 1;
4655 sub qemu_img_convert
{
4656 my ($src_volid, $dst_volid, $size, $snapname) = @_;
4658 my $storecfg = PVE
::Storage
::config
();
4659 my ($src_storeid, $src_volname) = PVE
::Storage
::parse_volume_id
($src_volid, 1);
4660 my ($dst_storeid, $dst_volname) = PVE
::Storage
::parse_volume_id
($dst_volid, 1);
4662 if ($src_storeid && $dst_storeid) {
4663 my $src_scfg = PVE
::Storage
::storage_config
($storecfg, $src_storeid);
4664 my $dst_scfg = PVE
::Storage
::storage_config
($storecfg, $dst_storeid);
4666 my $src_format = qemu_img_format
($src_scfg, $src_volname);
4667 my $dst_format = qemu_img_format
($dst_scfg, $dst_volname);
4669 my $src_path = PVE
::Storage
::path
($storecfg, $src_volid, $snapname);
4670 my $dst_path = PVE
::Storage
::path
($storecfg, $dst_volid);
4673 push @$cmd, '/usr/bin/qemu-img', 'convert', '-t', 'writeback', '-p', '-C';
4674 push @$cmd, '-s', $snapname if($snapname && $src_format eq "qcow2");
4675 push @$cmd, '-f', $src_format, '-O', $dst_format, $src_path, $dst_path;
4679 if($line =~ m/\((\S+)\/100\
%\)/){
4681 my $transferred = int($size * $percent / 100);
4682 my $remaining = $size - $transferred;
4684 print "transferred: $transferred bytes remaining: $remaining bytes total: $size bytes progression: $percent %\n";
4689 eval { run_command
($cmd, timeout
=> undef, outfunc
=> $parser); };
4691 die "copy failed: $err" if $err;
4695 sub qemu_img_format
{
4696 my ($scfg, $volname) = @_;
4698 if ($scfg->{path
} && $volname =~ m/\.(raw|qcow2|qed|vmdk)$/) {
4700 } elsif ($scfg->{type
} eq 'iscsi') {
4701 return "host_device";
4707 sub qemu_drive_mirror
{
4708 my ($vmid, $drive, $dst_volid, $vmiddst, $maxwait) = @_;
4714 my $storecfg = PVE
::Storage
::config
();
4715 my ($dst_storeid, $dst_volname) = PVE
::Storage
::parse_volume_id
($dst_volid, 1);
4718 my $dst_scfg = PVE
::Storage
::storage_config
($storecfg, $dst_storeid);
4721 if ($dst_volname =~ m/\.(raw|qcow2)$/){
4725 my $dst_path = PVE
::Storage
::path
($storecfg, $dst_volid);
4728 #fixme : sometime drive-mirror timeout, but works fine after.
4729 # (I have see the problem with big volume > 200GB), so we need to eval
4730 eval { vm_mon_cmd
($vmid, "drive-mirror", timeout
=> 10, device
=> "drive-$drive", mode
=> "existing",
4731 sync
=> "full", target
=> $dst_path, format
=> $format); };
4733 eval { vm_mon_cmd
($vmid, "drive-mirror", timeout
=> 10, device
=> "drive-$drive", mode
=> "existing",
4734 sync
=> "full", target
=> $dst_path); };
4739 my $stats = vm_mon_cmd
($vmid, "query-block-jobs");
4740 my $stat = @$stats[0];
4741 die "mirroring job seem to have die. Maybe do you have bad sectors?" if !$stat;
4742 die "error job is not mirroring" if $stat->{type
} ne "mirror";
4744 my $transferred = $stat->{offset
};
4745 my $total = $stat->{len
};
4746 my $remaining = $total - $transferred;
4747 my $percent = sprintf "%.2f", ($transferred * 100 / $total);
4749 print "transferred: $transferred bytes remaining: $remaining bytes total: $total bytes progression: $percent %\n";
4751 last if ($stat->{len
} == $stat->{offset
});
4752 if ($old_len == $stat->{offset
}) {
4753 if ($maxwait && $count > $maxwait) {
4754 # if writes to disk occurs the disk needs to be freezed
4755 # to be able to complete the migration
4756 vm_suspend
($vmid,1);
4760 $count++ unless $frozen;
4766 $old_len = $stat->{offset
};
4770 if ($vmiddst == $vmid) {
4771 # switch the disk if source and destination are on the same guest
4772 vm_mon_cmd
($vmid, "block-job-complete", device
=> "drive-$drive");
4776 eval { vm_mon_cmd
($vmid, "block-job-cancel", device
=> "drive-$drive"); };
4777 die "mirroring error: $err";
4780 if ($vmiddst != $vmid) {
4781 # if we clone a disk for a new target vm, we don't switch the disk
4782 vm_mon_cmd
($vmid, "block-job-cancel", device
=> "drive-$drive");
4788 my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
4789 $newvmid, $storage, $format, $full, $newvollist) = @_;
4794 print "create linked clone of drive $drivename ($drive->{file})\n";
4795 $newvolid = PVE
::Storage
::vdisk_clone
($storecfg, $drive->{file
}, $newvmid);
4796 push @$newvollist, $newvolid;
4798 my ($storeid, $volname) = PVE
::Storage
::parse_volume_id
($drive->{file
});
4799 $storeid = $storage if $storage;
4801 my ($defFormat, $validFormats) = PVE
::Storage
::storage_default_format
($storecfg, $storeid);
4803 $format = $drive->{format
} || $defFormat;
4806 # test if requested format is supported - else use default
4807 my $supported = grep { $_ eq $format } @$validFormats;
4808 $format = $defFormat if !$supported;
4810 my ($size) = PVE
::Storage
::volume_size_info
($storecfg, $drive->{file
}, 3);
4812 print "create full clone of drive $drivename ($drive->{file})\n";
4813 $newvolid = PVE
::Storage
::vdisk_alloc
($storecfg, $storeid, $newvmid, $format, undef, ($size/1024));
4814 push @$newvollist, $newvolid;
4816 if (!$running || $snapname) {
4817 qemu_img_convert
($drive->{file
}, $newvolid, $size, $snapname);
4819 qemu_drive_mirror
($vmid, $drivename, $newvolid, $newvmid);
4823 my ($size) = PVE
::Storage
::volume_size_info
($storecfg, $newvolid, 3);
4826 $disk->{format
} = undef;
4827 $disk->{file
} = $newvolid;
4828 $disk->{size
} = $size;
4833 # this only works if VM is running
4834 sub get_current_qemu_machine
{
4837 my $cmd = { execute
=> 'query-machines', arguments
=> {} };
4838 my $res = PVE
::QemuServer
::vm_qmp_command
($vmid, $cmd);
4840 my ($current, $default);
4841 foreach my $e (@$res) {
4842 $default = $e->{name
} if $e->{'is-default'};
4843 $current = $e->{name
} if $e->{'is-current'};
4846 # fallback to the default machine if current is not supported by qemu
4847 return $current || $default || 'pc';