1 package PVE
::QemuServer
;
22 use Storable
qw(dclone);
23 use PVE
::Exception
qw(raise raise_param_exc);
25 use PVE
::Tools
qw(run_command lock_file lock_file_full file_read_firstline dir_glob_foreach);
26 use PVE
::JSONSchema
qw(get_standard_option);
27 use PVE
::Cluster
qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
31 use PVE
::RPCEnvironment
;
32 use Time
::HiRes
qw(gettimeofday);
34 my $cpuinfo = PVE
::ProcFSTools
::read_cpuinfo
();
36 # Note about locking: we use flock on the config file protect
37 # against concurent actions.
38 # Aditionaly, we have a 'lock' setting in the config file. This
39 # can be set to 'migrate', 'backup', 'snapshot' or 'rollback'. Most actions are not
40 # allowed when such lock is set. But you can ignore this kind of
41 # lock with the --skiplock flag.
43 cfs_register_file
('/qemu-server/',
47 PVE
::JSONSchema
::register_standard_option
('skiplock', {
48 description
=> "Ignore locks - only root is allowed to use this option.",
53 PVE
::JSONSchema
::register_standard_option
('pve-qm-stateuri', {
54 description
=> "Some command save/restore state from this location.",
60 PVE
::JSONSchema
::register_standard_option
('pve-snapshot-name', {
61 description
=> "The name of the snapshot.",
62 type
=> 'string', format
=> 'pve-configid',
66 #no warnings 'redefine';
68 unless(defined(&_VZSYSCALLS_H_
)) {
69 eval 'sub _VZSYSCALLS_H_ () {1;}' unless defined(&_VZSYSCALLS_H_
);
70 require 'sys/syscall.ph';
71 if(defined(&__x86_64__
)) {
72 eval 'sub __NR_fairsched_vcpus () {499;}' unless defined(&__NR_fairsched_vcpus
);
73 eval 'sub __NR_fairsched_mknod () {504;}' unless defined(&__NR_fairsched_mknod
);
74 eval 'sub __NR_fairsched_rmnod () {505;}' unless defined(&__NR_fairsched_rmnod
);
75 eval 'sub __NR_fairsched_chwt () {506;}' unless defined(&__NR_fairsched_chwt
);
76 eval 'sub __NR_fairsched_mvpr () {507;}' unless defined(&__NR_fairsched_mvpr
);
77 eval 'sub __NR_fairsched_rate () {508;}' unless defined(&__NR_fairsched_rate
);
78 eval 'sub __NR_setluid () {501;}' unless defined(&__NR_setluid
);
79 eval 'sub __NR_setublimit () {502;}' unless defined(&__NR_setublimit
);
81 elsif(defined( &__i386__
) ) {
82 eval 'sub __NR_fairsched_mknod () {500;}' unless defined(&__NR_fairsched_mknod
);
83 eval 'sub __NR_fairsched_rmnod () {501;}' unless defined(&__NR_fairsched_rmnod
);
84 eval 'sub __NR_fairsched_chwt () {502;}' unless defined(&__NR_fairsched_chwt
);
85 eval 'sub __NR_fairsched_mvpr () {503;}' unless defined(&__NR_fairsched_mvpr
);
86 eval 'sub __NR_fairsched_rate () {504;}' unless defined(&__NR_fairsched_rate
);
87 eval 'sub __NR_fairsched_vcpus () {505;}' unless defined(&__NR_fairsched_vcpus
);
88 eval 'sub __NR_setluid () {511;}' unless defined(&__NR_setluid
);
89 eval 'sub __NR_setublimit () {512;}' unless defined(&__NR_setublimit
);
91 die("no fairsched syscall for this arch");
93 require 'asm/ioctl.ph';
94 eval 'sub KVM_GET_API_VERSION () { &_IO(0xAE, 0x);}' unless defined(&KVM_GET_API_VERSION
);
98 my ($parent, $weight, $desired) = @_;
100 return syscall(&__NR_fairsched_mknod
, int($parent), int($weight), int($desired));
103 sub fairsched_rmnod
{
106 return syscall(&__NR_fairsched_rmnod
, int($id));
110 my ($pid, $newid) = @_;
112 return syscall(&__NR_fairsched_mvpr
, int($pid), int($newid));
115 sub fairsched_vcpus
{
116 my ($id, $vcpus) = @_;
118 return syscall(&__NR_fairsched_vcpus
, int($id), int($vcpus));
122 my ($id, $op, $rate) = @_;
124 return syscall(&__NR_fairsched_rate
, int($id), int($op), int($rate));
127 use constant FAIRSCHED_SET_RATE
=> 0;
128 use constant FAIRSCHED_DROP_RATE
=> 1;
129 use constant FAIRSCHED_GET_RATE
=> 2;
131 sub fairsched_cpulimit
{
132 my ($id, $limit) = @_;
134 my $cpulim1024 = int($limit * 1024 / 100);
135 my $op = $cpulim1024 ? FAIRSCHED_SET_RATE
: FAIRSCHED_DROP_RATE
;
137 return fairsched_rate
($id, $op, $cpulim1024);
140 my $nodename = PVE
::INotify
::nodename
();
142 mkdir "/etc/pve/nodes/$nodename";
143 my $confdir = "/etc/pve/nodes/$nodename/qemu-server";
146 my $var_run_tmpdir = "/var/run/qemu-server";
147 mkdir $var_run_tmpdir;
149 my $lock_dir = "/var/lock/qemu-server";
152 my $pcisysfs = "/sys/bus/pci";
158 description
=> "Specifies whether a VM will be started during system bootup.",
164 description
=> "Automatic restart after crash (currently ignored).",
170 description
=> "Allow hotplug for disk and network device",
176 description
=> "Allow reboot. If set to '0' the VM exit on reboot.",
182 description
=> "Lock/unlock the VM.",
183 enum
=> [qw(migrate backup snapshot rollback)],
188 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.",
195 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.",
203 description
=> "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.",
210 description
=> "Amount of target RAM for the VM in MB. Using zero disables the ballon driver.",
216 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",
224 description
=> "Keybord layout for vnc server. Default is read from the datacenter configuration file.",
225 enum
=> PVE
::Tools
::kvmkeymaplist
(),
230 type
=> 'string', format
=> 'dns-name',
231 description
=> "Set a name for the VM. Only used on the configuration web interface.",
236 description
=> "scsi controller model",
237 enum
=> [qw(lsi lsi53c810 virtio-scsi-pci megasas pvscsi)],
243 description
=> "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.",
248 enum
=> [qw(other wxp w2k w2k3 w2k8 wvista win7 win8 l24 l26 solaris)],
249 description
=> <<EODESC,
250 Used to enable special optimization/features for specific
253 other => unspecified OS
254 wxp => Microsoft Windows XP
255 w2k => Microsoft Windows 2000
256 w2k3 => Microsoft Windows 2003
257 w2k8 => Microsoft Windows 2008
258 wvista => Microsoft Windows Vista
259 win7 => Microsoft Windows 7
260 win8 => Microsoft Windows 8/2012
261 l24 => Linux 2.4 Kernel
262 l26 => Linux 2.6/3.X Kernel
263 solaris => solaris/opensolaris/openindiania kernel
265 other|l24|l26|solaris ... no special behaviour
266 wxp|w2k|w2k3|w2k8|wvista|win7|win8 ... use --localtime switch
272 description
=> "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n).",
273 pattern
=> '[acdn]{1,4}',
278 type
=> 'string', format
=> 'pve-qm-bootdisk',
279 description
=> "Enable booting from specified disk.",
280 pattern
=> '(ide|sata|scsi|virtio)\d+',
285 description
=> "The number of CPUs. Please use option -sockets instead.",
292 description
=> "The number of CPU sockets.",
299 description
=> "The number of cores per socket.",
306 description
=> "Maximum cpus for hotplug.",
313 description
=> "Enable/disable ACPI.",
319 description
=> "Enable/disable Qemu GuestAgent.",
325 description
=> "Enable/disable KVM hardware virtualization.",
331 description
=> "Enable/disable time drift fix.",
337 description
=> "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
342 description
=> "Freeze CPU at startup (use 'c' monitor command to start execution).",
347 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. You can also run without any graphic card using a serial devive as terminal.",
348 enum
=> [qw(std cirrus vmware qxl serial0 serial1 serial2 serial3 qxl2 qxl3 qxl4)],
352 type
=> 'string', format
=> 'pve-qm-watchdog',
353 typetext
=> '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
354 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)",
359 typetext
=> "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
360 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'.",
361 pattern
=> '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
366 type
=> 'string', format
=> 'pve-qm-startup',
367 typetext
=> '[[order=]\d+] [,up=\d+] [,down=\d+] ',
368 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.",
373 description
=> "Enable/disable Template.",
379 description
=> <<EODESCR,
380 Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
382 args: -no-reboot -no-hpet
389 description
=> "Enable/disable the usb tablet device. This device is usually needed to allow absolute mouse positioning with VNC. 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. This is turned of by default if you use spice (vga=qxl).",
394 description
=> "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
398 migrate_downtime
=> {
401 description
=> "Set maximum tolerated downtime (in seconds) for migrations.",
407 type
=> 'string', format
=> 'pve-qm-drive',
408 typetext
=> 'volume',
409 description
=> "This is an alias for option -ide2",
413 description
=> "Emulated CPU type.",
415 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) ],
418 parent
=> get_standard_option
('pve-snapshot-name', {
420 description
=> "Parent snapshot name. This is used internally, and should not be modified.",
424 description
=> "Timestamp for snapshots.",
430 type
=> 'string', format
=> 'pve-volume-id',
431 description
=> "Reference to a volume which stores the VM state. This is used internally for snapshots.",
434 description
=> "Specific the Qemu machine type.",
436 pattern
=> '(pc|pc(-i440fx)?-\d+\.\d+|q35|pc-q35-\d+\.\d+)',
442 # what about other qemu settings ?
444 #machine => 'string',
457 ##soundhw => 'string',
459 while (my ($k, $v) = each %$confdesc) {
460 PVE
::JSONSchema
::register_standard_option
("pve-qm-$k", $v);
463 my $MAX_IDE_DISKS = 4;
464 my $MAX_SCSI_DISKS = 14;
465 my $MAX_VIRTIO_DISKS = 16;
466 my $MAX_SATA_DISKS = 6;
467 my $MAX_USB_DEVICES = 5;
469 my $MAX_UNUSED_DISKS = 8;
470 my $MAX_HOSTPCI_DEVICES = 2;
471 my $MAX_SERIAL_PORTS = 4;
472 my $MAX_PARALLEL_PORTS = 3;
474 my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
475 'ne2k_isa', 'i82551', 'i82557b', 'i82559er', 'vmxnet3'];
476 my $nic_model_list_txt = join(' ', sort @$nic_model_list);
480 type
=> 'string', format
=> 'pve-qm-net',
481 typetext
=> "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,queues=<nbqueues>][,rate=<mbps>][,tag=<vlanid>][,firewall=0|1]",
482 description
=> <<EODESCR,
483 Specify network devices.
485 MODEL is one of: $nic_model_list_txt
487 XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
488 automatically generated if not specified.
490 The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
492 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'.
494 If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
500 The DHCP server assign addresses to the guest starting from 10.0.2.15.
504 PVE
::JSONSchema
::register_standard_option
("pve-qm-net", $netdesc);
506 for (my $i = 0; $i < $MAX_NETS; $i++) {
507 $confdesc->{"net$i"} = $netdesc;
514 type
=> 'string', format
=> 'pve-qm-drive',
515 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] [,discard=ignore|on]',
516 description
=> "Use volume as IDE hard disk or CD-ROM (n is 0 to " .($MAX_IDE_DISKS -1) . ").",
518 PVE
::JSONSchema
::register_standard_option
("pve-qm-ide", $idedesc);
522 type
=> 'string', format
=> 'pve-qm-drive',
523 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] [,discard=ignore|on]',
524 description
=> "Use volume as SCSI hard disk or CD-ROM (n is 0 to " . ($MAX_SCSI_DISKS - 1) . ").",
526 PVE
::JSONSchema
::register_standard_option
("pve-qm-scsi", $scsidesc);
530 type
=> 'string', format
=> 'pve-qm-drive',
531 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] [,discard=ignore|on]',
532 description
=> "Use volume as SATA hard disk or CD-ROM (n is 0 to " . ($MAX_SATA_DISKS - 1). ").",
534 PVE
::JSONSchema
::register_standard_option
("pve-qm-sata", $satadesc);
538 type
=> 'string', format
=> 'pve-qm-drive',
539 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] [,discard=ignore|on]',
540 description
=> "Use volume as VIRTIO hard disk (n is 0 to " . ($MAX_VIRTIO_DISKS - 1) . ").",
542 PVE
::JSONSchema
::register_standard_option
("pve-qm-virtio", $virtiodesc);
546 type
=> 'string', format
=> 'pve-qm-usb-device',
547 typetext
=> 'host=HOSTUSBDEVICE|spice',
548 description
=> <<EODESCR,
549 Configure an USB device (n is 0 to 4). This can be used to
550 pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
552 'bus-port(.port)*' (decimal numbers) or
553 'vendor_id:product_id' (hexadeciaml numbers)
555 You can use the 'lsusb -t' command to list existing usb devices.
557 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
559 The value 'spice' can be used to add a usb redirection devices for spice.
563 PVE
::JSONSchema
::register_standard_option
("pve-qm-usb", $usbdesc);
567 type
=> 'string', format
=> 'pve-qm-hostpci',
568 typetext
=> "[host=]HOSTPCIDEVICE [,driver=kvm|vfio] [,rombar=on|off] [,pcie=0|1] [,x-vga=on|off]",
569 description
=> <<EODESCR,
570 Map host pci devices. HOSTPCIDEVICE syntax is:
572 'bus:dev.func' (hexadecimal numbers)
574 You can us the 'lspci' command to list existing pci devices.
576 The 'rombar' option determines whether or not the device's ROM will be visible in the guest's memory map (default is 'on').
578 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
580 Experimental: user reported problems with this option.
583 PVE
::JSONSchema
::register_standard_option
("pve-qm-hostpci", $hostpcidesc);
588 pattern
=> '(/dev/ttyS\d+|socket)',
589 description
=> <<EODESCR,
590 Create a serial device inside the VM (n is 0 to 3), and pass through a host serial device, or create a unix socket on the host side (use 'qm terminal' to open a terminal connection).
592 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
594 Experimental: user reported problems with this option.
601 pattern
=> '/dev/parport\d+|/dev/usb/lp\d+',
602 description
=> <<EODESCR,
603 Map host parallel devices (n is 0 to 2).
605 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
607 Experimental: user reported problems with this option.
611 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
612 $confdesc->{"parallel$i"} = $paralleldesc;
615 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
616 $confdesc->{"serial$i"} = $serialdesc;
619 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
620 $confdesc->{"hostpci$i"} = $hostpcidesc;
623 for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
624 $drivename_hash->{"ide$i"} = 1;
625 $confdesc->{"ide$i"} = $idedesc;
628 for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
629 $drivename_hash->{"sata$i"} = 1;
630 $confdesc->{"sata$i"} = $satadesc;
633 for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
634 $drivename_hash->{"scsi$i"} = 1;
635 $confdesc->{"scsi$i"} = $scsidesc ;
638 for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
639 $drivename_hash->{"virtio$i"} = 1;
640 $confdesc->{"virtio$i"} = $virtiodesc;
643 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
644 $confdesc->{"usb$i"} = $usbdesc;
649 type
=> 'string', format
=> 'pve-volume-id',
650 description
=> "Reference to unused volumes.",
653 for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
654 $confdesc->{"unused$i"} = $unuseddesc;
657 my $kvm_api_version = 0;
661 return $kvm_api_version if $kvm_api_version;
663 my $fh = IO
::File-
>new("</dev/kvm") ||
666 if (my $v = $fh->ioctl(KVM_GET_API_VERSION
(), 0)) {
667 $kvm_api_version = $v;
672 return $kvm_api_version;
675 my $kvm_user_version;
677 sub kvm_user_version
{
679 return $kvm_user_version if $kvm_user_version;
681 $kvm_user_version = 'unknown';
683 my $tmp = `kvm -help 2>/dev/null`;
685 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?)[,\s]/) {
686 $kvm_user_version = $2;
689 return $kvm_user_version;
693 my $kernel_has_vhost_net = -c
'/dev/vhost-net';
696 # order is important - used to autoselect boot disk
697 return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
698 (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
699 (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
700 (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
703 sub valid_drivename
{
706 return defined($drivename_hash->{$dev});
711 return defined($confdesc->{$key});
715 return $nic_model_list;
718 sub os_list_description
{
723 w2k
=> 'Windows 2000',
724 w2k3
=>, 'Windows 2003',
725 w2k8
=> 'Windows 2008',
726 wvista
=> 'Windows Vista',
728 win8
=> 'Windows 8/2012',
738 return $cdrom_path if $cdrom_path;
740 return $cdrom_path = "/dev/cdrom" if -l
"/dev/cdrom";
741 return $cdrom_path = "/dev/cdrom1" if -l
"/dev/cdrom1";
742 return $cdrom_path = "/dev/cdrom2" if -l
"/dev/cdrom2";
746 my ($storecfg, $vmid, $cdrom) = @_;
748 if ($cdrom eq 'cdrom') {
749 return get_cdrom_path
();
750 } elsif ($cdrom eq 'none') {
752 } elsif ($cdrom =~ m
|^/|) {
755 return PVE
::Storage
::path
($storecfg, $cdrom);
759 # try to convert old style file names to volume IDs
760 sub filename_to_volume_id
{
761 my ($vmid, $file, $media) = @_;
763 if (!($file eq 'none' || $file eq 'cdrom' ||
764 $file =~ m
|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
766 return undef if $file =~ m
|/|;
768 if ($media && $media eq 'cdrom') {
769 $file = "local:iso/$file";
771 $file = "local:$vmid/$file";
778 sub verify_media_type
{
779 my ($opt, $vtype, $media) = @_;
784 if ($media eq 'disk') {
786 } elsif ($media eq 'cdrom') {
789 die "internal error";
792 return if ($vtype eq $etype);
794 raise_param_exc
({ $opt => "unexpected media type ($vtype != $etype)" });
797 sub cleanup_drive_path
{
798 my ($opt, $storecfg, $drive) = @_;
800 # try to convert filesystem paths to volume IDs
802 if (($drive->{file
} !~ m/^(cdrom|none)$/) &&
803 ($drive->{file
} !~ m
|^/dev/.+|) &&
804 ($drive->{file
} !~ m/^([^:]+):(.+)$/) &&
805 ($drive->{file
} !~ m/^\d+$/)) {
806 my ($vtype, $volid) = PVE
::Storage
::path_to_volume_id
($storecfg, $drive->{file
});
807 raise_param_exc
({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
808 $drive->{media
} = 'cdrom' if !$drive->{media
} && $vtype eq 'iso';
809 verify_media_type
($opt, $vtype, $drive->{media
});
810 $drive->{file
} = $volid;
813 $drive->{media
} = 'cdrom' if !$drive->{media
} && $drive->{file
} =~ m/^(cdrom|none)$/;
816 sub create_conf_nolock
{
817 my ($vmid, $settings) = @_;
819 my $filename = config_file
($vmid);
821 die "configuration file '$filename' already exists\n" if -f
$filename;
823 my $defaults = load_defaults
();
825 $settings->{name
} = "vm$vmid" if !$settings->{name
};
826 $settings->{memory
} = $defaults->{memory
} if !$settings->{memory
};
829 foreach my $opt (keys %$settings) {
830 next if !$confdesc->{$opt};
832 my $value = $settings->{$opt};
835 $data .= "$opt: $value\n";
838 PVE
::Tools
::file_set_contents
($filename, $data);
841 my $parse_size = sub {
844 return undef if $value !~ m/^(\d+(\.\d+)?)([KMG])?$/;
845 my ($size, $unit) = ($1, $3);
848 $size = $size * 1024;
849 } elsif ($unit eq 'M') {
850 $size = $size * 1024 * 1024;
851 } elsif ($unit eq 'G') {
852 $size = $size * 1024 * 1024 * 1024;
858 my $format_size = sub {
863 my $kb = int($size/1024);
864 return $size if $kb*1024 != $size;
866 my $mb = int($kb/1024);
867 return "${kb}K" if $mb*1024 != $kb;
869 my $gb = int($mb/1024);
870 return "${mb}M" if $gb*1024 != $mb;
875 # ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
876 # [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
877 # [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
878 # [,aio=native|threads][,discard=ignore|on]
881 my ($key, $data) = @_;
885 # $key may be undefined - used to verify JSON parameters
886 if (!defined($key)) {
887 $res->{interface
} = 'unknown'; # should not harm when used to verify parameters
889 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
890 $res->{interface
} = $1;
896 foreach my $p (split (/,/, $data)) {
897 next if $p =~ m/^\s*$/;
899 if ($p =~ m/^(file|volume|cyls|heads|secs|trans|media|snapshot|cache|format|rerror|werror|backup|aio|bps|mbps|mbps_max|bps_rd|mbps_rd|mbps_rd_max|bps_wr|mbps_wr|mbps_wr_max|iops|iops_max|iops_rd|iops_rd_max|iops_wr|iops_wr_max|size|discard)=(.+)$/) {
900 my ($k, $v) = ($1, $2);
902 $k = 'file' if $k eq 'volume';
904 return undef if defined $res->{$k};
906 if ($k eq 'bps' || $k eq 'bps_rd' || $k eq 'bps_wr') {
907 return undef if !$v || $v !~ m/^\d+/;
909 $v = sprintf("%.3f", $v / (1024*1024));
913 if (!$res->{file
} && $p !~ m/=/) {
921 return undef if !$res->{file
};
923 if($res->{file
} =~ m/\.(raw|cow|qcow|qcow2|vmdk|cloop)$/){
927 return undef if $res->{cache
} &&
928 $res->{cache
} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
929 return undef if $res->{snapshot
} && $res->{snapshot
} !~ m/^(on|off)$/;
930 return undef if $res->{cyls
} && $res->{cyls
} !~ m/^\d+$/;
931 return undef if $res->{heads
} && $res->{heads
} !~ m/^\d+$/;
932 return undef if $res->{secs
} && $res->{secs
} !~ m/^\d+$/;
933 return undef if $res->{media
} && $res->{media
} !~ m/^(disk|cdrom)$/;
934 return undef if $res->{trans
} && $res->{trans
} !~ m/^(none|lba|auto)$/;
935 return undef if $res->{format
} && $res->{format
} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
936 return undef if $res->{rerror
} && $res->{rerror
} !~ m/^(ignore|report|stop)$/;
937 return undef if $res->{werror
} && $res->{werror
} !~ m/^(enospc|ignore|report|stop)$/;
938 return undef if $res->{backup
} && $res->{backup
} !~ m/^(yes|no)$/;
939 return undef if $res->{aio
} && $res->{aio
} !~ m/^(native|threads)$/;
940 return undef if $res->{discard
} && $res->{discard
} !~ m/^(ignore|on)$/;
942 return undef if $res->{mbps_rd
} && $res->{mbps
};
943 return undef if $res->{mbps_wr
} && $res->{mbps
};
945 return undef if $res->{mbps
} && $res->{mbps
} !~ m/^\d+(\.\d+)?$/;
946 return undef if $res->{mbps_max
} && $res->{mbps_max
} !~ m/^\d+(\.\d+)?$/;
947 return undef if $res->{mbps_rd
} && $res->{mbps_rd
} !~ m/^\d+(\.\d+)?$/;
948 return undef if $res->{mbps_rd_max
} && $res->{mbps_rd_max
} !~ m/^\d+(\.\d+)?$/;
949 return undef if $res->{mbps_wr
} && $res->{mbps_wr
} !~ m/^\d+(\.\d+)?$/;
950 return undef if $res->{mbps_wr_max
} && $res->{mbps_wr_max
} !~ m/^\d+(\.\d+)?$/;
952 return undef if $res->{iops_rd
} && $res->{iops
};
953 return undef if $res->{iops_wr
} && $res->{iops
};
956 return undef if $res->{iops
} && $res->{iops
} !~ m/^\d+$/;
957 return undef if $res->{iops_max
} && $res->{iops_max
} !~ m/^\d+$/;
958 return undef if $res->{iops_rd
} && $res->{iops_rd
} !~ m/^\d+$/;
959 return undef if $res->{iops_rd_max
} && $res->{iops_rd_max
} !~ m/^\d+$/;
960 return undef if $res->{iops_wr
} && $res->{iops_wr
} !~ m/^\d+$/;
961 return undef if $res->{iops_wr_max
} && $res->{iops_wr_max
} !~ m/^\d+$/;
965 return undef if !defined($res->{size
} = &$parse_size($res->{size
}));
968 if ($res->{media
} && ($res->{media
} eq 'cdrom')) {
969 return undef if $res->{snapshot
} || $res->{trans
} || $res->{format
};
970 return undef if $res->{heads
} || $res->{secs
} || $res->{cyls
};
971 return undef if $res->{interface
} eq 'virtio';
974 # rerror does not work with scsi drives
975 if ($res->{rerror
}) {
976 return undef if $res->{interface
} eq 'scsi';
982 my @qemu_drive_options = qw(heads secs cyls trans media format cache snapshot rerror werror aio discard iops iops_rd iops_wr iops_max iops_rd_max iops_wr_max);
985 my ($vmid, $drive) = @_;
988 foreach my $o (@qemu_drive_options, 'mbps', 'mbps_rd', 'mbps_wr', 'mbps_max', 'mbps_rd_max', 'mbps_wr_max', 'backup') {
989 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
992 if ($drive->{size
}) {
993 $opts .= ",size=" . &$format_size($drive->{size
});
996 return "$drive->{file}$opts";
1000 my($fh, $noerr) = @_;
1003 my $SG_GET_VERSION_NUM = 0x2282;
1005 my $versionbuf = "\x00" x
8;
1006 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
1008 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
1011 my $version = unpack("I", $versionbuf);
1012 if ($version < 30000) {
1013 die "scsi generic interface too old\n" if !$noerr;
1017 my $buf = "\x00" x
36;
1018 my $sensebuf = "\x00" x
8;
1019 my $cmd = pack("C x3 C x1", 0x12, 36);
1021 # see /usr/include/scsi/sg.h
1022 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";
1024 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
1025 length($sensebuf), 0, length($buf), $buf,
1026 $cmd, $sensebuf, 6000);
1028 $ret = ioctl($fh, $SG_IO, $packet);
1030 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
1034 my @res = unpack($sg_io_hdr_t, $packet);
1035 if ($res[17] || $res[18]) {
1036 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
1041 (my $byte0, my $byte1, $res->{vendor
},
1042 $res->{product
}, $res->{revision
}) = unpack("C C x6 A8 A16 A4", $buf);
1044 $res->{removable
} = $byte1 & 128 ?
1 : 0;
1045 $res->{type
} = $byte0 & 31;
1053 my $fh = IO
::File-
>new("+<$path") || return undef;
1054 my $res = scsi_inquiry
($fh, 1);
1060 sub machine_type_is_q35
{
1063 return $conf->{machine
} && ($conf->{machine
} =~ m/q35/) ?
1 : 0;
1066 sub print_tabletdevice_full
{
1069 my $q35 = machine_type_is_q35
($conf);
1071 # we use uhci for old VMs because tablet driver was buggy in older qemu
1072 my $usbbus = $q35 ?
"ehci" : "uhci";
1074 return "usb-tablet,id=tablet,bus=$usbbus.0,port=1";
1077 sub print_drivedevice_full
{
1078 my ($storecfg, $conf, $vmid, $drive, $bridges) = @_;
1083 if ($drive->{interface
} eq 'virtio') {
1084 my $pciaddr = print_pci_addr
("$drive->{interface}$drive->{index}", $bridges);
1085 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
1086 } elsif ($drive->{interface
} eq 'scsi') {
1087 $maxdev = ($conf->{scsihw
} && ($conf->{scsihw
} !~ m/^lsi/)) ?
256 : 7;
1088 my $controller = int($drive->{index} / $maxdev);
1089 my $unit = $drive->{index} % $maxdev;
1090 my $devicetype = 'hd';
1092 if (drive_is_cdrom
($drive)) {
1095 if ($drive->{file
} =~ m
|^/|) {
1096 $path = $drive->{file
};
1098 $path = PVE
::Storage
::path
($storecfg, $drive->{file
});
1101 if($path =~ m/^iscsi\:\/\
//){
1102 $devicetype = 'generic';
1104 if (my $info = path_is_scsi
($path)) {
1105 if ($info->{type
} == 0) {
1106 $devicetype = 'block';
1107 } elsif ($info->{type
} == 1) { # tape
1108 $devicetype = 'generic';
1114 if (!$conf->{scsihw
} || ($conf->{scsihw
} =~ m/^lsi/)){
1115 $device = "scsi-$devicetype,bus=scsihw$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1117 $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}";
1120 } elsif ($drive->{interface
} eq 'ide'){
1122 my $controller = int($drive->{index} / $maxdev);
1123 my $unit = $drive->{index} % $maxdev;
1124 my $devicetype = ($drive->{media
} && $drive->{media
} eq 'cdrom') ?
"cd" : "hd";
1126 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1127 } elsif ($drive->{interface
} eq 'sata'){
1128 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
1129 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1130 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1131 } elsif ($drive->{interface
} eq 'usb') {
1133 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1135 die "unsupported interface type";
1138 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex
};
1143 sub get_initiator_name
{
1146 my $fh = IO
::File-
>new('/etc/iscsi/initiatorname.iscsi') || return undef;
1147 while (defined(my $line = <$fh>)) {
1148 next if $line !~ m/^\s*InitiatorName\s*=\s*([\.\-:\w]+)/;
1157 sub print_drive_full
{
1158 my ($storecfg, $vmid, $drive) = @_;
1161 foreach my $o (@qemu_drive_options) {
1162 next if $o eq 'bootindex';
1163 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
1166 foreach my $o (qw(bps bps_rd bps_wr)) {
1167 my $v = $drive->{"m$o"};
1168 $opts .= ",$o=" . int($v*1024*1024) if $v;
1171 # use linux-aio by default (qemu default is threads)
1172 $opts .= ",aio=native" if !$drive->{aio
};
1175 my $volid = $drive->{file
};
1176 if (drive_is_cdrom
($drive)) {
1177 $path = get_iso_path
($storecfg, $vmid, $volid);
1179 if ($volid =~ m
|^/|) {
1182 $path = PVE
::Storage
::path
($storecfg, $volid);
1186 $opts .= ",cache=none" if !$drive->{cache
} && !drive_is_cdrom
($drive);
1188 my $pathinfo = $path ?
"file=$path," : '';
1190 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1193 sub print_netdevice_full
{
1194 my ($vmid, $conf, $net, $netid, $bridges) = @_;
1196 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
1198 my $device = $net->{model
};
1199 if ($net->{model
} eq 'virtio') {
1200 $device = 'virtio-net-pci';
1203 # qemu > 0.15 always try to boot from network - we disable that by
1204 # not loading the pxe rom file
1205 my $extra = ($bootorder !~ m/n/) ?
"romfile=," : '';
1206 my $pciaddr = print_pci_addr
("$netid", $bridges);
1207 my $tmpstr = "$device,${extra}mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
1208 if ($net->{queues
} && $net->{queues
} > 1 && $net->{model
} eq 'virtio'){
1209 #Consider we have N queues, the number of vectors needed is 2*N + 2 (plus one config interrupt and control vq)
1210 my $vectors = $net->{queues
} * 2 + 2;
1211 $tmpstr .= ",vectors=$vectors,mq=on";
1213 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex
} ;
1217 sub print_netdev_full
{
1218 my ($vmid, $conf, $net, $netid) = @_;
1221 if ($netid =~ m/^net(\d+)$/) {
1225 die "got strange net id '$i'\n" if $i >= ${MAX_NETS
};
1227 my $ifname = "tap${vmid}i$i";
1229 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1230 die "interface name '$ifname' is too long (max 15 character)\n"
1231 if length($ifname) >= 16;
1233 my $vhostparam = '';
1234 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model
} eq 'virtio';
1236 my $vmname = $conf->{name
} || "vm$vmid";
1240 if ($net->{bridge
}) {
1241 $netdev = "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown$vhostparam";
1243 $netdev = "type=user,id=$netid,hostname=$vmname";
1246 $netdev .= ",queues=$net->{queues}" if ($net->{queues
} && $net->{model
} eq 'virtio');
1251 sub drive_is_cdrom
{
1254 return $drive && $drive->{media
} && ($drive->{media
} eq 'cdrom');
1261 return undef if !$value;
1264 my @list = split(/,/, $value);
1268 foreach my $kv (@list) {
1270 if ($kv =~ m/^(host=)?([a-f0-9]{2}:[a-f0-9]{2})(\.([a-f0-9]))?$/) {
1273 push @{$res->{pciid
}}, { id
=> $2 , function
=> $4};
1276 my $pcidevices = lspci
($2);
1277 $res->{pciid
} = $pcidevices->{$2};
1279 } elsif ($kv =~ m/^driver=(kvm|vfio)$/) {
1280 $res->{driver
} = $1;
1281 } elsif ($kv =~ m/^rombar=(on|off)$/) {
1282 $res->{rombar
} = $1;
1283 } elsif ($kv =~ m/^x-vga=(on|off)$/) {
1284 $res->{'x-vga'} = $1;
1285 } elsif ($kv =~ m/^pcie=(\d+)$/) {
1286 $res->{pcie
} = 1 if $1 == 1;
1288 warn "unknown hostpci setting '$kv'\n";
1292 return undef if !$found;
1297 # netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1303 foreach my $kvp (split(/,/, $data)) {
1305 if ($kvp =~ m/^(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er|vmxnet3)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
1307 my $mac = defined($3) ?
uc($3) : PVE
::Tools
::random_ether_addr
();
1308 $res->{model
} = $model;
1309 $res->{macaddr
} = $mac;
1310 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1311 $res->{bridge
} = $1;
1312 } elsif ($kvp =~ m/^queues=(\d+)$/) {
1313 $res->{queues
} = $1;
1314 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1316 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1318 } elsif ($kvp =~ m/^firewall=(\d+)$/) {
1319 $res->{firewall
} = $1;
1326 return undef if !$res->{model
};
1334 my $res = "$net->{model}";
1335 $res .= "=$net->{macaddr}" if $net->{macaddr
};
1336 $res .= ",bridge=$net->{bridge}" if $net->{bridge
};
1337 $res .= ",rate=$net->{rate}" if $net->{rate
};
1338 $res .= ",tag=$net->{tag}" if $net->{tag
};
1339 $res .= ",firewall=$net->{firewall}" if $net->{firewall
};
1344 sub add_random_macs
{
1345 my ($settings) = @_;
1347 foreach my $opt (keys %$settings) {
1348 next if $opt !~ m/^net(\d+)$/;
1349 my $net = parse_net
($settings->{$opt});
1351 $settings->{$opt} = print_net
($net);
1355 sub add_unused_volume
{
1356 my ($config, $volid) = @_;
1359 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1360 my $test = "unused$ind";
1361 if (my $vid = $config->{$test}) {
1362 return if $vid eq $volid; # do not add duplicates
1368 die "To many unused volume - please delete them first.\n" if !$key;
1370 $config->{$key} = $volid;
1375 PVE
::JSONSchema
::register_format
('pve-qm-bootdisk', \
&verify_bootdisk
);
1376 sub verify_bootdisk
{
1377 my ($value, $noerr) = @_;
1379 return $value if valid_drivename
($value);
1381 return undef if $noerr;
1383 die "invalid boot disk '$value'\n";
1386 PVE
::JSONSchema
::register_format
('pve-qm-net', \
&verify_net
);
1388 my ($value, $noerr) = @_;
1390 return $value if parse_net
($value);
1392 return undef if $noerr;
1394 die "unable to parse network options\n";
1397 PVE
::JSONSchema
::register_format
('pve-qm-drive', \
&verify_drive
);
1399 my ($value, $noerr) = @_;
1401 return $value if parse_drive
(undef, $value);
1403 return undef if $noerr;
1405 die "unable to parse drive options\n";
1408 PVE
::JSONSchema
::register_format
('pve-qm-hostpci', \
&verify_hostpci
);
1409 sub verify_hostpci
{
1410 my ($value, $noerr) = @_;
1412 return $value if parse_hostpci
($value);
1414 return undef if $noerr;
1416 die "unable to parse pci id\n";
1419 PVE
::JSONSchema
::register_format
('pve-qm-watchdog', \
&verify_watchdog
);
1420 sub verify_watchdog
{
1421 my ($value, $noerr) = @_;
1423 return $value if parse_watchdog
($value);
1425 return undef if $noerr;
1427 die "unable to parse watchdog options\n";
1430 sub parse_watchdog
{
1433 return undef if !$value;
1437 foreach my $p (split(/,/, $value)) {
1438 next if $p =~ m/^\s*$/;
1440 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1442 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1443 $res->{action
} = $2;
1452 PVE
::JSONSchema
::register_format
('pve-qm-startup', \
&verify_startup
);
1453 sub verify_startup
{
1454 my ($value, $noerr) = @_;
1456 return $value if parse_startup
($value);
1458 return undef if $noerr;
1460 die "unable to parse startup options\n";
1466 return undef if !$value;
1470 foreach my $p (split(/,/, $value)) {
1471 next if $p =~ m/^\s*$/;
1473 if ($p =~ m/^(order=)?(\d+)$/) {
1475 } elsif ($p =~ m/^up=(\d+)$/) {
1477 } elsif ($p =~ m/^down=(\d+)$/) {
1487 sub parse_usb_device
{
1490 return undef if !$value;
1492 my @dl = split(/,/, $value);
1496 foreach my $v (@dl) {
1497 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1499 $res->{vendorid
} = $2;
1500 $res->{productid
} = $4;
1501 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1503 $res->{hostbus
} = $1;
1504 $res->{hostport
} = $2;
1505 } elsif ($v =~ m/^spice$/) {
1512 return undef if !$found;
1517 PVE
::JSONSchema
::register_format
('pve-qm-usb-device', \
&verify_usb_device
);
1518 sub verify_usb_device
{
1519 my ($value, $noerr) = @_;
1521 return $value if parse_usb_device
($value);
1523 return undef if $noerr;
1525 die "unable to parse usb device\n";
1528 # add JSON properties for create and set function
1529 sub json_config_properties
{
1532 foreach my $opt (keys %$confdesc) {
1533 next if $opt eq 'parent' || $opt eq 'snaptime' || $opt eq 'vmstate';
1534 $prop->{$opt} = $confdesc->{$opt};
1541 my ($key, $value) = @_;
1543 die "unknown setting '$key'\n" if !$confdesc->{$key};
1545 my $type = $confdesc->{$key}->{type
};
1547 if (!defined($value)) {
1548 die "got undefined value\n";
1551 if ($value =~ m/[\n\r]/) {
1552 die "property contains a line feed\n";
1555 if ($type eq 'boolean') {
1556 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1557 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1558 die "type check ('boolean') failed - got '$value'\n";
1559 } elsif ($type eq 'integer') {
1560 return int($1) if $value =~ m/^(\d+)$/;
1561 die "type check ('integer') failed - got '$value'\n";
1562 } elsif ($type eq 'number') {
1563 return $value if $value =~ m/^(\d+)(\.\d+)?$/;
1564 die "type check ('number') failed - got '$value'\n";
1565 } elsif ($type eq 'string') {
1566 if (my $fmt = $confdesc->{$key}->{format
}) {
1567 if ($fmt eq 'pve-qm-drive') {
1568 # special case - we need to pass $key to parse_drive()
1569 my $drive = parse_drive
($key, $value);
1570 return $value if $drive;
1571 die "unable to parse drive options\n";
1573 PVE
::JSONSchema
::check_format
($fmt, $value);
1576 $value =~ s/^\"(.*)\"$/$1/;
1579 die "internal error"
1583 sub lock_config_full
{
1584 my ($vmid, $timeout, $code, @param) = @_;
1586 my $filename = config_file_lock
($vmid);
1588 my $res = lock_file
($filename, $timeout, $code, @param);
1595 sub lock_config_mode
{
1596 my ($vmid, $timeout, $shared, $code, @param) = @_;
1598 my $filename = config_file_lock
($vmid);
1600 my $res = lock_file_full
($filename, $timeout, $shared, $code, @param);
1608 my ($vmid, $code, @param) = @_;
1610 return lock_config_full
($vmid, 10, $code, @param);
1613 sub cfs_config_path
{
1614 my ($vmid, $node) = @_;
1616 $node = $nodename if !$node;
1617 return "nodes/$node/qemu-server/$vmid.conf";
1620 sub check_iommu_support
{
1621 #fixme : need to check IOMMU support
1622 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1630 my ($vmid, $node) = @_;
1632 my $cfspath = cfs_config_path
($vmid, $node);
1633 return "/etc/pve/$cfspath";
1636 sub config_file_lock
{
1639 return "$lock_dir/lock-$vmid.conf";
1645 my $conf = config_file
($vmid);
1646 utime undef, undef, $conf;
1650 my ($storecfg, $vmid, $keep_empty_config) = @_;
1652 my $conffile = config_file
($vmid);
1654 my $conf = load_config
($vmid);
1658 # only remove disks owned by this VM
1659 foreach_drive
($conf, sub {
1660 my ($ds, $drive) = @_;
1662 return if drive_is_cdrom
($drive);
1664 my $volid = $drive->{file
};
1666 return if !$volid || $volid =~ m
|^/|;
1668 my ($path, $owner) = PVE
::Storage
::path
($storecfg, $volid);
1669 return if !$path || !$owner || ($owner != $vmid);
1671 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1674 if ($keep_empty_config) {
1675 PVE
::Tools
::file_set_contents
($conffile, "memory: 128\n");
1680 # also remove unused disk
1682 my $dl = PVE
::Storage
::vdisk_list
($storecfg, undef, $vmid);
1685 PVE
::Storage
::foreach_volid
($dl, sub {
1686 my ($volid, $sid, $volname, $d) = @_;
1687 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1697 my ($vmid, $node) = @_;
1699 my $cfspath = cfs_config_path
($vmid, $node);
1701 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath);
1703 die "no such VM ('$vmid')\n" if !defined($conf);
1708 sub parse_vm_config
{
1709 my ($filename, $raw) = @_;
1711 return undef if !defined($raw);
1714 digest
=> Digest
::SHA
::sha1_hex
($raw),
1718 $filename =~ m
|/qemu-server/(\d
+)\
.conf
$|
1719 || die "got strange filename '$filename'";
1726 my @lines = split(/\n/, $raw);
1727 foreach my $line (@lines) {
1728 next if $line =~ m/^\s*$/;
1730 if ($line =~ m/^\[([a-z][a-z0-9_\-]+)\]\s*$/i) {
1732 $conf->{description
} = $descr if $descr;
1734 $conf = $res->{snapshots
}->{$snapname} = {};
1738 if ($line =~ m/^\#(.*)\s*$/) {
1739 $descr .= PVE
::Tools
::decode_text
($1) . "\n";
1743 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
1744 $descr .= PVE
::Tools
::decode_text
($2);
1745 } elsif ($line =~ m/snapstate:\s*(prepare|delete)\s*$/) {
1746 $conf->{snapstate
} = $1;
1747 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1750 $conf->{$key} = $value;
1751 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1754 eval { $value = check_type
($key, $value); };
1756 warn "vm $vmid - unable to parse value of '$key' - $@";
1758 my $fmt = $confdesc->{$key}->{format
};
1759 if ($fmt && $fmt eq 'pve-qm-drive') {
1760 my $v = parse_drive
($key, $value);
1761 if (my $volid = filename_to_volume_id
($vmid, $v->{file
}, $v->{media
})) {
1762 $v->{file
} = $volid;
1763 $value = print_drive
($vmid, $v);
1765 warn "vm $vmid - unable to parse value of '$key'\n";
1770 if ($key eq 'cdrom') {
1771 $conf->{ide2
} = $value;
1773 $conf->{$key} = $value;
1779 $conf->{description
} = $descr if $descr;
1781 delete $res->{snapstate
}; # just to be sure
1786 sub write_vm_config
{
1787 my ($filename, $conf) = @_;
1789 delete $conf->{snapstate
}; # just to be sure
1791 if ($conf->{cdrom
}) {
1792 die "option ide2 conflicts with cdrom\n" if $conf->{ide2
};
1793 $conf->{ide2
} = $conf->{cdrom
};
1794 delete $conf->{cdrom
};
1797 # we do not use 'smp' any longer
1798 if ($conf->{sockets
}) {
1799 delete $conf->{smp
};
1800 } elsif ($conf->{smp
}) {
1801 $conf->{sockets
} = $conf->{smp
};
1802 delete $conf->{cores
};
1803 delete $conf->{smp
};
1806 if ($conf->{maxcpus
} && $conf->{sockets
}) {
1807 delete $conf->{sockets
};
1810 my $used_volids = {};
1812 my $cleanup_config = sub {
1813 my ($cref, $snapname) = @_;
1815 foreach my $key (keys %$cref) {
1816 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots' ||
1817 $key eq 'snapstate';
1818 my $value = $cref->{$key};
1819 eval { $value = check_type
($key, $value); };
1820 die "unable to parse value of '$key' - $@" if $@;
1822 $cref->{$key} = $value;
1824 if (!$snapname && valid_drivename
($key)) {
1825 my $drive = parse_drive
($key, $value);
1826 $used_volids->{$drive->{file
}} = 1 if $drive && $drive->{file
};
1831 &$cleanup_config($conf);
1832 foreach my $snapname (keys %{$conf->{snapshots
}}) {
1833 &$cleanup_config($conf->{snapshots
}->{$snapname}, $snapname);
1836 # remove 'unusedX' settings if we re-add a volume
1837 foreach my $key (keys %$conf) {
1838 my $value = $conf->{$key};
1839 if ($key =~ m/^unused/ && $used_volids->{$value}) {
1840 delete $conf->{$key};
1844 my $generate_raw_config = sub {
1849 # add description as comment to top of file
1850 my $descr = $conf->{description
} || '';
1851 foreach my $cl (split(/\n/, $descr)) {
1852 $raw .= '#' . PVE
::Tools
::encode_text
($cl) . "\n";
1855 foreach my $key (sort keys %$conf) {
1856 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots';
1857 $raw .= "$key: $conf->{$key}\n";
1862 my $raw = &$generate_raw_config($conf);
1863 foreach my $snapname (sort keys %{$conf->{snapshots
}}) {
1864 $raw .= "\n[$snapname]\n";
1865 $raw .= &$generate_raw_config($conf->{snapshots
}->{$snapname});
1871 sub update_config_nolock
{
1872 my ($vmid, $conf, $skiplock) = @_;
1874 check_lock
($conf) if !$skiplock;
1876 my $cfspath = cfs_config_path
($vmid);
1878 PVE
::Cluster
::cfs_write_file
($cfspath, $conf);
1882 my ($vmid, $conf, $skiplock) = @_;
1884 lock_config
($vmid, &update_config_nolock
, $conf, $skiplock);
1891 # we use static defaults from our JSON schema configuration
1892 foreach my $key (keys %$confdesc) {
1893 if (defined(my $default = $confdesc->{$key}->{default})) {
1894 $res->{$key} = $default;
1898 my $conf = PVE
::Cluster
::cfs_read_file
('datacenter.cfg');
1899 $res->{keyboard
} = $conf->{keyboard
} if $conf->{keyboard
};
1905 my $vmlist = PVE
::Cluster
::get_vmlist
();
1907 return $res if !$vmlist || !$vmlist->{ids
};
1908 my $ids = $vmlist->{ids
};
1910 foreach my $vmid (keys %$ids) {
1911 my $d = $ids->{$vmid};
1912 next if !$d->{node
} || $d->{node
} ne $nodename;
1913 next if !$d->{type
} || $d->{type
} ne 'qemu';
1914 $res->{$vmid}->{exists} = 1;
1919 # test if VM uses local resources (to prevent migration)
1920 sub check_local_resources
{
1921 my ($conf, $noerr) = @_;
1925 $loc_res = 1 if $conf->{hostusb
}; # old syntax
1926 $loc_res = 1 if $conf->{hostpci
}; # old syntax
1928 foreach my $k (keys %$conf) {
1929 next if $k =~ m/^usb/ && ($conf->{$k} eq 'spice');
1930 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
1933 die "VM uses local resources\n" if $loc_res && !$noerr;
1938 # check if used storages are available on all nodes (use by migrate)
1939 sub check_storage_availability
{
1940 my ($storecfg, $conf, $node) = @_;
1942 foreach_drive
($conf, sub {
1943 my ($ds, $drive) = @_;
1945 my $volid = $drive->{file
};
1948 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
1951 # check if storage is available on both nodes
1952 my $scfg = PVE
::Storage
::storage_check_node
($storecfg, $sid);
1953 PVE
::Storage
::storage_check_node
($storecfg, $sid, $node);
1957 # list nodes where all VM images are available (used by has_feature API)
1959 my ($conf, $storecfg) = @_;
1961 my $nodelist = PVE
::Cluster
::get_nodelist
();
1962 my $nodehash = { map { $_ => 1 } @$nodelist };
1963 my $nodename = PVE
::INotify
::nodename
();
1965 foreach_drive
($conf, sub {
1966 my ($ds, $drive) = @_;
1968 my $volid = $drive->{file
};
1971 my ($storeid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
1973 my $scfg = PVE
::Storage
::storage_config
($storecfg, $storeid);
1974 if ($scfg->{disable
}) {
1976 } elsif (my $avail = $scfg->{nodes
}) {
1977 foreach my $node (keys %$nodehash) {
1978 delete $nodehash->{$node} if !$avail->{$node};
1980 } elsif (!$scfg->{shared
}) {
1981 foreach my $node (keys %$nodehash) {
1982 delete $nodehash->{$node} if $node ne $nodename
1994 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1998 my ($pidfile, $pid) = @_;
2000 my $fh = IO
::File-
>new("/proc/$pid/cmdline", "r");
2004 return undef if !$line;
2005 my @param = split(/\0/, $line);
2007 my $cmd = $param[0];
2008 return if !$cmd || ($cmd !~ m
|kvm
$| && $cmd !~ m
|qemu-system-x86_64
$|);
2010 for (my $i = 0; $i < scalar (@param); $i++) {
2013 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
2014 my $p = $param[$i+1];
2015 return 1 if $p && ($p eq $pidfile);
2024 my ($vmid, $nocheck, $node) = @_;
2026 my $filename = config_file
($vmid, $node);
2028 die "unable to find configuration file for VM $vmid - no such machine\n"
2029 if !$nocheck && ! -f
$filename;
2031 my $pidfile = pidfile_name
($vmid);
2033 if (my $fd = IO
::File-
>new("<$pidfile")) {
2038 my $mtime = $st->mtime;
2039 if ($mtime > time()) {
2040 warn "file '$filename' modified in future\n";
2043 if ($line =~ m/^(\d+)$/) {
2045 if (check_cmdline
($pidfile, $pid)) {
2046 if (my $pinfo = PVE
::ProcFSTools
::check_process_running
($pid)) {
2058 my $vzlist = config_list
();
2060 my $fd = IO
::Dir-
>new($var_run_tmpdir) || return $vzlist;
2062 while (defined(my $de = $fd->read)) {
2063 next if $de !~ m/^(\d+)\.pid$/;
2065 next if !defined($vzlist->{$vmid});
2066 if (my $pid = check_running
($vmid)) {
2067 $vzlist->{$vmid}->{pid
} = $pid;
2075 my ($storecfg, $conf) = @_;
2077 my $bootdisk = $conf->{bootdisk
};
2078 return undef if !$bootdisk;
2079 return undef if !valid_drivename
($bootdisk);
2081 return undef if !$conf->{$bootdisk};
2083 my $drive = parse_drive
($bootdisk, $conf->{$bootdisk});
2084 return undef if !defined($drive);
2086 return undef if drive_is_cdrom
($drive);
2088 my $volid = $drive->{file
};
2089 return undef if !$volid;
2091 return $drive->{size
};
2094 my $last_proc_pid_stat;
2096 # get VM status information
2097 # This must be fast and should not block ($full == false)
2098 # We only query KVM using QMP if $full == true (this can be slow)
2100 my ($opt_vmid, $full) = @_;
2104 my $storecfg = PVE
::Storage
::config
();
2106 my $list = vzlist
();
2107 my ($uptime) = PVE
::ProcFSTools
::read_proc_uptime
(1);
2109 my $cpucount = $cpuinfo->{cpus
} || 1;
2111 foreach my $vmid (keys %$list) {
2112 next if $opt_vmid && ($vmid ne $opt_vmid);
2114 my $cfspath = cfs_config_path
($vmid);
2115 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath) || {};
2118 $d->{pid
} = $list->{$vmid}->{pid
};
2120 # fixme: better status?
2121 $d->{status
} = $list->{$vmid}->{pid
} ?
'running' : 'stopped';
2123 my $size = disksize
($storecfg, $conf);
2124 if (defined($size)) {
2125 $d->{disk
} = 0; # no info available
2126 $d->{maxdisk
} = $size;
2132 $d->{cpus
} = ($conf->{sockets
} || 1) * ($conf->{cores
} || 1);
2133 $d->{cpus
} = $cpucount if $d->{cpus
} > $cpucount;
2135 $d->{name
} = $conf->{name
} || "VM $vmid";
2136 $d->{maxmem
} = $conf->{memory
} ?
$conf->{memory
}*(1024*1024) : 0;
2138 if ($conf->{balloon
}) {
2139 $d->{balloon_min
} = $conf->{balloon
}*(1024*1024);
2140 $d->{shares
} = defined($conf->{shares
}) ?
$conf->{shares
} : 1000;
2151 $d->{diskwrite
} = 0;
2153 $d->{template
} = is_template
($conf);
2158 my $netdev = PVE
::ProcFSTools
::read_proc_net_dev
();
2159 foreach my $dev (keys %$netdev) {
2160 next if $dev !~ m/^tap([1-9]\d*)i/;
2162 my $d = $res->{$vmid};
2165 $d->{netout
} += $netdev->{$dev}->{receive
};
2166 $d->{netin
} += $netdev->{$dev}->{transmit
};
2169 my $ctime = gettimeofday
;
2171 foreach my $vmid (keys %$list) {
2173 my $d = $res->{$vmid};
2174 my $pid = $d->{pid
};
2177 my $pstat = PVE
::ProcFSTools
::read_proc_pid_stat
($pid);
2178 next if !$pstat; # not running
2180 my $used = $pstat->{utime} + $pstat->{stime
};
2182 $d->{uptime
} = int(($uptime - $pstat->{starttime
})/$cpuinfo->{user_hz
});
2184 if ($pstat->{vsize
}) {
2185 $d->{mem
} = int(($pstat->{rss
}/$pstat->{vsize
})*$d->{maxmem
});
2188 my $old = $last_proc_pid_stat->{$pid};
2190 $last_proc_pid_stat->{$pid} = {
2198 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz
};
2200 if ($dtime > 1000) {
2201 my $dutime = $used - $old->{used
};
2203 $d->{cpu
} = (($dutime/$dtime)* $cpucount) / $d->{cpus
};
2204 $last_proc_pid_stat->{$pid} = {
2210 $d->{cpu
} = $old->{cpu
};
2214 return $res if !$full;
2216 my $qmpclient = PVE
::QMPClient-
>new();
2218 my $ballooncb = sub {
2219 my ($vmid, $resp) = @_;
2221 my $info = $resp->{'return'};
2222 return if !$info->{max_mem
};
2224 my $d = $res->{$vmid};
2226 # use memory assigned to VM
2227 $d->{maxmem
} = $info->{max_mem
};
2228 $d->{balloon
} = $info->{actual
};
2230 if (defined($info->{total_mem
}) && defined($info->{free_mem
})) {
2231 $d->{mem
} = $info->{total_mem
} - $info->{free_mem
};
2232 $d->{freemem
} = $info->{free_mem
};
2237 my $blockstatscb = sub {
2238 my ($vmid, $resp) = @_;
2239 my $data = $resp->{'return'} || [];
2240 my $totalrdbytes = 0;
2241 my $totalwrbytes = 0;
2242 for my $blockstat (@$data) {
2243 $totalrdbytes = $totalrdbytes + $blockstat->{stats
}->{rd_bytes
};
2244 $totalwrbytes = $totalwrbytes + $blockstat->{stats
}->{wr_bytes
};
2246 $res->{$vmid}->{diskread
} = $totalrdbytes;
2247 $res->{$vmid}->{diskwrite
} = $totalwrbytes;
2250 my $statuscb = sub {
2251 my ($vmid, $resp) = @_;
2253 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
2254 # this fails if ballon driver is not loaded, so this must be
2255 # the last commnand (following command are aborted if this fails).
2256 $qmpclient->queue_cmd($vmid, $ballooncb, 'query-balloon');
2258 my $status = 'unknown';
2259 if (!defined($status = $resp->{'return'}->{status
})) {
2260 warn "unable to get VM status\n";
2264 $res->{$vmid}->{qmpstatus
} = $resp->{'return'}->{status
};
2267 foreach my $vmid (keys %$list) {
2268 next if $opt_vmid && ($vmid ne $opt_vmid);
2269 next if !$res->{$vmid}->{pid
}; # not running
2270 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2273 $qmpclient->queue_execute();
2275 foreach my $vmid (keys %$list) {
2276 next if $opt_vmid && ($vmid ne $opt_vmid);
2277 $res->{$vmid}->{qmpstatus
} = $res->{$vmid}->{status
} if !$res->{$vmid}->{qmpstatus
};
2284 my ($conf, $func) = @_;
2286 foreach my $ds (keys %$conf) {
2287 next if !valid_drivename
($ds);
2289 my $drive = parse_drive
($ds, $conf->{$ds});
2292 &$func($ds, $drive);
2297 my ($conf, $func) = @_;
2301 my $test_volid = sub {
2302 my ($volid, $is_cdrom) = @_;
2306 $volhash->{$volid} = $is_cdrom || 0;
2309 foreach_drive
($conf, sub {
2310 my ($ds, $drive) = @_;
2311 &$test_volid($drive->{file
}, drive_is_cdrom
($drive));
2314 foreach my $snapname (keys %{$conf->{snapshots
}}) {
2315 my $snap = $conf->{snapshots
}->{$snapname};
2316 &$test_volid($snap->{vmstate
}, 0);
2317 foreach_drive
($snap, sub {
2318 my ($ds, $drive) = @_;
2319 &$test_volid($drive->{file
}, drive_is_cdrom
($drive));
2323 foreach my $volid (keys %$volhash) {
2324 &$func($volid, $volhash->{$volid});
2328 sub vga_conf_has_spice
{
2331 return 0 if !$vga || $vga !~ m/^qxl([234])?$/;
2336 sub config_to_command
{
2337 my ($storecfg, $vmid, $conf, $defaults, $forcemachine) = @_;
2340 my $globalFlags = [];
2341 my $machineFlags = [];
2347 my $kvmver = kvm_user_version
();
2348 my $vernum = 0; # unknown
2349 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2350 $vernum = $1*1000000+$2*1000;
2351 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
2352 $vernum = $1*1000000+$2*1000+$3;
2355 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
2357 my $have_ovz = -f
'/proc/vz/vestat';
2359 my $q35 = machine_type_is_q35
($conf);
2361 push @$cmd, '/usr/bin/kvm';
2363 push @$cmd, '-id', $vmid;
2367 my $qmpsocket = qmp_socket
($vmid);
2368 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2369 push @$cmd, '-mon', "chardev=qmp,mode=control";
2371 my $socket = vnc_socket
($vmid);
2372 push @$cmd, '-vnc', "unix:$socket,x509,password";
2374 push @$cmd, '-pidfile' , pidfile_name
($vmid);
2376 push @$cmd, '-daemonize';
2379 # the q35 chipset support native usb2, so we enable usb controller
2380 # by default for this machine type
2381 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-q35.cfg';
2383 $pciaddr = print_pci_addr
("piix3", $bridges);
2384 push @$devices, '-device', "piix3-usb-uhci,id=uhci$pciaddr.0x2";
2387 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2388 next if !$conf->{"usb$i"};
2391 # include usb device config
2392 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
2395 my $vga = $conf->{vga
};
2397 my $qxlnum = vga_conf_has_spice
($vga);
2398 $vga = 'qxl' if $qxlnum;
2401 if ($conf->{ostype
} && ($conf->{ostype
} eq 'win8' ||
2402 $conf->{ostype
} eq 'win7' ||
2403 $conf->{ostype
} eq 'w2k8')) {
2410 # enable absolute mouse coordinates (needed by vnc)
2412 if (defined($conf->{tablet
})) {
2413 $tablet = $conf->{tablet
};
2415 $tablet = $defaults->{tablet
};
2416 $tablet = 0 if $qxlnum; # disable for spice because it is not needed
2417 $tablet = 0 if $vga =~ m/^serial\d+$/; # disable if we use serial terminal (no vga card)
2420 push @$devices, '-device', print_tabletdevice_full
($conf) if $tablet;
2423 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2424 my $d = parse_hostpci
($conf->{"hostpci$i"});
2427 my $pcie = $d->{pcie
};
2429 die "q35 machine model is not enabled" if !$q35;
2430 $pciaddr = print_pcie_addr
("hostpci$i");
2432 $pciaddr = print_pci_addr
("hostpci$i", $bridges);
2435 my $rombar = $d->{rombar
} && $d->{rombar
} eq 'off' ?
",rombar=0" : "";
2436 my $driver = $d->{driver
} && $d->{driver
} eq 'vfio' ?
"vfio-pci" : "pci-assign";
2437 my $xvga = $d->{'x-vga'} && $d->{'x-vga'} eq 'on' ?
",x-vga=on" : "";
2438 $driver = "vfio-pci" if $xvga ne '';
2439 my $pcidevices = $d->{pciid
};
2440 my $multifunction = 1 if @$pcidevices > 1;
2443 foreach my $pcidevice (@$pcidevices) {
2445 my $id = "hostpci$i";
2446 $id .= ".$j" if $multifunction;
2447 my $addr = $pciaddr;
2448 $addr .= ".$j" if $multifunction;
2449 my $devicestr = "$driver,host=$pcidevice->{id}.$pcidevice->{function},id=$id$addr";
2452 $devicestr .= "$rombar$xvga";
2453 $devicestr .= ",multifunction=on" if $multifunction;
2456 push @$devices, '-device', $devicestr;
2462 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2463 my $d = parse_usb_device
($conf->{"usb$i"});
2465 if ($d->{vendorid
} && $d->{productid
}) {
2466 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
2467 } elsif (defined($d->{hostbus
}) && defined($d->{hostport
})) {
2468 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
2469 } elsif ($d->{spice
}) {
2470 # usb redir support for spice
2471 push @$devices, '-chardev', "spicevmc,id=usbredirchardev$i,name=usbredir";
2472 push @$devices, '-device', "usb-redir,chardev=usbredirchardev$i,id=usbredirdev$i,bus=ehci.0";
2477 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
2478 if (my $path = $conf->{"serial$i"}) {
2479 if ($path eq 'socket') {
2480 my $socket = "/var/run/qemu-server/${vmid}.serial$i";
2481 push @$devices, '-chardev', "socket,id=serial$i,path=$socket,server,nowait";
2482 push @$devices, '-device', "isa-serial,chardev=serial$i";
2484 die "no such serial device\n" if ! -c
$path;
2485 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2486 push @$devices, '-device', "isa-serial,chardev=serial$i";
2492 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
2493 if (my $path = $conf->{"parallel$i"}) {
2494 die "no such parallel device\n" if ! -c
$path;
2495 my $devtype = $path =~ m!^/dev/usb/lp! ?
'tty' : 'parport';
2496 push @$devices, '-chardev', "$devtype,id=parallel$i,path=$path";
2497 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
2501 my $vmname = $conf->{name
} || "vm$vmid";
2503 push @$cmd, '-name', $vmname;
2506 $sockets = $conf->{smp
} if $conf->{smp
}; # old style - no longer iused
2507 $sockets = $conf->{sockets
} if $conf->{sockets
};
2509 my $cores = $conf->{cores
} || 1;
2510 my $maxcpus = $conf->{maxcpus
} if $conf->{maxcpus
};
2513 push @$cmd, '-smp', "cpus=$cores,maxcpus=$maxcpus";
2515 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2518 push @$cmd, '-nodefaults';
2520 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
2522 my $bootindex_hash = {};
2524 foreach my $o (split(//, $bootorder)) {
2525 $bootindex_hash->{$o} = $i*100;
2529 push @$cmd, '-boot', "menu=on";
2531 push @$cmd, '-no-acpi' if defined($conf->{acpi
}) && $conf->{acpi
} == 0;
2533 push @$cmd, '-no-reboot' if defined($conf->{reboot
}) && $conf->{reboot
} == 0;
2535 push @$cmd, '-vga', $vga if $vga && $vga !~ m/^serial\d+$/; # for kvm 77 and later
2538 my $tdf = defined($conf->{tdf
}) ?
$conf->{tdf
} : $defaults->{tdf
};
2540 my $nokvm = defined($conf->{kvm
}) && $conf->{kvm
} == 0 ?
1 : 0;
2541 my $useLocaltime = $conf->{localtime};
2543 if (my $ost = $conf->{ostype
}) {
2544 # other, wxp, w2k, w2k3, w2k8, wvista, win7, win8, l24, l26, solaris
2546 if ($ost =~ m/^w/) { # windows
2547 $useLocaltime = 1 if !defined($conf->{localtime});
2549 # use time drift fix when acpi is enabled
2550 if (!(defined($conf->{acpi
}) && $conf->{acpi
} == 0)) {
2551 $tdf = 1 if !defined($conf->{tdf
});
2555 if ($ost eq 'win7' || $ost eq 'win8' || $ost eq 'w2k8' ||
2557 push @$globalFlags, 'kvm-pit.lost_tick_policy=discard';
2558 push @$cmd, '-no-hpet';
2559 #push @$cpuFlags , 'hv_vapic" if !$nokvm; #fixme, my win2008R2 hang at boot with this
2560 push @$cpuFlags , 'hv_spinlocks=0xffff' if !$nokvm;
2563 if ($ost eq 'win7' || $ost eq 'win8') {
2564 push @$cpuFlags , 'hv_relaxed' if !$nokvm;
2568 push @$rtcFlags, 'driftfix=slew' if $tdf;
2571 push @$machineFlags, 'accel=tcg';
2573 die "No accelerator found!\n" if !$cpuinfo->{hvm
};
2576 my $machine_type = $forcemachine || $conf->{machine
};
2577 if ($machine_type) {
2578 push @$machineFlags, "type=${machine_type}";
2581 if ($conf->{startdate
}) {
2582 push @$rtcFlags, "base=$conf->{startdate}";
2583 } elsif ($useLocaltime) {
2584 push @$rtcFlags, 'base=localtime';
2587 my $cpu = $nokvm ?
"qemu64" : "kvm64";
2588 $cpu = $conf->{cpu
} if $conf->{cpu
};
2590 push @$cpuFlags , '+lahf_lm' if $cpu eq 'kvm64';
2592 push @$cpuFlags , '+x2apic' if !$nokvm && $conf->{ostype
} ne 'solaris';
2594 push @$cpuFlags , '-x2apic' if $conf->{ostype
} eq 'solaris';
2596 push @$cpuFlags, '+sep' if $cpu eq 'kvm64' || $cpu eq 'kvm32';
2598 $cpu .= "," . join(',', @$cpuFlags) if scalar(@$cpuFlags);
2600 # Note: enforce needs kernel 3.10, so we do not use it for now
2601 # push @$cmd, '-cpu', "$cpu,enforce";
2602 push @$cmd, '-cpu', $cpu;
2604 push @$cmd, '-S' if $conf->{freeze
};
2606 # set keyboard layout
2607 my $kb = $conf->{keyboard
} || $defaults->{keyboard
};
2608 push @$cmd, '-k', $kb if $kb;
2611 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2612 #push @$cmd, '-soundhw', 'es1370';
2613 #push @$cmd, '-soundhw', $soundhw if $soundhw;
2615 if($conf->{agent
}) {
2616 my $qgasocket = qga_socket
($vmid);
2617 my $pciaddr = print_pci_addr
("qga0", $bridges);
2618 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
2619 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
2620 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
2627 if ($conf->{ostype
} && $conf->{ostype
} =~ m/^w/){
2628 for(my $i = 1; $i < $qxlnum; $i++){
2629 my $pciaddr = print_pci_addr
("vga$i", $bridges);
2630 push @$cmd, '-device', "qxl,id=vga$i,ram_size=67108864,vram_size=33554432$pciaddr";
2633 # assume other OS works like Linux
2634 push @$cmd, '-global', 'qxl-vga.ram_size=134217728';
2635 push @$cmd, '-global', 'qxl-vga.vram_size=67108864';
2639 my $pciaddr = print_pci_addr
("spice", $bridges);
2641 $spice_port = PVE
::Tools
::next_spice_port
();
2643 push @$cmd, '-spice', "tls-port=${spice_port},addr=127.0.0.1,tls-ciphers=DES-CBC3-SHA,seamless-migration=on";
2645 push @$cmd, '-device', "virtio-serial,id=spice$pciaddr";
2646 push @$cmd, '-chardev', "spicevmc,id=vdagent,name=vdagent";
2647 push @$cmd, '-device', "virtserialport,chardev=vdagent,name=com.redhat.spice.0";
2650 # enable balloon by default, unless explicitly disabled
2651 if (!defined($conf->{balloon
}) || $conf->{balloon
}) {
2652 $pciaddr = print_pci_addr
("balloon0", $bridges);
2653 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr";
2656 if ($conf->{watchdog
}) {
2657 my $wdopts = parse_watchdog
($conf->{watchdog
});
2658 $pciaddr = print_pci_addr
("watchdog", $bridges);
2659 my $watchdog = $wdopts->{model
} || 'i6300esb';
2660 push @$devices, '-device', "$watchdog$pciaddr";
2661 push @$devices, '-watchdog-action', $wdopts->{action
} if $wdopts->{action
};
2665 my $scsicontroller = {};
2666 my $ahcicontroller = {};
2667 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : $defaults->{scsihw
};
2669 # Add iscsi initiator name if available
2670 if (my $initiator = get_initiator_name
()) {
2671 push @$devices, '-iscsi', "initiator-name=$initiator";
2674 foreach_drive
($conf, sub {
2675 my ($ds, $drive) = @_;
2677 if (PVE
::Storage
::parse_volume_id
($drive->{file
}, 1)) {
2678 push @$vollist, $drive->{file
};
2681 $use_virtio = 1 if $ds =~ m/^virtio/;
2683 if (drive_is_cdrom
($drive)) {
2684 if ($bootindex_hash->{d
}) {
2685 $drive->{bootindex
} = $bootindex_hash->{d
};
2686 $bootindex_hash->{d
} += 1;
2689 if ($bootindex_hash->{c
}) {
2690 $drive->{bootindex
} = $bootindex_hash->{c
} if $conf->{bootdisk
} && ($conf->{bootdisk
} eq $ds);
2691 $bootindex_hash->{c
} += 1;
2695 if ($drive->{interface
} eq 'scsi') {
2697 my $maxdev = ($scsihw !~ m/^lsi/) ?
256 : 7;
2698 my $controller = int($drive->{index} / $maxdev);
2699 $pciaddr = print_pci_addr
("scsihw$controller", $bridges);
2700 push @$devices, '-device', "$scsihw,id=scsihw$controller$pciaddr" if !$scsicontroller->{$controller};
2701 $scsicontroller->{$controller}=1;
2704 if ($drive->{interface
} eq 'sata') {
2705 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
2706 $pciaddr = print_pci_addr
("ahci$controller", $bridges);
2707 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
2708 $ahcicontroller->{$controller}=1;
2711 my $drive_cmd = print_drive_full
($storecfg, $vmid, $drive);
2712 push @$devices, '-drive',$drive_cmd;
2713 push @$devices, '-device', print_drivedevice_full
($storecfg, $conf, $vmid, $drive, $bridges);
2716 push @$cmd, '-m', $conf->{memory
} || $defaults->{memory
};
2718 for (my $i = 0; $i < $MAX_NETS; $i++) {
2719 next if !$conf->{"net$i"};
2720 my $d = parse_net
($conf->{"net$i"});
2723 $use_virtio = 1 if $d->{model
} eq 'virtio';
2725 if ($bootindex_hash->{n
}) {
2726 $d->{bootindex
} = $bootindex_hash->{n
};
2727 $bootindex_hash->{n
} += 1;
2730 my $netdevfull = print_netdev_full
($vmid,$conf,$d,"net$i");
2731 push @$devices, '-netdev', $netdevfull;
2733 my $netdevicefull = print_netdevice_full
($vmid,$conf,$d,"net$i",$bridges);
2734 push @$devices, '-device', $netdevicefull;
2739 while (my ($k, $v) = each %$bridges) {
2740 $pciaddr = print_pci_addr
("pci.$k");
2741 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
2745 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2746 # when the VM uses virtio devices.
2747 if (!$use_virtio && $have_ovz) {
2749 my $cpuunits = defined($conf->{cpuunits
}) ?
2750 $conf->{cpuunits
} : $defaults->{cpuunits
};
2752 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2754 # fixme: cpulimit is currently ignored
2755 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2759 if ($conf->{args
}) {
2760 my $aa = PVE
::Tools
::split_args
($conf->{args
});
2764 push @$cmd, @$devices;
2765 push @$cmd, '-rtc', join(',', @$rtcFlags)
2766 if scalar(@$rtcFlags);
2767 push @$cmd, '-machine', join(',', @$machineFlags)
2768 if scalar(@$machineFlags);
2769 push @$cmd, '-global', join(',', @$globalFlags)
2770 if scalar(@$globalFlags);
2772 return wantarray ?
($cmd, $vollist, $spice_port) : $cmd;
2777 return "${var_run_tmpdir}/$vmid.vnc";
2783 my $res = vm_mon_cmd
($vmid, 'query-spice');
2785 return $res->{'tls-port'} || $res->{'port'} || die "no spice port\n";
2790 return "${var_run_tmpdir}/$vmid.qmp";
2795 return "${var_run_tmpdir}/$vmid.qga";
2800 return "${var_run_tmpdir}/$vmid.pid";
2803 sub vm_devices_list
{
2806 my $res = vm_mon_cmd
($vmid, 'query-pci');
2809 foreach my $pcibus (@$res) {
2810 foreach my $device (@{$pcibus->{devices
}}) {
2811 next if !$device->{'qdev_id'};
2812 $devices->{$device->{'qdev_id'}} = $device;
2820 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
2822 return 1 if !check_running
($vmid);
2824 my $q35 = machine_type_is_q35
($conf);
2826 if ($deviceid eq 'tablet') {
2827 qemu_deviceadd
($vmid, print_tabletdevice_full
($conf));
2831 return 1 if !$conf->{hotplug
};
2833 my $devices_list = vm_devices_list
($vmid);
2834 return 1 if defined($devices_list->{$deviceid});
2836 qemu_bridgeadd
($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
2838 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2839 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2840 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
2841 qemu_deviceadd
($vmid, $devicefull);
2842 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2843 qemu_drivedel
($vmid, $deviceid);
2848 if ($deviceid =~ m/^(scsihw)(\d+)$/) {
2849 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : "lsi";
2850 my $pciaddr = print_pci_addr
($deviceid);
2851 my $devicefull = "$scsihw,id=$deviceid$pciaddr";
2852 qemu_deviceadd
($vmid, $devicefull);
2853 return undef if(!qemu_deviceaddverify
($vmid, $deviceid));
2856 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2857 return 1 if ($conf->{scsihw
} && ($conf->{scsihw
} !~ m/^lsi/)); #virtio-scsi not yet support hotplug
2858 return undef if !qemu_findorcreatescsihw
($storecfg,$conf, $vmid, $device);
2859 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2860 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
2861 if(!qemu_deviceadd
($vmid, $devicefull)) {
2862 qemu_drivedel
($vmid, $deviceid);
2867 if ($deviceid =~ m/^(net)(\d+)$/) {
2868 return undef if !qemu_netdevadd
($vmid, $conf, $device, $deviceid);
2869 my $netdevicefull = print_netdevice_full
($vmid, $conf, $device, $deviceid);
2870 qemu_deviceadd
($vmid, $netdevicefull);
2871 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2872 qemu_netdevdel
($vmid, $deviceid);
2878 if (!$q35 && $deviceid =~ m/^(pci\.)(\d+)$/) {
2880 my $pciaddr = print_pci_addr
($deviceid);
2881 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
2882 qemu_deviceadd
($vmid, $devicefull);
2883 return undef if !qemu_deviceaddverify
($vmid, $deviceid);
2889 sub vm_deviceunplug
{
2890 my ($vmid, $conf, $deviceid) = @_;
2892 return 1 if !check_running
($vmid);
2894 if ($deviceid eq 'tablet') {
2895 qemu_devicedel
($vmid, $deviceid);
2899 return 1 if !$conf->{hotplug
};
2901 my $devices_list = vm_devices_list
($vmid);
2902 return 1 if !defined($devices_list->{$deviceid});
2904 die "can't unplug bootdisk" if $conf->{bootdisk
} && $conf->{bootdisk
} eq $deviceid;
2906 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2907 qemu_devicedel
($vmid, $deviceid);
2908 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2909 return undef if !qemu_drivedel
($vmid, $deviceid);
2912 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2913 return undef if !qemu_devicedel
($vmid, $deviceid);
2916 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2917 return undef if !qemu_devicedel
($vmid, $deviceid);
2918 return undef if !qemu_drivedel
($vmid, $deviceid);
2921 if ($deviceid =~ m/^(net)(\d+)$/) {
2922 qemu_devicedel
($vmid, $deviceid);
2923 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2924 return undef if !qemu_netdevdel
($vmid, $deviceid);
2930 sub qemu_deviceadd
{
2931 my ($vmid, $devicefull) = @_;
2933 $devicefull = "driver=".$devicefull;
2934 my %options = split(/[=,]/, $devicefull);
2936 vm_mon_cmd
($vmid, "device_add" , %options);
2940 sub qemu_devicedel
{
2941 my($vmid, $deviceid) = @_;
2942 my $ret = vm_mon_cmd
($vmid, "device_del", id
=> $deviceid);
2947 my($storecfg, $vmid, $device) = @_;
2949 my $drive = print_drive_full
($storecfg, $vmid, $device);
2950 my $ret = vm_human_monitor_command
($vmid, "drive_add auto $drive");
2951 # If the command succeeds qemu prints: "OK"
2952 if ($ret !~ m/OK/s) {
2953 syslog
("err", "adding drive failed: $ret");
2960 my($vmid, $deviceid) = @_;
2962 my $ret = vm_human_monitor_command
($vmid, "drive_del drive-$deviceid");
2964 if ($ret =~ m/Device \'.*?\' not found/s) {
2965 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
2967 elsif ($ret ne "") {
2968 syslog
("err", "deleting drive $deviceid failed : $ret");
2974 sub qemu_deviceaddverify
{
2975 my ($vmid,$deviceid) = @_;
2977 for (my $i = 0; $i <= 5; $i++) {
2978 my $devices_list = vm_devices_list
($vmid);
2979 return 1 if defined($devices_list->{$deviceid});
2982 syslog
("err", "error on hotplug device $deviceid");
2987 sub qemu_devicedelverify
{
2988 my ($vmid,$deviceid) = @_;
2990 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2991 for (my $i = 0; $i <= 5; $i++) {
2992 my $devices_list = vm_devices_list
($vmid);
2993 return 1 if !defined($devices_list->{$deviceid});
2996 syslog
("err", "error on hot-unplugging device $deviceid");
3000 sub qemu_findorcreatescsihw
{
3001 my ($storecfg, $conf, $vmid, $device) = @_;
3003 my $maxdev = ($conf->{scsihw
} && ($conf->{scsihw
} !~ m/^lsi/)) ?
256 : 7;
3004 my $controller = int($device->{index} / $maxdev);
3005 my $scsihwid="scsihw$controller";
3006 my $devices_list = vm_devices_list
($vmid);
3008 if(!defined($devices_list->{$scsihwid})) {
3009 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $scsihwid);
3014 sub qemu_bridgeadd
{
3015 my ($storecfg, $conf, $vmid, $device) = @_;
3018 my $bridgeid = undef;
3019 print_pci_addr
($device, $bridges);
3021 while (my ($k, $v) = each %$bridges) {
3024 return if !$bridgeid || $bridgeid < 1;
3025 my $bridge = "pci.$bridgeid";
3026 my $devices_list = vm_devices_list
($vmid);
3028 if(!defined($devices_list->{$bridge})) {
3029 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $bridge);
3034 sub qemu_netdevadd
{
3035 my ($vmid, $conf, $device, $deviceid) = @_;
3037 my $netdev = print_netdev_full
($vmid, $conf, $device, $deviceid);
3038 my %options = split(/[=,]/, $netdev);
3040 vm_mon_cmd
($vmid, "netdev_add", %options);
3044 sub qemu_netdevdel
{
3045 my ($vmid, $deviceid) = @_;
3047 vm_mon_cmd
($vmid, "netdev_del", id
=> $deviceid);
3051 sub qemu_cpu_hotplug
{
3052 my ($vmid, $conf, $cores) = @_;
3054 die "new cores config is not defined" if !$cores;
3055 die "you can't add more cores than maxcpus"
3056 if $conf->{maxcpus
} && ($cores > $conf->{maxcpus
});
3057 return if !check_running
($vmid);
3059 my $currentcores = $conf->{cores
} if $conf->{cores
};
3060 die "current cores is not defined" if !$currentcores;
3061 die "maxcpus is not defined" if !$conf->{maxcpus
};
3062 raise_param_exc
({ 'cores' => "online cpu unplug is not yet possible" })
3063 if($cores < $currentcores);
3065 my $currentrunningcores = vm_mon_cmd
($vmid, "query-cpus");
3066 raise_param_exc
({ 'cores' => "cores number if running vm is different than configuration" })
3067 if scalar (@{$currentrunningcores}) != $currentcores;
3069 for(my $i = $currentcores; $i < $cores; $i++) {
3070 vm_mon_cmd
($vmid, "cpu-add", id
=> int($i));
3074 sub qemu_block_set_io_throttle
{
3075 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
3077 return if !check_running
($vmid) ;
3079 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));
3083 # old code, only used to shutdown old VM after update
3085 my ($fh, $timeout) = @_;
3087 my $sel = new IO
::Select
;
3094 while (scalar (@ready = $sel->can_read($timeout))) {
3096 if ($count = $fh->sysread($buf, 8192)) {
3097 if ($buf =~ /^(.*)\(qemu\) $/s) {
3104 if (!defined($count)) {
3111 die "monitor read timeout\n" if !scalar(@ready);
3116 # old code, only used to shutdown old VM after update
3117 sub vm_monitor_command
{
3118 my ($vmid, $cmdstr, $nocheck) = @_;
3123 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
3125 my $sname = "${var_run_tmpdir}/$vmid.mon";
3127 my $sock = IO
::Socket
::UNIX-
>new( Peer
=> $sname ) ||
3128 die "unable to connect to VM $vmid socket - $!\n";
3132 # hack: migrate sometime blocks the monitor (when migrate_downtime
3134 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3135 $timeout = 60*60; # 1 hour
3139 my $data = __read_avail
($sock, $timeout);
3141 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
3142 die "got unexpected qemu monitor banner\n";
3145 my $sel = new IO
::Select
;
3148 if (!scalar(my @ready = $sel->can_write($timeout))) {
3149 die "monitor write error - timeout";
3152 my $fullcmd = "$cmdstr\r";
3154 # syslog('info', "VM $vmid monitor command: $cmdstr");
3157 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
3158 die "monitor write error - $!";
3161 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
3165 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3166 $timeout = 60*60; # 1 hour
3167 } elsif ($cmdstr =~ m/^(eject|change)/) {
3168 $timeout = 60; # note: cdrom mount command is slow
3170 if ($res = __read_avail
($sock, $timeout)) {
3172 my @lines = split("\r?\n", $res);
3174 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
3176 $res = join("\n", @lines);
3184 syslog
("err", "VM $vmid monitor command failed - $err");
3191 sub qemu_block_resize
{
3192 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
3194 my $running = check_running
($vmid);
3196 return if !PVE
::Storage
::volume_resize
($storecfg, $volid, $size, $running);
3198 return if !$running;
3200 vm_mon_cmd
($vmid, "block_resize", device
=> $deviceid, size
=> int($size));
3204 sub qemu_volume_snapshot
{
3205 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3207 my $running = check_running
($vmid);
3209 return if !PVE
::Storage
::volume_snapshot
($storecfg, $volid, $snap, $running);
3211 return if !$running;
3213 vm_mon_cmd
($vmid, "snapshot-drive", device
=> $deviceid, name
=> $snap);
3217 sub qemu_volume_snapshot_delete
{
3218 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3220 my $running = check_running
($vmid);
3222 return if !PVE
::Storage
::volume_snapshot_delete
($storecfg, $volid, $snap, $running);
3224 return if !$running;
3226 vm_mon_cmd
($vmid, "delete-drive-snapshot", device
=> $deviceid, name
=> $snap);
3232 #need to impplement call to qemu-ga
3235 sub qga_unfreezefs
{
3238 #need to impplement call to qemu-ga
3241 sub set_migration_caps
{
3247 "auto-converge" => 1,
3249 "x-rdma-pin-all" => 0,
3253 my $supported_capabilities = vm_mon_cmd_nocheck
($vmid, "query-migrate-capabilities");
3255 for my $supported_capability (@$supported_capabilities) {
3257 capability
=> $supported_capability->{capability
},
3258 state => $enabled_cap->{$supported_capability->{capability
}} ? JSON
::true
: JSON
::false
,
3262 vm_mon_cmd_nocheck
($vmid, "migrate-set-capabilities", capabilities
=> $cap_ref);
3266 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;
3268 lock_config
($vmid, sub {
3269 my $conf = load_config
($vmid, $migratedfrom);
3271 die "you can't start a vm if it's a template\n" if is_template
($conf);
3273 check_lock
($conf) if !$skiplock;
3275 die "VM $vmid already running\n" if check_running
($vmid, undef, $migratedfrom);
3277 my $defaults = load_defaults
();
3279 # set environment variable useful inside network script
3280 $ENV{PVE_MIGRATED_FROM
} = $migratedfrom if $migratedfrom;
3282 my ($cmd, $vollist, $spice_port) = config_to_command
($storecfg, $vmid, $conf, $defaults, $forcemachine);
3284 my $migrate_port = 0;
3287 if ($statefile eq 'tcp') {
3288 my $localip = "localhost";
3289 my $datacenterconf = PVE
::Cluster
::cfs_read_file
('datacenter.cfg');
3290 if ($datacenterconf->{migration_unsecure
}) {
3291 my $nodename = PVE
::INotify
::nodename
();
3292 $localip = PVE
::Cluster
::remote_node_ip
($nodename, 1);
3294 $migrate_port = PVE
::Tools
::next_migrate_port
();
3295 $migrate_uri = "tcp:${localip}:${migrate_port}";
3296 push @$cmd, '-incoming', $migrate_uri;
3299 push @$cmd, '-loadstate', $statefile;
3306 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
3307 my $d = parse_hostpci
($conf->{"hostpci$i"});
3309 my $pcidevices = $d->{pciid
};
3310 foreach my $pcidevice (@$pcidevices) {
3311 my $pciid = $pcidevice->{id
}.".".$pcidevice->{function
};
3313 my $info = pci_device_info
("0000:$pciid");
3314 die "IOMMU not present\n" if !check_iommu_support
();
3315 die "no pci device info for device '$pciid'\n" if !$info;
3317 if ($d->{driver
} && $d->{driver
} eq "vfio") {
3318 die "can't unbind/bind pci group to vfio '$pciid'\n" if !pci_dev_group_bind_to_vfio
($pciid);
3320 die "can't unbind/bind to stub pci device '$pciid'\n" if !pci_dev_bind_to_stub
($info);
3323 die "can't reset pci device '$pciid'\n" if !pci_dev_reset
($info);
3327 PVE
::Storage
::activate_volumes
($storecfg, $vollist);
3329 eval { run_command
($cmd, timeout
=> $statefile ?
undef : 30,
3332 die "start failed: $err" if $err;
3334 print "migration listens on $migrate_uri\n" if $migrate_uri;
3336 if ($statefile && $statefile ne 'tcp') {
3337 eval { vm_mon_cmd_nocheck
($vmid, "cont"); };
3341 if ($migratedfrom) {
3344 PVE
::QemuServer
::set_migration_caps
($vmid);
3349 print "spice listens on port $spice_port\n";
3350 if ($spice_ticket) {
3351 PVE
::QemuServer
::vm_mon_cmd_nocheck
($vmid, "set_password", protocol
=> 'spice', password
=> $spice_ticket);
3352 PVE
::QemuServer
::vm_mon_cmd_nocheck
($vmid, "expire_password", protocol
=> 'spice', time => "+30");
3358 if (!$statefile && (!defined($conf->{balloon
}) || $conf->{balloon
})) {
3359 vm_mon_cmd_nocheck
($vmid, "balloon", value
=> $conf->{balloon
}*1024*1024)
3360 if $conf->{balloon
};
3361 vm_mon_cmd_nocheck
($vmid, 'qom-set',
3362 path
=> "machine/peripheral/balloon0",
3363 property
=> "guest-stats-polling-interval",
3371 my ($vmid, $execute, %params) = @_;
3373 my $cmd = { execute
=> $execute, arguments
=> \
%params };
3374 vm_qmp_command
($vmid, $cmd);
3377 sub vm_mon_cmd_nocheck
{
3378 my ($vmid, $execute, %params) = @_;
3380 my $cmd = { execute
=> $execute, arguments
=> \
%params };
3381 vm_qmp_command
($vmid, $cmd, 1);
3384 sub vm_qmp_command
{
3385 my ($vmid, $cmd, $nocheck) = @_;
3390 if ($cmd->{arguments
} && $cmd->{arguments
}->{timeout
}) {
3391 $timeout = $cmd->{arguments
}->{timeout
};
3392 delete $cmd->{arguments
}->{timeout
};
3396 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
3397 my $sname = qmp_socket
($vmid);
3399 my $qmpclient = PVE
::QMPClient-
>new();
3401 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
3402 } elsif (-e
"${var_run_tmpdir}/$vmid.mon") {
3403 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
3404 if scalar(%{$cmd->{arguments
}});
3405 vm_monitor_command
($vmid, $cmd->{execute
}, $nocheck);
3407 die "unable to open monitor socket\n";
3411 syslog
("err", "VM $vmid qmp command failed - $err");
3418 sub vm_human_monitor_command
{
3419 my ($vmid, $cmdline) = @_;
3424 execute
=> 'human-monitor-command',
3425 arguments
=> { 'command-line' => $cmdline},
3428 return vm_qmp_command
($vmid, $cmd);
3431 sub vm_commandline
{
3432 my ($storecfg, $vmid) = @_;
3434 my $conf = load_config
($vmid);
3436 my $defaults = load_defaults
();
3438 my $cmd = config_to_command
($storecfg, $vmid, $conf, $defaults);
3440 return join(' ', @$cmd);
3444 my ($vmid, $skiplock) = @_;
3446 lock_config
($vmid, sub {
3448 my $conf = load_config
($vmid);
3450 check_lock
($conf) if !$skiplock;
3452 vm_mon_cmd
($vmid, "system_reset");
3456 sub get_vm_volumes
{
3460 foreach_volid
($conf, sub {
3461 my ($volid, $is_cdrom) = @_;
3463 return if $volid =~ m
|^/|;
3465 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
3468 push @$vollist, $volid;
3474 sub vm_stop_cleanup
{
3475 my ($storecfg, $vmid, $conf, $keepActive) = @_;
3478 fairsched_rmnod
($vmid); # try to destroy group
3481 my $vollist = get_vm_volumes
($conf);
3482 PVE
::Storage
::deactivate_volumes
($storecfg, $vollist);
3485 foreach my $ext (qw(mon qmp pid vnc qga)) {
3486 unlink "/var/run/qemu-server/${vmid}.$ext";
3489 warn $@ if $@; # avoid errors - just warn
3492 # Note: use $nockeck to skip tests if VM configuration file exists.
3493 # We need that when migration VMs to other nodes (files already moved)
3494 # Note: we set $keepActive in vzdump stop mode - volumes need to stay active
3496 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
3498 $force = 1 if !defined($force) && !$shutdown;
3501 my $pid = check_running
($vmid, $nocheck, $migratedfrom);
3502 kill 15, $pid if $pid;
3503 my $conf = load_config
($vmid, $migratedfrom);
3504 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive);
3508 lock_config
($vmid, sub {
3510 my $pid = check_running
($vmid, $nocheck);
3515 $conf = load_config
($vmid);
3516 check_lock
($conf) if !$skiplock;
3517 if (!defined($timeout) && $shutdown && $conf->{startup
}) {
3518 my $opts = parse_startup
($conf->{startup
});
3519 $timeout = $opts->{down
} if $opts->{down
};
3523 $timeout = 60 if !defined($timeout);
3527 $nocheck ? vm_mon_cmd_nocheck
($vmid, "system_powerdown") : vm_mon_cmd
($vmid, "system_powerdown");
3530 $nocheck ? vm_mon_cmd_nocheck
($vmid, "quit") : vm_mon_cmd
($vmid, "quit");
3537 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
3542 if ($count >= $timeout) {
3544 warn "VM still running - terminating now with SIGTERM\n";
3547 die "VM quit/powerdown failed - got timeout\n";
3550 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
3555 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
3558 die "VM quit/powerdown failed\n";
3566 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
3571 if ($count >= $timeout) {
3572 warn "VM still running - terminating now with SIGKILL\n";
3577 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
3582 my ($vmid, $skiplock) = @_;
3584 lock_config
($vmid, sub {
3586 my $conf = load_config
($vmid);
3588 check_lock
($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
3590 vm_mon_cmd
($vmid, "stop");
3595 my ($vmid, $skiplock) = @_;
3597 lock_config
($vmid, sub {
3599 my $conf = load_config
($vmid);
3601 check_lock
($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
3603 vm_mon_cmd
($vmid, "cont");
3608 my ($vmid, $skiplock, $key) = @_;
3610 lock_config
($vmid, sub {
3612 my $conf = load_config
($vmid);
3614 # there is no qmp command, so we use the human monitor command
3615 vm_human_monitor_command
($vmid, "sendkey $key");
3620 my ($storecfg, $vmid, $skiplock) = @_;
3622 lock_config
($vmid, sub {
3624 my $conf = load_config
($vmid);
3626 check_lock
($conf) if !$skiplock;
3628 if (!check_running
($vmid)) {
3629 fairsched_rmnod
($vmid); # try to destroy group
3630 destroy_vm
($storecfg, $vmid);
3632 die "VM $vmid is running - destroy failed\n";
3640 my ($filename, $buf) = @_;
3642 my $fh = IO
::File-
>new($filename, "w");
3643 return undef if !$fh;
3645 my $res = print $fh $buf;
3652 sub pci_device_info
{
3657 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
3658 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
3660 my $irq = file_read_firstline
("$pcisysfs/devices/$name/irq");
3661 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3663 my $vendor = file_read_firstline
("$pcisysfs/devices/$name/vendor");
3664 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3666 my $product = file_read_firstline
("$pcisysfs/devices/$name/device");
3667 return undef if !defined($product) || $product !~ s/^0x//;
3672 product
=> $product,
3678 has_fl_reset
=> -f
"$pcisysfs/devices/$name/reset" || 0,
3687 my $name = $dev->{name
};
3689 my $fn = "$pcisysfs/devices/$name/reset";
3691 return file_write
($fn, "1");
3694 sub pci_dev_bind_to_stub
{
3697 my $name = $dev->{name
};
3699 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3700 return 1 if -d
$testdir;
3702 my $data = "$dev->{vendor} $dev->{product}";
3703 return undef if !file_write
("$pcisysfs/drivers/pci-stub/new_id", $data);
3705 my $fn = "$pcisysfs/devices/$name/driver/unbind";
3706 if (!file_write
($fn, $name)) {
3707 return undef if -f
$fn;
3710 $fn = "$pcisysfs/drivers/pci-stub/bind";
3711 if (! -d
$testdir) {
3712 return undef if !file_write
($fn, $name);
3718 sub pci_dev_bind_to_vfio
{
3721 my $name = $dev->{name
};
3723 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
3725 if (!-d
$vfio_basedir) {
3726 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
3728 die "Cannot find vfio-pci module!\n" if !-d
$vfio_basedir;
3730 my $testdir = "$vfio_basedir/$name";
3731 return 1 if -d
$testdir;
3733 my $data = "$dev->{vendor} $dev->{product}";
3734 return undef if !file_write
("$vfio_basedir/new_id", $data);
3736 my $fn = "$pcisysfs/devices/$name/driver/unbind";
3737 if (!file_write
($fn, $name)) {
3738 return undef if -f
$fn;
3741 $fn = "$vfio_basedir/bind";
3742 if (! -d
$testdir) {
3743 return undef if !file_write
($fn, $name);
3749 sub pci_dev_group_bind_to_vfio
{
3752 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
3754 if (!-d
$vfio_basedir) {
3755 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
3757 die "Cannot find vfio-pci module!\n" if !-d
$vfio_basedir;
3759 # get IOMMU group devices
3760 opendir(my $D, "$pcisysfs/devices/0000:$pciid/iommu_group/devices/") || die "Cannot open iommu_group: $!\n";
3761 my @devs = grep /^0000:/, readdir($D);
3764 foreach my $pciid (@devs) {
3765 $pciid =~ m/^([:\.\da-f]+)$/ or die "PCI ID $pciid not valid!\n";
3766 my $info = pci_device_info
($1);
3767 pci_dev_bind_to_vfio
($info) || die "Cannot bind $pciid to vfio\n";
3773 sub print_pci_addr
{
3774 my ($id, $bridges) = @_;
3778 piix3
=> { bus
=> 0, addr
=> 1 },
3779 #addr2 : first videocard
3780 balloon0
=> { bus
=> 0, addr
=> 3 },
3781 watchdog
=> { bus
=> 0, addr
=> 4 },
3782 scsihw0
=> { bus
=> 0, addr
=> 5 },
3783 scsihw1
=> { bus
=> 0, addr
=> 6 },
3784 ahci0
=> { bus
=> 0, addr
=> 7 },
3785 qga0
=> { bus
=> 0, addr
=> 8 },
3786 spice
=> { bus
=> 0, addr
=> 9 },
3787 virtio0
=> { bus
=> 0, addr
=> 10 },
3788 virtio1
=> { bus
=> 0, addr
=> 11 },
3789 virtio2
=> { bus
=> 0, addr
=> 12 },
3790 virtio3
=> { bus
=> 0, addr
=> 13 },
3791 virtio4
=> { bus
=> 0, addr
=> 14 },
3792 virtio5
=> { bus
=> 0, addr
=> 15 },
3793 hostpci0
=> { bus
=> 0, addr
=> 16 },
3794 hostpci1
=> { bus
=> 0, addr
=> 17 },
3795 net0
=> { bus
=> 0, addr
=> 18 },
3796 net1
=> { bus
=> 0, addr
=> 19 },
3797 net2
=> { bus
=> 0, addr
=> 20 },
3798 net3
=> { bus
=> 0, addr
=> 21 },
3799 net4
=> { bus
=> 0, addr
=> 22 },
3800 net5
=> { bus
=> 0, addr
=> 23 },
3801 vga1
=> { bus
=> 0, addr
=> 24 },
3802 vga2
=> { bus
=> 0, addr
=> 25 },
3803 vga3
=> { bus
=> 0, addr
=> 26 },
3804 #addr29 : usb-host (pve-usb.cfg)
3805 'pci.1' => { bus
=> 0, addr
=> 30 },
3806 'pci.2' => { bus
=> 0, addr
=> 31 },
3807 'net6' => { bus
=> 1, addr
=> 1 },
3808 'net7' => { bus
=> 1, addr
=> 2 },
3809 'net8' => { bus
=> 1, addr
=> 3 },
3810 'net9' => { bus
=> 1, addr
=> 4 },
3811 'net10' => { bus
=> 1, addr
=> 5 },
3812 'net11' => { bus
=> 1, addr
=> 6 },
3813 'net12' => { bus
=> 1, addr
=> 7 },
3814 'net13' => { bus
=> 1, addr
=> 8 },
3815 'net14' => { bus
=> 1, addr
=> 9 },
3816 'net15' => { bus
=> 1, addr
=> 10 },
3817 'net16' => { bus
=> 1, addr
=> 11 },
3818 'net17' => { bus
=> 1, addr
=> 12 },
3819 'net18' => { bus
=> 1, addr
=> 13 },
3820 'net19' => { bus
=> 1, addr
=> 14 },
3821 'net20' => { bus
=> 1, addr
=> 15 },
3822 'net21' => { bus
=> 1, addr
=> 16 },
3823 'net22' => { bus
=> 1, addr
=> 17 },
3824 'net23' => { bus
=> 1, addr
=> 18 },
3825 'net24' => { bus
=> 1, addr
=> 19 },
3826 'net25' => { bus
=> 1, addr
=> 20 },
3827 'net26' => { bus
=> 1, addr
=> 21 },
3828 'net27' => { bus
=> 1, addr
=> 22 },
3829 'net28' => { bus
=> 1, addr
=> 23 },
3830 'net29' => { bus
=> 1, addr
=> 24 },
3831 'net30' => { bus
=> 1, addr
=> 25 },
3832 'net31' => { bus
=> 1, addr
=> 26 },
3833 'virtio6' => { bus
=> 2, addr
=> 1 },
3834 'virtio7' => { bus
=> 2, addr
=> 2 },
3835 'virtio8' => { bus
=> 2, addr
=> 3 },
3836 'virtio9' => { bus
=> 2, addr
=> 4 },
3837 'virtio10' => { bus
=> 2, addr
=> 5 },
3838 'virtio11' => { bus
=> 2, addr
=> 6 },
3839 'virtio12' => { bus
=> 2, addr
=> 7 },
3840 'virtio13' => { bus
=> 2, addr
=> 8 },
3841 'virtio14' => { bus
=> 2, addr
=> 9 },
3842 'virtio15' => { bus
=> 2, addr
=> 10 },
3845 if (defined($devices->{$id}->{bus
}) && defined($devices->{$id}->{addr
})) {
3846 my $addr = sprintf("0x%x", $devices->{$id}->{addr
});
3847 my $bus = $devices->{$id}->{bus
};
3848 $res = ",bus=pci.$bus,addr=$addr";
3849 $bridges->{$bus} = 1 if $bridges;
3855 sub print_pcie_addr
{
3860 hostpci0
=> { bus
=> "ich9-pcie-port-1", addr
=> 0 },
3861 hostpci1
=> { bus
=> "ich9-pcie-port-2", addr
=> 0 },
3862 hostpci2
=> { bus
=> "ich9-pcie-port-3", addr
=> 0 },
3863 hostpci3
=> { bus
=> "ich9-pcie-port-4", addr
=> 0 },
3866 if (defined($devices->{$id}->{bus
}) && defined($devices->{$id}->{addr
})) {
3867 my $addr = sprintf("0x%x", $devices->{$id}->{addr
});
3868 my $bus = $devices->{$id}->{bus
};
3869 $res = ",bus=$bus,addr=$addr";
3875 # vzdump restore implementaion
3877 sub tar_archive_read_firstfile
{
3878 my $archive = shift;
3880 die "ERROR: file '$archive' does not exist\n" if ! -f
$archive;
3882 # try to detect archive type first
3883 my $pid = open (TMP
, "tar tf '$archive'|") ||
3884 die "unable to open file '$archive'\n";
3885 my $firstfile = <TMP
>;
3889 die "ERROR: archive contaions no data\n" if !$firstfile;
3895 sub tar_restore_cleanup
{
3896 my ($storecfg, $statfile) = @_;
3898 print STDERR
"starting cleanup\n";
3900 if (my $fd = IO
::File-
>new($statfile, "r")) {
3901 while (defined(my $line = <$fd>)) {
3902 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3905 if ($volid =~ m
|^/|) {
3906 unlink $volid || die 'unlink failed\n';
3908 PVE
::Storage
::vdisk_free
($storecfg, $volid);
3910 print STDERR
"temporary volume '$volid' sucessfuly removed\n";
3912 print STDERR
"unable to cleanup '$volid' - $@" if $@;
3914 print STDERR
"unable to parse line in statfile - $line";
3921 sub restore_archive
{
3922 my ($archive, $vmid, $user, $opts) = @_;
3924 my $format = $opts->{format
};
3927 if ($archive =~ m/\.tgz$/ || $archive =~ m/\.tar\.gz$/) {
3928 $format = 'tar' if !$format;
3930 } elsif ($archive =~ m/\.tar$/) {
3931 $format = 'tar' if !$format;
3932 } elsif ($archive =~ m/.tar.lzo$/) {
3933 $format = 'tar' if !$format;
3935 } elsif ($archive =~ m/\.vma$/) {
3936 $format = 'vma' if !$format;
3937 } elsif ($archive =~ m/\.vma\.gz$/) {
3938 $format = 'vma' if !$format;
3940 } elsif ($archive =~ m/\.vma\.lzo$/) {
3941 $format = 'vma' if !$format;
3944 $format = 'vma' if !$format; # default
3947 # try to detect archive format
3948 if ($format eq 'tar') {
3949 return restore_tar_archive
($archive, $vmid, $user, $opts);
3951 return restore_vma_archive
($archive, $vmid, $user, $opts, $comp);
3955 sub restore_update_config_line
{
3956 my ($outfd, $cookie, $vmid, $map, $line, $unique) = @_;
3958 return if $line =~ m/^\#qmdump\#/;
3959 return if $line =~ m/^\#vzdump\#/;
3960 return if $line =~ m/^lock:/;
3961 return if $line =~ m/^unused\d+:/;
3962 return if $line =~ m/^parent:/;
3963 return if $line =~ m/^template:/; # restored VM is never a template
3965 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3966 # try to convert old 1.X settings
3967 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3968 foreach my $devconfig (PVE
::Tools
::split_list
($ethcfg)) {
3969 my ($model, $macaddr) = split(/\=/, $devconfig);
3970 $macaddr = PVE
::Tools
::random_ether_addr
() if !$macaddr || $unique;
3973 bridge
=> "vmbr$ind",
3974 macaddr
=> $macaddr,
3976 my $netstr = print_net
($net);
3978 print $outfd "net$cookie->{netcount}: $netstr\n";
3979 $cookie->{netcount
}++;
3981 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && $unique) {
3982 my ($id, $netstr) = ($1, $2);
3983 my $net = parse_net
($netstr);
3984 $net->{macaddr
} = PVE
::Tools
::random_ether_addr
() if $net->{macaddr
};
3985 $netstr = print_net
($net);
3986 print $outfd "$id: $netstr\n";
3987 } elsif ($line =~ m/^((ide|scsi|virtio|sata)\d+):\s*(\S+)\s*$/) {
3990 if ($line =~ m/backup=no/) {
3991 print $outfd "#$line";
3992 } elsif ($virtdev && $map->{$virtdev}) {
3993 my $di = parse_drive
($virtdev, $value);
3994 delete $di->{format
}; # format can change on restore
3995 $di->{file
} = $map->{$virtdev};
3996 $value = print_drive
($vmid, $di);
3997 print $outfd "$virtdev: $value\n";
4007 my ($cfg, $vmid) = @_;
4009 my $info = PVE
::Storage
::vdisk_list
($cfg, undef, $vmid);
4011 my $volid_hash = {};
4012 foreach my $storeid (keys %$info) {
4013 foreach my $item (@{$info->{$storeid}}) {
4014 next if !($item->{volid
} && $item->{size
});
4015 $item->{path
} = PVE
::Storage
::path
($cfg, $item->{volid
});
4016 $volid_hash->{$item->{volid
}} = $item;
4023 sub get_used_paths
{
4024 my ($vmid, $storecfg, $conf, $scan_snapshots, $skip_drive) = @_;
4028 my $scan_config = sub {
4029 my ($cref, $snapname) = @_;
4031 foreach my $key (keys %$cref) {
4032 my $value = $cref->{$key};
4033 if (valid_drivename
($key)) {
4034 next if $skip_drive && $key eq $skip_drive;
4035 my $drive = parse_drive
($key, $value);
4036 next if !$drive || !$drive->{file
} || drive_is_cdrom
($drive);
4037 if ($drive->{file
} =~ m!^/!) {
4038 $used_path->{$drive->{file
}}++; # = 1;
4040 my ($storeid, $volname) = PVE
::Storage
::parse_volume_id
($drive->{file
}, 1);
4042 my $scfg = PVE
::Storage
::storage_config
($storecfg, $storeid, 1);
4044 my $path = PVE
::Storage
::path
($storecfg, $drive->{file
}, $snapname);
4045 $used_path->{$path}++; # = 1;
4051 &$scan_config($conf);
4055 if ($scan_snapshots) {
4056 foreach my $snapname (keys %{$conf->{snapshots
}}) {
4057 &$scan_config($conf->{snapshots
}->{$snapname}, $snapname);
4064 sub update_disksize
{
4065 my ($vmid, $conf, $volid_hash) = @_;
4071 # Note: it is allowed to define multiple storages with same path (alias), so
4072 # we need to check both 'volid' and real 'path' (two different volid can point
4073 # to the same path).
4078 foreach my $opt (keys %$conf) {
4079 if (valid_drivename
($opt)) {
4080 my $drive = parse_drive
($opt, $conf->{$opt});
4081 my $volid = $drive->{file
};
4084 $used->{$volid} = 1;
4085 if ($volid_hash->{$volid} &&
4086 (my $path = $volid_hash->{$volid}->{path
})) {
4087 $usedpath->{$path} = 1;
4090 next if drive_is_cdrom
($drive);
4091 next if !$volid_hash->{$volid};
4093 $drive->{size
} = $volid_hash->{$volid}->{size
};
4094 my $new = print_drive
($vmid, $drive);
4095 if ($new ne $conf->{$opt}) {
4097 $conf->{$opt} = $new;
4102 # remove 'unusedX' entry if volume is used
4103 foreach my $opt (keys %$conf) {
4104 next if $opt !~ m/^unused\d+$/;
4105 my $volid = $conf->{$opt};
4106 my $path = $volid_hash->{$volid}->{path
} if $volid_hash->{$volid};
4107 if ($used->{$volid} || ($path && $usedpath->{$path})) {
4109 delete $conf->{$opt};
4113 foreach my $volid (sort keys %$volid_hash) {
4114 next if $volid =~ m/vm-$vmid-state-/;
4115 next if $used->{$volid};
4116 my $path = $volid_hash->{$volid}->{path
};
4117 next if !$path; # just to be sure
4118 next if $usedpath->{$path};
4120 add_unused_volume
($conf, $volid);
4121 $usedpath->{$path} = 1; # avoid to add more than once (aliases)
4128 my ($vmid, $nolock) = @_;
4130 my $cfg = PVE
::Cluster
::cfs_read_file
("storage.cfg");
4132 my $volid_hash = scan_volids
($cfg, $vmid);
4134 my $updatefn = sub {
4137 my $conf = load_config
($vmid);
4142 foreach my $volid (keys %$volid_hash) {
4143 my $info = $volid_hash->{$volid};
4144 $vm_volids->{$volid} = $info if $info->{vmid
} && $info->{vmid
} == $vmid;
4147 my $changes = update_disksize
($vmid, $conf, $vm_volids);
4149 update_config_nolock
($vmid, $conf, 1) if $changes;
4152 if (defined($vmid)) {
4156 lock_config
($vmid, $updatefn, $vmid);
4159 my $vmlist = config_list
();
4160 foreach my $vmid (keys %$vmlist) {
4164 lock_config
($vmid, $updatefn, $vmid);
4170 sub restore_vma_archive
{
4171 my ($archive, $vmid, $user, $opts, $comp) = @_;
4173 my $input = $archive eq '-' ?
"<&STDIN" : undef;
4174 my $readfrom = $archive;
4179 my $qarchive = PVE
::Tools
::shellquote
($archive);
4180 if ($comp eq 'gzip') {
4181 $uncomp = "zcat $qarchive|";
4182 } elsif ($comp eq 'lzop') {
4183 $uncomp = "lzop -d -c $qarchive|";
4185 die "unknown compression method '$comp'\n";
4190 my $tmpdir = "/var/tmp/vzdumptmp$$";
4193 # disable interrupts (always do cleanups)
4194 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
4195 warn "got interrupt - ignored\n";
4198 my $mapfifo = "/var/tmp/vzdumptmp$$.fifo";
4199 POSIX
::mkfifo
($mapfifo, 0600);
4202 my $openfifo = sub {
4203 open($fifofh, '>', $mapfifo) || die $!;
4206 my $cmd = "${uncomp}vma extract -v -r $mapfifo $readfrom $tmpdir";
4213 my $rpcenv = PVE
::RPCEnvironment
::get
();
4215 my $conffile = config_file
($vmid);
4216 my $tmpfn = "$conffile.$$.tmp";
4218 # Note: $oldconf is undef if VM does not exists
4219 my $oldconf = PVE
::Cluster
::cfs_read_file
(cfs_config_path
($vmid));
4221 my $print_devmap = sub {
4222 my $virtdev_hash = {};
4224 my $cfgfn = "$tmpdir/qemu-server.conf";
4226 # we can read the config - that is already extracted
4227 my $fh = IO
::File-
>new($cfgfn, "r") ||
4228 "unable to read qemu-server.conf - $!\n";
4230 while (defined(my $line = <$fh>)) {
4231 if ($line =~ m/^\#qmdump\#map:(\S+):(\S+):(\S*):(\S*):$/) {
4232 my ($virtdev, $devname, $storeid, $format) = ($1, $2, $3, $4);
4233 die "archive does not contain data for drive '$virtdev'\n"
4234 if !$devinfo->{$devname};
4235 if (defined($opts->{storage
})) {
4236 $storeid = $opts->{storage
} || 'local';
4237 } elsif (!$storeid) {
4240 $format = 'raw' if !$format;
4241 $devinfo->{$devname}->{devname
} = $devname;
4242 $devinfo->{$devname}->{virtdev
} = $virtdev;
4243 $devinfo->{$devname}->{format
} = $format;
4244 $devinfo->{$devname}->{storeid
} = $storeid;
4246 # check permission on storage
4247 my $pool = $opts->{pool
}; # todo: do we need that?
4248 if ($user ne 'root@pam') {
4249 $rpcenv->check($user, "/storage/$storeid", ['Datastore.AllocateSpace']);
4252 $virtdev_hash->{$virtdev} = $devinfo->{$devname};
4256 foreach my $devname (keys %$devinfo) {
4257 die "found no device mapping information for device '$devname'\n"
4258 if !$devinfo->{$devname}->{virtdev
};
4261 my $cfg = cfs_read_file
('storage.cfg');
4263 # create empty/temp config
4265 PVE
::Tools
::file_set_contents
($conffile, "memory: 128\n");
4266 foreach_drive
($oldconf, sub {
4267 my ($ds, $drive) = @_;
4269 return if drive_is_cdrom
($drive);
4271 my $volid = $drive->{file
};
4273 return if !$volid || $volid =~ m
|^/|;
4275 my ($path, $owner) = PVE
::Storage
::path
($cfg, $volid);
4276 return if !$path || !$owner || ($owner != $vmid);
4278 # Note: only delete disk we want to restore
4279 # other volumes will become unused
4280 if ($virtdev_hash->{$ds}) {
4281 PVE
::Storage
::vdisk_free
($cfg, $volid);
4287 foreach my $virtdev (sort keys %$virtdev_hash) {
4288 my $d = $virtdev_hash->{$virtdev};
4289 my $alloc_size = int(($d->{size
} + 1024 - 1)/1024);
4290 my $scfg = PVE
::Storage
::storage_config
($cfg, $d->{storeid
});
4292 # test if requested format is supported
4293 my ($defFormat, $validFormats) = PVE
::Storage
::storage_default_format
($cfg, $d->{storeid
});
4294 my $supported = grep { $_ eq $d->{format
} } @$validFormats;
4295 $d->{format
} = $defFormat if !$supported;
4297 my $volid = PVE
::Storage
::vdisk_alloc
($cfg, $d->{storeid
}, $vmid,
4298 $d->{format
}, undef, $alloc_size);
4299 print STDERR
"new volume ID is '$volid'\n";
4300 $d->{volid
} = $volid;
4301 my $path = PVE
::Storage
::path
($cfg, $volid);
4303 my $write_zeros = 1;
4304 # fixme: what other storages types initialize volumes with zero?
4305 if ($scfg->{type
} eq 'dir' || $scfg->{type
} eq 'nfs' || $scfg->{type
} eq 'glusterfs' ||
4306 $scfg->{type
} eq 'sheepdog' || $scfg->{type
} eq 'rbd') {
4310 print $fifofh "${write_zeros}:$d->{devname}=$path\n";
4312 print "map '$d->{devname}' to '$path' (write zeros = ${write_zeros})\n";
4313 $map->{$virtdev} = $volid;
4316 $fh->seek(0, 0) || die "seek failed - $!\n";
4318 my $outfd = new IO
::File
($tmpfn, "w") ||
4319 die "unable to write config for VM $vmid\n";
4321 my $cookie = { netcount
=> 0 };
4322 while (defined(my $line = <$fh>)) {
4323 restore_update_config_line
($outfd, $cookie, $vmid, $map, $line, $opts->{unique
});
4332 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
4333 die "interrupted by signal\n";
4335 local $SIG{ALRM
} = sub { die "got timeout\n"; };
4337 $oldtimeout = alarm($timeout);
4344 if ($line =~ m/^DEV:\sdev_id=(\d+)\ssize:\s(\d+)\sdevname:\s(\S+)$/) {
4345 my ($dev_id, $size, $devname) = ($1, $2, $3);
4346 $devinfo->{$devname} = { size
=> $size, dev_id
=> $dev_id };
4347 } elsif ($line =~ m/^CTIME: /) {
4348 # we correctly received the vma config, so we can disable
4349 # the timeout now for disk allocation (set to 10 minutes, so
4350 # that we always timeout if something goes wrong)
4353 print $fifofh "done\n";
4354 my $tmp = $oldtimeout || 0;
4355 $oldtimeout = undef;
4361 print "restore vma archive: $cmd\n";
4362 run_command
($cmd, input
=> $input, outfunc
=> $parser, afterfork
=> $openfifo);
4366 alarm($oldtimeout) if $oldtimeout;
4374 my $cfg = cfs_read_file
('storage.cfg');
4375 foreach my $devname (keys %$devinfo) {
4376 my $volid = $devinfo->{$devname}->{volid
};
4379 if ($volid =~ m
|^/|) {
4380 unlink $volid || die 'unlink failed\n';
4382 PVE
::Storage
::vdisk_free
($cfg, $volid);
4384 print STDERR
"temporary volume '$volid' sucessfuly removed\n";
4386 print STDERR
"unable to cleanup '$volid' - $@" if $@;
4393 rename($tmpfn, $conffile) ||
4394 die "unable to commit configuration file '$conffile'\n";
4396 PVE
::Cluster
::cfs_update
(); # make sure we read new file
4398 eval { rescan
($vmid, 1); };
4402 sub restore_tar_archive
{
4403 my ($archive, $vmid, $user, $opts) = @_;
4405 if ($archive ne '-') {
4406 my $firstfile = tar_archive_read_firstfile
($archive);
4407 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
4408 if $firstfile ne 'qemu-server.conf';
4411 my $storecfg = cfs_read_file
('storage.cfg');
4413 # destroy existing data - keep empty config
4414 my $vmcfgfn = PVE
::QemuServer
::config_file
($vmid);
4415 destroy_vm
($storecfg, $vmid, 1) if -f
$vmcfgfn;
4417 my $tocmd = "/usr/lib/qemu-server/qmextract";
4419 $tocmd .= " --storage " . PVE
::Tools
::shellquote
($opts->{storage
}) if $opts->{storage
};
4420 $tocmd .= " --pool " . PVE
::Tools
::shellquote
($opts->{pool
}) if $opts->{pool
};
4421 $tocmd .= ' --prealloc' if $opts->{prealloc
};
4422 $tocmd .= ' --info' if $opts->{info
};
4424 # tar option "xf" does not autodetect compression when read from STDIN,
4425 # so we pipe to zcat
4426 my $cmd = "zcat -f|tar xf " . PVE
::Tools
::shellquote
($archive) . " " .
4427 PVE
::Tools
::shellquote
("--to-command=$tocmd");
4429 my $tmpdir = "/var/tmp/vzdumptmp$$";
4432 local $ENV{VZDUMP_TMPDIR
} = $tmpdir;
4433 local $ENV{VZDUMP_VMID
} = $vmid;
4434 local $ENV{VZDUMP_USER
} = $user;
4436 my $conffile = config_file
($vmid);
4437 my $tmpfn = "$conffile.$$.tmp";
4439 # disable interrupts (always do cleanups)
4440 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
4441 print STDERR
"got interrupt - ignored\n";
4446 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
4447 die "interrupted by signal\n";
4450 if ($archive eq '-') {
4451 print "extracting archive from STDIN\n";
4452 run_command
($cmd, input
=> "<&STDIN");
4454 print "extracting archive '$archive'\n";
4458 return if $opts->{info
};
4462 my $statfile = "$tmpdir/qmrestore.stat";
4463 if (my $fd = IO
::File-
>new($statfile, "r")) {
4464 while (defined (my $line = <$fd>)) {
4465 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
4466 $map->{$1} = $2 if $1;
4468 print STDERR
"unable to parse line in statfile - $line\n";
4474 my $confsrc = "$tmpdir/qemu-server.conf";
4476 my $srcfd = new IO
::File
($confsrc, "r") ||
4477 die "unable to open file '$confsrc'\n";
4479 my $outfd = new IO
::File
($tmpfn, "w") ||
4480 die "unable to write config for VM $vmid\n";
4482 my $cookie = { netcount
=> 0 };
4483 while (defined (my $line = <$srcfd>)) {
4484 restore_update_config_line
($outfd, $cookie, $vmid, $map, $line, $opts->{unique
});
4496 tar_restore_cleanup
($storecfg, "$tmpdir/qmrestore.stat") if !$opts->{info
};
4503 rename $tmpfn, $conffile ||
4504 die "unable to commit configuration file '$conffile'\n";
4506 PVE
::Cluster
::cfs_update
(); # make sure we read new file
4508 eval { rescan
($vmid, 1); };
4513 # Internal snapshots
4515 # NOTE: Snapshot create/delete involves several non-atomic
4516 # action, and can take a long time.
4517 # So we try to avoid locking the file and use 'lock' variable
4518 # inside the config file instead.
4520 my $snapshot_copy_config = sub {
4521 my ($source, $dest) = @_;
4523 foreach my $k (keys %$source) {
4524 next if $k eq 'snapshots';
4525 next if $k eq 'snapstate';
4526 next if $k eq 'snaptime';
4527 next if $k eq 'vmstate';
4528 next if $k eq 'lock';
4529 next if $k eq 'digest';
4530 next if $k eq 'description';
4531 next if $k =~ m/^unused\d+$/;
4533 $dest->{$k} = $source->{$k};
4537 my $snapshot_apply_config = sub {
4538 my ($conf, $snap) = @_;
4540 # copy snapshot list
4542 snapshots
=> $conf->{snapshots
},
4545 # keep description and list of unused disks
4546 foreach my $k (keys %$conf) {
4547 next if !($k =~ m/^unused\d+$/ || $k eq 'description');
4548 $newconf->{$k} = $conf->{$k};
4551 &$snapshot_copy_config($snap, $newconf);
4556 sub foreach_writable_storage
{
4557 my ($conf, $func) = @_;
4561 foreach my $ds (keys %$conf) {
4562 next if !valid_drivename
($ds);
4564 my $drive = parse_drive
($ds, $conf->{$ds});
4566 next if drive_is_cdrom
($drive);
4568 my $volid = $drive->{file
};
4570 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
4571 $sidhash->{$sid} = $sid if $sid;
4574 foreach my $sid (sort keys %$sidhash) {
4579 my $alloc_vmstate_volid = sub {
4580 my ($storecfg, $vmid, $conf, $snapname) = @_;
4582 # Note: we try to be smart when selecting a $target storage
4586 # search shared storage first
4587 foreach_writable_storage
($conf, sub {
4589 my $scfg = PVE
::Storage
::storage_config
($storecfg, $sid);
4590 return if !$scfg->{shared
};
4592 $target = $sid if !$target || $scfg->{path
}; # prefer file based storage
4596 # now search local storage
4597 foreach_writable_storage
($conf, sub {
4599 my $scfg = PVE
::Storage
::storage_config
($storecfg, $sid);
4600 return if $scfg->{shared
};
4602 $target = $sid if !$target || $scfg->{path
}; # prefer file based storage;
4606 $target = 'local' if !$target;
4608 my $driver_state_size = 500; # assume 32MB is enough to safe all driver state;
4609 # we abort live save after $conf->{memory}, so we need at max twice that space
4610 my $size = $conf->{memory
}*2 + $driver_state_size;
4612 my $name = "vm-$vmid-state-$snapname";
4613 my $scfg = PVE
::Storage
::storage_config
($storecfg, $target);
4614 $name .= ".raw" if $scfg->{path
}; # add filename extension for file base storage
4615 my $volid = PVE
::Storage
::vdisk_alloc
($storecfg, $target, $vmid, 'raw', $name, $size*1024);
4620 my $snapshot_prepare = sub {
4621 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
4625 my $updatefn = sub {
4627 my $conf = load_config
($vmid);
4629 die "you can't take a snapshot if it's a template\n"
4630 if is_template
($conf);
4634 $conf->{lock} = 'snapshot';
4636 die "snapshot name '$snapname' already used\n"
4637 if defined($conf->{snapshots
}->{$snapname});
4639 my $storecfg = PVE
::Storage
::config
();
4640 die "snapshot feature is not available" if !has_feature
('snapshot', $conf, $storecfg);
4642 $snap = $conf->{snapshots
}->{$snapname} = {};
4644 if ($save_vmstate && check_running
($vmid)) {
4645 $snap->{vmstate
} = &$alloc_vmstate_volid($storecfg, $vmid, $conf, $snapname);
4648 &$snapshot_copy_config($conf, $snap);
4650 $snap->{snapstate
} = "prepare";
4651 $snap->{snaptime
} = time();
4652 $snap->{description
} = $comment if $comment;
4654 # always overwrite machine if we save vmstate. This makes sure we
4655 # can restore it later using correct machine type
4656 $snap->{machine
} = get_current_qemu_machine
($vmid) if $snap->{vmstate
};
4658 update_config_nolock
($vmid, $conf, 1);
4661 lock_config
($vmid, $updatefn);
4666 my $snapshot_commit = sub {
4667 my ($vmid, $snapname) = @_;
4669 my $updatefn = sub {
4671 my $conf = load_config
($vmid);
4673 die "missing snapshot lock\n"
4674 if !($conf->{lock} && $conf->{lock} eq 'snapshot');
4676 my $snap = $conf->{snapshots
}->{$snapname};
4678 die "snapshot '$snapname' does not exist\n" if !defined($snap);
4680 die "wrong snapshot state\n"
4681 if !($snap->{snapstate
} && $snap->{snapstate
} eq "prepare");
4683 delete $snap->{snapstate
};
4684 delete $conf->{lock};
4686 my $newconf = &$snapshot_apply_config($conf, $snap);
4688 $newconf->{parent
} = $snapname;
4690 update_config_nolock
($vmid, $newconf, 1);
4693 lock_config
($vmid, $updatefn);
4696 sub snapshot_rollback
{
4697 my ($vmid, $snapname) = @_;
4703 my $storecfg = PVE
::Storage
::config
();
4705 my $updatefn = sub {
4707 my $conf = load_config
($vmid);
4709 die "you can't rollback if vm is a template\n" if is_template
($conf);
4711 $snap = $conf->{snapshots
}->{$snapname};
4713 die "snapshot '$snapname' does not exist\n" if !defined($snap);
4715 die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
4716 if $snap->{snapstate
};
4720 vm_stop
($storecfg, $vmid, undef, undef, 5, undef, undef);
4723 die "unable to rollback vm $vmid: vm is running\n"
4724 if check_running
($vmid);
4727 $conf->{lock} = 'rollback';
4729 die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
4730 delete $conf->{lock};
4736 my $has_machine_config = defined($conf->{machine
});
4738 # copy snapshot config to current config
4739 $conf = &$snapshot_apply_config($conf, $snap);
4740 $conf->{parent
} = $snapname;
4742 # Note: old code did not store 'machine', so we try to be smart
4743 # and guess the snapshot was generated with kvm 1.4 (pc-i440fx-1.4).
4744 $forcemachine = $conf->{machine
} || 'pc-i440fx-1.4';
4745 # we remove the 'machine' configuration if not explicitly specified
4746 # in the original config.
4747 delete $conf->{machine
} if $snap->{vmstate
} && !$has_machine_config;
4750 update_config_nolock
($vmid, $conf, 1);
4752 if (!$prepare && $snap->{vmstate
}) {
4753 my $statefile = PVE
::Storage
::path
($storecfg, $snap->{vmstate
});
4754 vm_start
($storecfg, $vmid, $statefile, undef, undef, undef, $forcemachine);
4758 lock_config
($vmid, $updatefn);
4760 foreach_drive
($snap, sub {
4761 my ($ds, $drive) = @_;
4763 return if drive_is_cdrom
($drive);
4765 my $volid = $drive->{file
};
4766 my $device = "drive-$ds";
4768 PVE
::Storage
::volume_snapshot_rollback
($storecfg, $volid, $snapname);
4772 lock_config
($vmid, $updatefn);
4775 my $savevm_wait = sub {
4779 my $stat = vm_mon_cmd_nocheck
($vmid, "query-savevm");
4780 if (!$stat->{status
}) {
4781 die "savevm not active\n";
4782 } elsif ($stat->{status
} eq 'active') {
4785 } elsif ($stat->{status
} eq 'completed') {
4788 die "query-savevm returned status '$stat->{status}'\n";
4793 sub snapshot_create
{
4794 my ($vmid, $snapname, $save_vmstate, $freezefs, $comment) = @_;
4796 my $snap = &$snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
4798 $freezefs = $save_vmstate = 0 if !$snap->{vmstate
}; # vm is not running
4802 my $running = check_running
($vmid);
4805 # create internal snapshots of all drives
4807 my $storecfg = PVE
::Storage
::config
();
4810 if ($snap->{vmstate
}) {
4811 my $path = PVE
::Storage
::path
($storecfg, $snap->{vmstate
});
4812 vm_mon_cmd
($vmid, "savevm-start", statefile
=> $path);
4813 &$savevm_wait($vmid);
4815 vm_mon_cmd
($vmid, "savevm-start");
4819 qga_freezefs
($vmid) if $running && $freezefs;
4821 foreach_drive
($snap, sub {
4822 my ($ds, $drive) = @_;
4824 return if drive_is_cdrom
($drive);
4826 my $volid = $drive->{file
};
4827 my $device = "drive-$ds";
4829 qemu_volume_snapshot
($vmid, $device, $storecfg, $volid, $snapname);
4830 $drivehash->{$ds} = 1;
4835 eval { qga_unfreezefs
($vmid) if $running && $freezefs; };
4838 eval { vm_mon_cmd
($vmid, "savevm-end") if $running; };
4842 warn "snapshot create failed: starting cleanup\n";
4843 eval { snapshot_delete
($vmid, $snapname, 0, $drivehash); };
4848 &$snapshot_commit($vmid, $snapname);
4851 # Note: $drivehash is only set when called from snapshot_create.
4852 sub snapshot_delete
{
4853 my ($vmid, $snapname, $force, $drivehash) = @_;
4860 my $unlink_parent = sub {
4861 my ($confref, $new_parent) = @_;
4863 if ($confref->{parent
} && $confref->{parent
} eq $snapname) {
4865 $confref->{parent
} = $new_parent;
4867 delete $confref->{parent
};
4872 my $updatefn = sub {
4873 my ($remove_drive) = @_;
4875 my $conf = load_config
($vmid);
4879 die "you can't delete a snapshot if vm is a template\n"
4880 if is_template
($conf);
4883 $snap = $conf->{snapshots
}->{$snapname};
4885 die "snapshot '$snapname' does not exist\n" if !defined($snap);
4887 # remove parent refs
4888 &$unlink_parent($conf, $snap->{parent
});
4889 foreach my $sn (keys %{$conf->{snapshots
}}) {
4890 next if $sn eq $snapname;
4891 &$unlink_parent($conf->{snapshots
}->{$sn}, $snap->{parent
});
4894 if ($remove_drive) {
4895 if ($remove_drive eq 'vmstate') {
4896 delete $snap->{$remove_drive};
4898 my $drive = parse_drive
($remove_drive, $snap->{$remove_drive});
4899 my $volid = $drive->{file
};
4900 delete $snap->{$remove_drive};
4901 add_unused_volume
($conf, $volid);
4906 $snap->{snapstate
} = 'delete';
4908 delete $conf->{snapshots
}->{$snapname};
4909 delete $conf->{lock} if $drivehash;
4910 foreach my $volid (@$unused) {
4911 add_unused_volume
($conf, $volid);
4915 update_config_nolock
($vmid, $conf, 1);
4918 lock_config
($vmid, $updatefn);
4920 # now remove vmstate file
4922 my $storecfg = PVE
::Storage
::config
();
4924 if ($snap->{vmstate
}) {
4925 eval { PVE
::Storage
::vdisk_free
($storecfg, $snap->{vmstate
}); };
4927 die $err if !$force;
4930 # save changes (remove vmstate from snapshot)
4931 lock_config
($vmid, $updatefn, 'vmstate') if !$force;
4934 # now remove all internal snapshots
4935 foreach_drive
($snap, sub {
4936 my ($ds, $drive) = @_;
4938 return if drive_is_cdrom
($drive);
4940 my $volid = $drive->{file
};
4941 my $device = "drive-$ds";
4943 if (!$drivehash || $drivehash->{$ds}) {
4944 eval { qemu_volume_snapshot_delete
($vmid, $device, $storecfg, $volid, $snapname); };
4946 die $err if !$force;
4951 # save changes (remove drive fron snapshot)
4952 lock_config
($vmid, $updatefn, $ds) if !$force;
4953 push @$unused, $volid;
4956 # now cleanup config
4958 lock_config
($vmid, $updatefn);
4962 my ($feature, $conf, $storecfg, $snapname, $running) = @_;
4965 foreach_drive
($conf, sub {
4966 my ($ds, $drive) = @_;
4968 return if drive_is_cdrom
($drive);
4969 my $volid = $drive->{file
};
4970 $err = 1 if !PVE
::Storage
::volume_has_feature
($storecfg, $feature, $volid, $snapname, $running);
4973 return $err ?
0 : 1;
4976 sub template_create
{
4977 my ($vmid, $conf, $disk) = @_;
4979 my $storecfg = PVE
::Storage
::config
();
4981 foreach_drive
($conf, sub {
4982 my ($ds, $drive) = @_;
4984 return if drive_is_cdrom
($drive);
4985 return if $disk && $ds ne $disk;
4987 my $volid = $drive->{file
};
4988 return if !PVE
::Storage
::volume_has_feature
($storecfg, 'template', $volid);
4990 my $voliddst = PVE
::Storage
::vdisk_create_base
($storecfg, $volid);
4991 $drive->{file
} = $voliddst;
4992 $conf->{$ds} = print_drive
($vmid, $drive);
4993 update_config_nolock
($vmid, $conf, 1);
5000 return 1 if defined $conf->{template
} && $conf->{template
} == 1;
5003 sub qemu_img_convert
{
5004 my ($src_volid, $dst_volid, $size, $snapname) = @_;
5006 my $storecfg = PVE
::Storage
::config
();
5007 my ($src_storeid, $src_volname) = PVE
::Storage
::parse_volume_id
($src_volid, 1);
5008 my ($dst_storeid, $dst_volname) = PVE
::Storage
::parse_volume_id
($dst_volid, 1);
5010 if ($src_storeid && $dst_storeid) {
5011 my $src_scfg = PVE
::Storage
::storage_config
($storecfg, $src_storeid);
5012 my $dst_scfg = PVE
::Storage
::storage_config
($storecfg, $dst_storeid);
5014 my $src_format = qemu_img_format
($src_scfg, $src_volname);
5015 my $dst_format = qemu_img_format
($dst_scfg, $dst_volname);
5017 my $src_path = PVE
::Storage
::path
($storecfg, $src_volid, $snapname);
5018 my $dst_path = PVE
::Storage
::path
($storecfg, $dst_volid);
5021 push @$cmd, '/usr/bin/qemu-img', 'convert', '-t', 'writeback', '-p', '-n';
5022 push @$cmd, '-s', $snapname if($snapname && $src_format eq "qcow2");
5023 push @$cmd, '-f', $src_format, '-O', $dst_format, $src_path, $dst_path;
5027 if($line =~ m/\((\S+)\/100\
%\)/){
5029 my $transferred = int($size * $percent / 100);
5030 my $remaining = $size - $transferred;
5032 print "transferred: $transferred bytes remaining: $remaining bytes total: $size bytes progression: $percent %\n";
5037 eval { run_command
($cmd, timeout
=> undef, outfunc
=> $parser); };
5039 die "copy failed: $err" if $err;
5043 sub qemu_img_format
{
5044 my ($scfg, $volname) = @_;
5046 if ($scfg->{path
} && $volname =~ m/\.(raw|qcow2|qed|vmdk)$/) {
5048 } elsif ($scfg->{type
} eq 'iscsi') {
5049 return "host_device";
5055 sub qemu_drive_mirror
{
5056 my ($vmid, $drive, $dst_volid, $vmiddst, $maxwait) = @_;
5062 my $storecfg = PVE
::Storage
::config
();
5063 my ($dst_storeid, $dst_volname) = PVE
::Storage
::parse_volume_id
($dst_volid, 1);
5066 my $dst_scfg = PVE
::Storage
::storage_config
($storecfg, $dst_storeid);
5069 if ($dst_volname =~ m/\.(raw|qcow2)$/){
5073 my $dst_path = PVE
::Storage
::path
($storecfg, $dst_volid);
5076 #fixme : sometime drive-mirror timeout, but works fine after.
5077 # (I have see the problem with big volume > 200GB), so we need to eval
5078 eval { vm_mon_cmd
($vmid, "drive-mirror", timeout
=> 10, device
=> "drive-$drive", mode
=> "existing",
5079 sync
=> "full", target
=> $dst_path, format
=> $format); };
5081 eval { vm_mon_cmd
($vmid, "drive-mirror", timeout
=> 10, device
=> "drive-$drive", mode
=> "existing",
5082 sync
=> "full", target
=> $dst_path); };
5087 my $stats = vm_mon_cmd
($vmid, "query-block-jobs");
5088 my $stat = @$stats[0];
5089 die "mirroring job seem to have die. Maybe do you have bad sectors?" if !$stat;
5090 die "error job is not mirroring" if $stat->{type
} ne "mirror";
5092 my $transferred = $stat->{offset
};
5093 my $total = $stat->{len
};
5094 my $remaining = $total - $transferred;
5095 my $percent = sprintf "%.2f", ($transferred * 100 / $total);
5097 print "transferred: $transferred bytes remaining: $remaining bytes total: $total bytes progression: $percent %\n";
5099 last if ($stat->{len
} == $stat->{offset
});
5100 if ($old_len == $stat->{offset
}) {
5101 if ($maxwait && $count > $maxwait) {
5102 # if writes to disk occurs the disk needs to be freezed
5103 # to be able to complete the migration
5104 vm_suspend
($vmid,1);
5108 $count++ unless $frozen;
5114 $old_len = $stat->{offset
};
5118 if ($vmiddst == $vmid) {
5119 # switch the disk if source and destination are on the same guest
5120 vm_mon_cmd
($vmid, "block-job-complete", device
=> "drive-$drive");
5124 eval { vm_mon_cmd
($vmid, "block-job-cancel", device
=> "drive-$drive"); };
5125 die "mirroring error: $err";
5128 if ($vmiddst != $vmid) {
5129 # if we clone a disk for a new target vm, we don't switch the disk
5130 vm_mon_cmd
($vmid, "block-job-cancel", device
=> "drive-$drive");
5136 my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
5137 $newvmid, $storage, $format, $full, $newvollist) = @_;
5142 print "create linked clone of drive $drivename ($drive->{file})\n";
5143 $newvolid = PVE
::Storage
::vdisk_clone
($storecfg, $drive->{file
}, $newvmid);
5144 push @$newvollist, $newvolid;
5146 my ($storeid, $volname) = PVE
::Storage
::parse_volume_id
($drive->{file
});
5147 $storeid = $storage if $storage;
5149 my ($defFormat, $validFormats) = PVE
::Storage
::storage_default_format
($storecfg, $storeid);
5151 $format = $drive->{format
} || $defFormat;
5154 # test if requested format is supported - else use default
5155 my $supported = grep { $_ eq $format } @$validFormats;
5156 $format = $defFormat if !$supported;
5158 my ($size) = PVE
::Storage
::volume_size_info
($storecfg, $drive->{file
}, 3);
5160 print "create full clone of drive $drivename ($drive->{file})\n";
5161 $newvolid = PVE
::Storage
::vdisk_alloc
($storecfg, $storeid, $newvmid, $format, undef, ($size/1024));
5162 push @$newvollist, $newvolid;
5164 if (!$running || $snapname) {
5165 qemu_img_convert
($drive->{file
}, $newvolid, $size, $snapname);
5167 qemu_drive_mirror
($vmid, $drivename, $newvolid, $newvmid);
5171 my ($size) = PVE
::Storage
::volume_size_info
($storecfg, $newvolid, 3);
5174 $disk->{format
} = undef;
5175 $disk->{file
} = $newvolid;
5176 $disk->{size
} = $size;
5181 # this only works if VM is running
5182 sub get_current_qemu_machine
{
5185 my $cmd = { execute
=> 'query-machines', arguments
=> {} };
5186 my $res = PVE
::QemuServer
::vm_qmp_command
($vmid, $cmd);
5188 my ($current, $default);
5189 foreach my $e (@$res) {
5190 $default = $e->{name
} if $e->{'is-default'};
5191 $current = $e->{name
} if $e->{'is-current'};
5194 # fallback to the default machine if current is not supported by qemu
5195 return $current || $default || 'pc';
5202 dir_glob_foreach
("$pcisysfs/devices", '[a-f0-9]{4}:([a-f0-9]{2}:[a-f0-9]{2})\.([0-9])', sub {
5203 my (undef, $id, $function) = @_;
5204 my $res = { id
=> $id, function
=> $function};
5205 push @{$devices->{$id}}, $res;