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).",
169 type
=> 'string', format
=> 'pve-hotplug-features',
170 description
=> "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory' and 'usb'. Use '0' to disable hotplug completely. Value '1' is an alias for the default 'network,disk,usb'.",
171 default => 'network,disk,usb',
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 virtio-scsi-single 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
=> "Enable/disable Numa.",
312 description
=> "Number of hotplugged vcpus.",
319 description
=> "Enable/disable ACPI.",
325 description
=> "Enable/disable Qemu GuestAgent.",
331 description
=> "Enable/disable KVM hardware virtualization.",
337 description
=> "Enable/disable time drift fix.",
343 description
=> "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
348 description
=> "Freeze CPU at startup (use 'c' monitor command to start execution).",
353 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.",
354 enum
=> [qw(std cirrus vmware qxl serial0 serial1 serial2 serial3 qxl2 qxl3 qxl4)],
358 type
=> 'string', format
=> 'pve-qm-watchdog',
359 typetext
=> '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
360 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)",
365 typetext
=> "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
366 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'.",
367 pattern
=> '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
372 type
=> 'string', format
=> 'pve-qm-startup',
373 typetext
=> '[[order=]\d+] [,up=\d+] [,down=\d+] ',
374 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.",
379 description
=> "Enable/disable Template.",
385 description
=> <<EODESCR,
386 Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
388 args: -no-reboot -no-hpet
395 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).",
400 description
=> "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
404 migrate_downtime
=> {
407 description
=> "Set maximum tolerated downtime (in seconds) for migrations.",
413 type
=> 'string', format
=> 'pve-qm-drive',
414 typetext
=> 'volume',
415 description
=> "This is an alias for option -ide2",
419 description
=> "Emulated CPU type.",
421 enum
=> [ qw(486 athlon pentium pentium2 pentium3 coreduo core2duo kvm32 kvm64 qemu32 qemu64 phenom Conroe Penryn Nehalem Westmere SandyBridge IvyBridge Haswell Broadwell Opteron_G1 Opteron_G2 Opteron_G3 Opteron_G4 Opteron_G5 host) ],
424 parent
=> get_standard_option
('pve-snapshot-name', {
426 description
=> "Parent snapshot name. This is used internally, and should not be modified.",
430 description
=> "Timestamp for snapshots.",
436 type
=> 'string', format
=> 'pve-volume-id',
437 description
=> "Reference to a volume which stores the VM state. This is used internally for snapshots.",
440 description
=> "Specific the Qemu machine type.",
442 pattern
=> '(pc|pc(-i440fx)?-\d+\.\d+|q35|pc-q35-\d+\.\d+)',
447 description
=> "Specify SMBIOS type 1 fields.",
448 type
=> 'string', format
=> 'pve-qm-smbios1',
449 typetext
=> "[manufacturer=str][,product=str][,version=str][,serial=str] [,uuid=uuid][,sku=str][,family=str]",
455 # what about other qemu settings ?
457 #machine => 'string',
470 ##soundhw => 'string',
472 while (my ($k, $v) = each %$confdesc) {
473 PVE
::JSONSchema
::register_standard_option
("pve-qm-$k", $v);
476 my $MAX_IDE_DISKS = 4;
477 my $MAX_SCSI_DISKS = 14;
478 my $MAX_VIRTIO_DISKS = 16;
479 my $MAX_SATA_DISKS = 6;
480 my $MAX_USB_DEVICES = 5;
482 my $MAX_UNUSED_DISKS = 8;
483 my $MAX_HOSTPCI_DEVICES = 4;
484 my $MAX_SERIAL_PORTS = 4;
485 my $MAX_PARALLEL_PORTS = 3;
487 my $MAX_MEM = 4194304;
488 my $STATICMEM = 1024;
492 type
=> 'string', format
=> 'pve-qm-numanode',
493 typetext
=> "cpus=<id[-id],memory=<mb>[[,hostnodes=<id[-id]>] [,policy=<preferred|bind|interleave>]]",
494 description
=> "numa topology",
496 PVE
::JSONSchema
::register_standard_option
("pve-qm-numanode", $numadesc);
498 for (my $i = 0; $i < $MAX_NUMA; $i++) {
499 $confdesc->{"numa$i"} = $numadesc;
502 my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
503 'ne2k_isa', 'i82551', 'i82557b', 'i82559er', 'vmxnet3',
504 'e1000-82540em', 'e1000-82544gc', 'e1000-82545em'];
505 my $nic_model_list_txt = join(' ', sort @$nic_model_list);
509 type
=> 'string', format
=> 'pve-qm-net',
510 typetext
=> "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,queues=<nbqueues>][,rate=<mbps>] [,tag=<vlanid>][,firewall=0|1],link_down=0|1]",
511 description
=> <<EODESCR,
512 Specify network devices.
514 MODEL is one of: $nic_model_list_txt
516 XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
517 automatically generated if not specified.
519 The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
521 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'.
523 If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
529 The DHCP server assign addresses to the guest starting from 10.0.2.15.
533 PVE
::JSONSchema
::register_standard_option
("pve-qm-net", $netdesc);
535 for (my $i = 0; $i < $MAX_NETS; $i++) {
536 $confdesc->{"net$i"} = $netdesc;
543 type
=> 'string', format
=> 'pve-qm-drive',
544 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]',
545 description
=> "Use volume as IDE hard disk or CD-ROM (n is 0 to " .($MAX_IDE_DISKS -1) . ").",
547 PVE
::JSONSchema
::register_standard_option
("pve-qm-ide", $idedesc);
551 type
=> 'string', format
=> 'pve-qm-drive',
552 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] [,iothread=on]',
553 description
=> "Use volume as SCSI hard disk or CD-ROM (n is 0 to " . ($MAX_SCSI_DISKS - 1) . ").",
555 PVE
::JSONSchema
::register_standard_option
("pve-qm-scsi", $scsidesc);
559 type
=> 'string', format
=> 'pve-qm-drive',
560 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]',
561 description
=> "Use volume as SATA hard disk or CD-ROM (n is 0 to " . ($MAX_SATA_DISKS - 1). ").",
563 PVE
::JSONSchema
::register_standard_option
("pve-qm-sata", $satadesc);
567 type
=> 'string', format
=> 'pve-qm-drive',
568 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] [,iothread=on]',
569 description
=> "Use volume as VIRTIO hard disk (n is 0 to " . ($MAX_VIRTIO_DISKS - 1) . ").",
571 PVE
::JSONSchema
::register_standard_option
("pve-qm-virtio", $virtiodesc);
575 type
=> 'string', format
=> 'pve-qm-usb-device',
576 typetext
=> 'host=HOSTUSBDEVICE|spice',
577 description
=> <<EODESCR,
578 Configure an USB device (n is 0 to 4). This can be used to
579 pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
581 'bus-port(.port)*' (decimal numbers) or
582 'vendor_id:product_id' (hexadeciaml numbers)
584 You can use the 'lsusb -t' command to list existing usb devices.
586 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
588 The value 'spice' can be used to add a usb redirection devices for spice.
592 PVE
::JSONSchema
::register_standard_option
("pve-qm-usb", $usbdesc);
596 type
=> 'string', format
=> 'pve-qm-hostpci',
597 typetext
=> "[host=]HOSTPCIDEVICE [,driver=kvm|vfio] [,rombar=on|off] [,pcie=0|1] [,x-vga=on|off]",
598 description
=> <<EODESCR,
599 Map host pci devices. HOSTPCIDEVICE syntax is:
601 'bus:dev.func' (hexadecimal numbers)
603 You can us the 'lspci' command to list existing pci devices.
605 The 'rombar' option determines whether or not the device's ROM will be visible in the guest's memory map (default is 'on').
607 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
609 Experimental: user reported problems with this option.
612 PVE
::JSONSchema
::register_standard_option
("pve-qm-hostpci", $hostpcidesc);
617 pattern
=> '(/dev/.+|socket)',
618 description
=> <<EODESCR,
619 Create a serial device inside the VM (n is 0 to 3), and pass through a host serial device (i.e. /dev/ttyS0), or create a unix socket on the host side (use 'qm terminal' to open a terminal connection).
621 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
623 Experimental: user reported problems with this option.
630 pattern
=> '/dev/parport\d+|/dev/usb/lp\d+',
631 description
=> <<EODESCR,
632 Map host parallel devices (n is 0 to 2).
634 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
636 Experimental: user reported problems with this option.
640 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
641 $confdesc->{"parallel$i"} = $paralleldesc;
644 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
645 $confdesc->{"serial$i"} = $serialdesc;
648 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
649 $confdesc->{"hostpci$i"} = $hostpcidesc;
652 for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
653 $drivename_hash->{"ide$i"} = 1;
654 $confdesc->{"ide$i"} = $idedesc;
657 for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
658 $drivename_hash->{"sata$i"} = 1;
659 $confdesc->{"sata$i"} = $satadesc;
662 for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
663 $drivename_hash->{"scsi$i"} = 1;
664 $confdesc->{"scsi$i"} = $scsidesc ;
667 for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
668 $drivename_hash->{"virtio$i"} = 1;
669 $confdesc->{"virtio$i"} = $virtiodesc;
672 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
673 $confdesc->{"usb$i"} = $usbdesc;
678 type
=> 'string', format
=> 'pve-volume-id',
679 description
=> "Reference to unused volumes.",
682 for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
683 $confdesc->{"unused$i"} = $unuseddesc;
686 my $kvm_api_version = 0;
690 return $kvm_api_version if $kvm_api_version;
692 my $fh = IO
::File-
>new("</dev/kvm") ||
695 if (my $v = $fh->ioctl(KVM_GET_API_VERSION
(), 0)) {
696 $kvm_api_version = $v;
701 return $kvm_api_version;
704 my $kvm_user_version;
706 sub kvm_user_version
{
708 return $kvm_user_version if $kvm_user_version;
710 $kvm_user_version = 'unknown';
712 my $tmp = `kvm -help 2>/dev/null`;
714 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?)[,\s]/) {
715 $kvm_user_version = $2;
718 return $kvm_user_version;
722 my $kernel_has_vhost_net = -c
'/dev/vhost-net';
725 # order is important - used to autoselect boot disk
726 return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
727 (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
728 (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
729 (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
732 sub valid_drivename
{
735 return defined($drivename_hash->{$dev});
740 return defined($confdesc->{$key});
744 return $nic_model_list;
747 sub os_list_description
{
752 w2k
=> 'Windows 2000',
753 w2k3
=>, 'Windows 2003',
754 w2k8
=> 'Windows 2008',
755 wvista
=> 'Windows Vista',
757 win8
=> 'Windows 8/2012',
767 return $cdrom_path if $cdrom_path;
769 return $cdrom_path = "/dev/cdrom" if -l
"/dev/cdrom";
770 return $cdrom_path = "/dev/cdrom1" if -l
"/dev/cdrom1";
771 return $cdrom_path = "/dev/cdrom2" if -l
"/dev/cdrom2";
775 my ($storecfg, $vmid, $cdrom) = @_;
777 if ($cdrom eq 'cdrom') {
778 return get_cdrom_path
();
779 } elsif ($cdrom eq 'none') {
781 } elsif ($cdrom =~ m
|^/|) {
784 return PVE
::Storage
::path
($storecfg, $cdrom);
788 # try to convert old style file names to volume IDs
789 sub filename_to_volume_id
{
790 my ($vmid, $file, $media) = @_;
792 if (!($file eq 'none' || $file eq 'cdrom' ||
793 $file =~ m
|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
795 return undef if $file =~ m
|/|;
797 if ($media && $media eq 'cdrom') {
798 $file = "local:iso/$file";
800 $file = "local:$vmid/$file";
807 sub verify_media_type
{
808 my ($opt, $vtype, $media) = @_;
813 if ($media eq 'disk') {
815 } elsif ($media eq 'cdrom') {
818 die "internal error";
821 return if ($vtype eq $etype);
823 raise_param_exc
({ $opt => "unexpected media type ($vtype != $etype)" });
826 sub cleanup_drive_path
{
827 my ($opt, $storecfg, $drive) = @_;
829 # try to convert filesystem paths to volume IDs
831 if (($drive->{file
} !~ m/^(cdrom|none)$/) &&
832 ($drive->{file
} !~ m
|^/dev/.+|) &&
833 ($drive->{file
} !~ m/^([^:]+):(.+)$/) &&
834 ($drive->{file
} !~ m/^\d+$/)) {
835 my ($vtype, $volid) = PVE
::Storage
::path_to_volume_id
($storecfg, $drive->{file
});
836 raise_param_exc
({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
837 $drive->{media
} = 'cdrom' if !$drive->{media
} && $vtype eq 'iso';
838 verify_media_type
($opt, $vtype, $drive->{media
});
839 $drive->{file
} = $volid;
842 $drive->{media
} = 'cdrom' if !$drive->{media
} && $drive->{file
} =~ m/^(cdrom|none)$/;
845 sub create_conf_nolock
{
846 my ($vmid, $settings) = @_;
848 my $filename = config_file
($vmid);
850 die "configuration file '$filename' already exists\n" if -f
$filename;
852 my $defaults = load_defaults
();
854 $settings->{name
} = "vm$vmid" if !$settings->{name
};
855 $settings->{memory
} = $defaults->{memory
} if !$settings->{memory
};
858 foreach my $opt (keys %$settings) {
859 next if !$confdesc->{$opt};
861 my $value = $settings->{$opt};
864 $data .= "$opt: $value\n";
867 PVE
::Tools
::file_set_contents
($filename, $data);
870 sub parse_hotplug_features
{
875 return $res if $data eq '0';
877 $data = $confdesc->{hotplug
}->{default} if $data eq '1';
879 foreach my $feature (PVE
::Tools
::split_list
($data)) {
880 if ($feature =~ m/^(network|disk|cpu|memory|usb)$/) {
883 warn "ignoring unknown hotplug feature '$feature'\n";
889 PVE
::JSONSchema
::register_format
('pve-hotplug-features', \
&pve_verify_hotplug_features
);
890 sub pve_verify_hotplug_features
{
891 my ($value, $noerr) = @_;
893 return $value if parse_hotplug_features
($value);
895 return undef if $noerr;
897 die "unable to parse hotplug option\n";
900 my $parse_size = sub {
903 return undef if $value !~ m/^(\d+(\.\d+)?)([KMG])?$/;
904 my ($size, $unit) = ($1, $3);
907 $size = $size * 1024;
908 } elsif ($unit eq 'M') {
909 $size = $size * 1024 * 1024;
910 } elsif ($unit eq 'G') {
911 $size = $size * 1024 * 1024 * 1024;
917 my $format_size = sub {
922 my $kb = int($size/1024);
923 return $size if $kb*1024 != $size;
925 my $mb = int($kb/1024);
926 return "${kb}K" if $mb*1024 != $kb;
928 my $gb = int($mb/1024);
929 return "${mb}M" if $gb*1024 != $mb;
934 # ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
935 # [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
936 # [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
937 # [,aio=native|threads][,discard=ignore|on][,iothread=on]
940 my ($key, $data) = @_;
944 # $key may be undefined - used to verify JSON parameters
945 if (!defined($key)) {
946 $res->{interface
} = 'unknown'; # should not harm when used to verify parameters
948 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
949 $res->{interface
} = $1;
955 foreach my $p (split (/,/, $data)) {
956 next if $p =~ m/^\s*$/;
958 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|iothread)=(.+)$/) {
959 my ($k, $v) = ($1, $2);
961 $k = 'file' if $k eq 'volume';
963 return undef if defined $res->{$k};
965 if ($k eq 'bps' || $k eq 'bps_rd' || $k eq 'bps_wr') {
966 return undef if !$v || $v !~ m/^\d+/;
968 $v = sprintf("%.3f", $v / (1024*1024));
972 if (!$res->{file
} && $p !~ m/=/) {
980 return undef if !$res->{file
};
982 if($res->{file
} =~ m/\.(raw|cow|qcow|qcow2|vmdk|cloop)$/){
986 return undef if $res->{cache
} &&
987 $res->{cache
} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
988 return undef if $res->{snapshot
} && $res->{snapshot
} !~ m/^(on|off)$/;
989 return undef if $res->{cyls
} && $res->{cyls
} !~ m/^\d+$/;
990 return undef if $res->{heads
} && $res->{heads
} !~ m/^\d+$/;
991 return undef if $res->{secs
} && $res->{secs
} !~ m/^\d+$/;
992 return undef if $res->{media
} && $res->{media
} !~ m/^(disk|cdrom)$/;
993 return undef if $res->{trans
} && $res->{trans
} !~ m/^(none|lba|auto)$/;
994 return undef if $res->{format
} && $res->{format
} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
995 return undef if $res->{rerror
} && $res->{rerror
} !~ m/^(ignore|report|stop)$/;
996 return undef if $res->{werror
} && $res->{werror
} !~ m/^(enospc|ignore|report|stop)$/;
997 return undef if $res->{backup
} && $res->{backup
} !~ m/^(yes|no)$/;
998 return undef if $res->{aio
} && $res->{aio
} !~ m/^(native|threads)$/;
999 return undef if $res->{discard
} && $res->{discard
} !~ m/^(ignore|on)$/;
1000 return undef if $res->{iothread
} && $res->{iothread
} !~ m/^(on)$/;
1002 return undef if $res->{mbps_rd
} && $res->{mbps
};
1003 return undef if $res->{mbps_wr
} && $res->{mbps
};
1005 return undef if $res->{mbps
} && $res->{mbps
} !~ m/^\d+(\.\d+)?$/;
1006 return undef if $res->{mbps_max
} && $res->{mbps_max
} !~ m/^\d+(\.\d+)?$/;
1007 return undef if $res->{mbps_rd
} && $res->{mbps_rd
} !~ m/^\d+(\.\d+)?$/;
1008 return undef if $res->{mbps_rd_max
} && $res->{mbps_rd_max
} !~ m/^\d+(\.\d+)?$/;
1009 return undef if $res->{mbps_wr
} && $res->{mbps_wr
} !~ m/^\d+(\.\d+)?$/;
1010 return undef if $res->{mbps_wr_max
} && $res->{mbps_wr_max
} !~ m/^\d+(\.\d+)?$/;
1012 return undef if $res->{iops_rd
} && $res->{iops
};
1013 return undef if $res->{iops_wr
} && $res->{iops
};
1016 return undef if $res->{iops
} && $res->{iops
} !~ m/^\d+$/;
1017 return undef if $res->{iops_max
} && $res->{iops_max
} !~ m/^\d+$/;
1018 return undef if $res->{iops_rd
} && $res->{iops_rd
} !~ m/^\d+$/;
1019 return undef if $res->{iops_rd_max
} && $res->{iops_rd_max
} !~ m/^\d+$/;
1020 return undef if $res->{iops_wr
} && $res->{iops_wr
} !~ m/^\d+$/;
1021 return undef if $res->{iops_wr_max
} && $res->{iops_wr_max
} !~ m/^\d+$/;
1025 return undef if !defined($res->{size
} = &$parse_size($res->{size
}));
1028 if ($res->{media
} && ($res->{media
} eq 'cdrom')) {
1029 return undef if $res->{snapshot
} || $res->{trans
} || $res->{format
};
1030 return undef if $res->{heads
} || $res->{secs
} || $res->{cyls
};
1031 return undef if $res->{interface
} eq 'virtio';
1034 # rerror does not work with scsi drives
1035 if ($res->{rerror
}) {
1036 return undef if $res->{interface
} eq 'scsi';
1042 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);
1045 my ($vmid, $drive) = @_;
1048 foreach my $o (@qemu_drive_options, 'mbps', 'mbps_rd', 'mbps_wr', 'mbps_max', 'mbps_rd_max', 'mbps_wr_max', 'backup', 'iothread') {
1049 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
1052 if ($drive->{size
}) {
1053 $opts .= ",size=" . &$format_size($drive->{size
});
1056 return "$drive->{file}$opts";
1060 my($fh, $noerr) = @_;
1063 my $SG_GET_VERSION_NUM = 0x2282;
1065 my $versionbuf = "\x00" x
8;
1066 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
1068 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
1071 my $version = unpack("I", $versionbuf);
1072 if ($version < 30000) {
1073 die "scsi generic interface too old\n" if !$noerr;
1077 my $buf = "\x00" x
36;
1078 my $sensebuf = "\x00" x
8;
1079 my $cmd = pack("C x3 C x1", 0x12, 36);
1081 # see /usr/include/scsi/sg.h
1082 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";
1084 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
1085 length($sensebuf), 0, length($buf), $buf,
1086 $cmd, $sensebuf, 6000);
1088 $ret = ioctl($fh, $SG_IO, $packet);
1090 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
1094 my @res = unpack($sg_io_hdr_t, $packet);
1095 if ($res[17] || $res[18]) {
1096 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
1101 (my $byte0, my $byte1, $res->{vendor
},
1102 $res->{product
}, $res->{revision
}) = unpack("C C x6 A8 A16 A4", $buf);
1104 $res->{removable
} = $byte1 & 128 ?
1 : 0;
1105 $res->{type
} = $byte0 & 31;
1113 my $fh = IO
::File-
>new("+<$path") || return undef;
1114 my $res = scsi_inquiry
($fh, 1);
1120 sub machine_type_is_q35
{
1123 return $conf->{machine
} && ($conf->{machine
} =~ m/q35/) ?
1 : 0;
1126 sub print_tabletdevice_full
{
1129 my $q35 = machine_type_is_q35
($conf);
1131 # we use uhci for old VMs because tablet driver was buggy in older qemu
1132 my $usbbus = $q35 ?
"ehci" : "uhci";
1134 return "usb-tablet,id=tablet,bus=$usbbus.0,port=1";
1137 sub print_drivedevice_full
{
1138 my ($storecfg, $conf, $vmid, $drive, $bridges) = @_;
1143 if ($drive->{interface
} eq 'virtio') {
1144 my $pciaddr = print_pci_addr
("$drive->{interface}$drive->{index}", $bridges);
1145 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
1146 $device .= ",iothread=iothread-$drive->{interface}$drive->{index}" if $drive->{iothread
};
1147 } elsif ($drive->{interface
} eq 'scsi') {
1149 my ($maxdev, $controller, $controller_prefix) = scsihw_infos
($conf, $drive);
1150 my $unit = $drive->{index} % $maxdev;
1151 my $devicetype = 'hd';
1153 if (drive_is_cdrom
($drive)) {
1156 if ($drive->{file
} =~ m
|^/|) {
1157 $path = $drive->{file
};
1159 $path = PVE
::Storage
::path
($storecfg, $drive->{file
});
1162 if($path =~ m/^iscsi\:\/\
//){
1163 $devicetype = 'generic';
1165 if (my $info = path_is_scsi
($path)) {
1166 if ($info->{type
} == 0) {
1167 $devicetype = 'block';
1168 } elsif ($info->{type
} == 1) { # tape
1169 $devicetype = 'generic';
1175 if (!$conf->{scsihw
} || ($conf->{scsihw
} =~ m/^lsi/)){
1176 $device = "scsi-$devicetype,bus=$controller_prefix$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1178 $device = "scsi-$devicetype,bus=$controller_prefix$controller.0,channel=0,scsi-id=0,lun=$drive->{index},drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1181 } elsif ($drive->{interface
} eq 'ide'){
1183 my $controller = int($drive->{index} / $maxdev);
1184 my $unit = $drive->{index} % $maxdev;
1185 my $devicetype = ($drive->{media
} && $drive->{media
} eq 'cdrom') ?
"cd" : "hd";
1187 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1188 } elsif ($drive->{interface
} eq 'sata'){
1189 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
1190 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1191 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1192 } elsif ($drive->{interface
} eq 'usb') {
1194 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1196 die "unsupported interface type";
1199 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex
};
1204 sub get_initiator_name
{
1207 my $fh = IO
::File-
>new('/etc/iscsi/initiatorname.iscsi') || return undef;
1208 while (defined(my $line = <$fh>)) {
1209 next if $line !~ m/^\s*InitiatorName\s*=\s*([\.\-:\w]+)/;
1218 sub print_drive_full
{
1219 my ($storecfg, $vmid, $drive) = @_;
1222 foreach my $o (@qemu_drive_options) {
1223 next if $o eq 'bootindex';
1224 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
1227 foreach my $o (qw(bps bps_rd bps_wr)) {
1228 my $v = $drive->{"m$o"};
1229 $opts .= ",$o=" . int($v*1024*1024) if $v;
1232 # aio native works only with O_DIRECT
1233 if (!$drive->{aio
}) {
1234 if(!$drive->{cache
} || $drive->{cache
} eq 'none' || $drive->{cache
} eq 'directsync') {
1235 $opts .= ",aio=native";
1237 $opts .= ",aio=threads";
1243 my $volid = $drive->{file
};
1244 if (drive_is_cdrom
($drive)) {
1245 $path = get_iso_path
($storecfg, $vmid, $volid);
1247 if ($volid =~ m
|^/|) {
1250 $path = PVE
::Storage
::path
($storecfg, $volid);
1254 $opts .= ",cache=none" if !$drive->{cache
} && !drive_is_cdrom
($drive);
1256 my $detectzeroes = $drive->{discard
} ?
"unmap" : "on";
1257 $opts .= ",detect-zeroes=$detectzeroes" if !drive_is_cdrom
($drive);
1259 my $pathinfo = $path ?
"file=$path," : '';
1261 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1264 sub print_netdevice_full
{
1265 my ($vmid, $conf, $net, $netid, $bridges) = @_;
1267 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
1269 my $device = $net->{model
};
1270 if ($net->{model
} eq 'virtio') {
1271 $device = 'virtio-net-pci';
1274 my $pciaddr = print_pci_addr
("$netid", $bridges);
1275 my $tmpstr = "$device,mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
1276 if ($net->{queues
} && $net->{queues
} > 1 && $net->{model
} eq 'virtio'){
1277 #Consider we have N queues, the number of vectors needed is 2*N + 2 (plus one config interrupt and control vq)
1278 my $vectors = $net->{queues
} * 2 + 2;
1279 $tmpstr .= ",vectors=$vectors,mq=on";
1281 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex
} ;
1285 sub print_netdev_full
{
1286 my ($vmid, $conf, $net, $netid) = @_;
1289 if ($netid =~ m/^net(\d+)$/) {
1293 die "got strange net id '$i'\n" if $i >= ${MAX_NETS
};
1295 my $ifname = "tap${vmid}i$i";
1297 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1298 die "interface name '$ifname' is too long (max 15 character)\n"
1299 if length($ifname) >= 16;
1301 my $vhostparam = '';
1302 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model
} eq 'virtio';
1304 my $vmname = $conf->{name
} || "vm$vmid";
1308 if ($net->{bridge
}) {
1309 $netdev = "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown$vhostparam";
1311 $netdev = "type=user,id=$netid,hostname=$vmname";
1314 $netdev .= ",queues=$net->{queues}" if ($net->{queues
} && $net->{model
} eq 'virtio');
1319 sub drive_is_cdrom
{
1322 return $drive && $drive->{media
} && ($drive->{media
} eq 'cdrom');
1331 foreach my $kvp (split(/,/, $data)) {
1333 if ($kvp =~ m/^memory=(\S+)$/) {
1334 $res->{memory
} = $1;
1335 } elsif ($kvp =~ m/^policy=(preferred|bind|interleave)$/) {
1336 $res->{policy
} = $1;
1337 } elsif ($kvp =~ m/^cpus=(\d+)(-(\d+))?$/) {
1338 $res->{cpus
}->{start
} = $1;
1339 $res->{cpus
}->{end
} = $3;
1340 } elsif ($kvp =~ m/^hostnodes=(\d+)(-(\d+))?$/) {
1341 $res->{hostnodes
}->{start
} = $1;
1342 $res->{hostnodes
}->{end
} = $3;
1354 return undef if !$value;
1357 my @list = split(/,/, $value);
1361 foreach my $kv (@list) {
1363 if ($kv =~ m/^(host=)?([a-f0-9]{2}:[a-f0-9]{2})(\.([a-f0-9]))?$/) {
1366 push @{$res->{pciid
}}, { id
=> $2 , function
=> $4};
1369 my $pcidevices = lspci
($2);
1370 $res->{pciid
} = $pcidevices->{$2};
1372 } elsif ($kv =~ m/^driver=(kvm|vfio)$/) {
1373 $res->{driver
} = $1;
1374 } elsif ($kv =~ m/^rombar=(on|off)$/) {
1375 $res->{rombar
} = $1;
1376 } elsif ($kv =~ m/^x-vga=(on|off)$/) {
1377 $res->{'x-vga'} = $1;
1378 } elsif ($kv =~ m/^pcie=(\d+)$/) {
1379 $res->{pcie
} = 1 if $1 == 1;
1381 warn "unknown hostpci setting '$kv'\n";
1385 return undef if !$found;
1390 # netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1396 foreach my $kvp (split(/,/, $data)) {
1398 if ($kvp =~ m/^(ne2k_pci|e1000|e1000-82540em|e1000-82544gc|e1000-82545em|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er|vmxnet3)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
1400 my $mac = defined($3) ?
uc($3) : PVE
::Tools
::random_ether_addr
();
1401 $res->{model
} = $model;
1402 $res->{macaddr
} = $mac;
1403 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1404 $res->{bridge
} = $1;
1405 } elsif ($kvp =~ m/^queues=(\d+)$/) {
1406 $res->{queues
} = $1;
1407 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1409 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1411 } elsif ($kvp =~ m/^firewall=([01])$/) {
1412 $res->{firewall
} = $1;
1413 } elsif ($kvp =~ m/^link_down=([01])$/) {
1414 $res->{link_down
} = $1;
1421 return undef if !$res->{model
};
1429 my $res = "$net->{model}";
1430 $res .= "=$net->{macaddr}" if $net->{macaddr
};
1431 $res .= ",bridge=$net->{bridge}" if $net->{bridge
};
1432 $res .= ",rate=$net->{rate}" if $net->{rate
};
1433 $res .= ",tag=$net->{tag}" if $net->{tag
};
1434 $res .= ",firewall=1" if $net->{firewall
};
1435 $res .= ",link_down=1" if $net->{link_down
};
1436 $res .= ",queues=$net->{queues}" if $net->{queues
};
1441 sub add_random_macs
{
1442 my ($settings) = @_;
1444 foreach my $opt (keys %$settings) {
1445 next if $opt !~ m/^net(\d+)$/;
1446 my $net = parse_net
($settings->{$opt});
1448 $settings->{$opt} = print_net
($net);
1452 sub add_unused_volume
{
1453 my ($config, $volid) = @_;
1456 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1457 my $test = "unused$ind";
1458 if (my $vid = $config->{$test}) {
1459 return if $vid eq $volid; # do not add duplicates
1465 die "To many unused volume - please delete them first.\n" if !$key;
1467 $config->{$key} = $volid;
1472 sub vm_is_volid_owner
{
1473 my ($storecfg, $vmid, $volid) = @_;
1475 if ($volid !~ m
|^/|) {
1477 eval { ($path, $owner) = PVE
::Storage
::path
($storecfg, $volid); };
1478 if ($owner && ($owner == $vmid)) {
1486 sub vmconfig_delete_pending_option
{
1487 my ($conf, $key) = @_;
1489 delete $conf->{pending
}->{$key};
1490 my $pending_delete_hash = { $key => 1 };
1491 foreach my $opt (PVE
::Tools
::split_list
($conf->{pending
}->{delete})) {
1492 $pending_delete_hash->{$opt} = 1;
1494 $conf->{pending
}->{delete} = join(',', keys %$pending_delete_hash);
1497 sub vmconfig_undelete_pending_option
{
1498 my ($conf, $key) = @_;
1500 my $pending_delete_hash = {};
1501 foreach my $opt (PVE
::Tools
::split_list
($conf->{pending
}->{delete})) {
1502 $pending_delete_hash->{$opt} = 1;
1504 delete $pending_delete_hash->{$key};
1506 my @keylist = keys %$pending_delete_hash;
1507 if (scalar(@keylist)) {
1508 $conf->{pending
}->{delete} = join(',', @keylist);
1510 delete $conf->{pending
}->{delete};
1514 sub vmconfig_register_unused_drive
{
1515 my ($storecfg, $vmid, $conf, $drive) = @_;
1517 if (!drive_is_cdrom
($drive)) {
1518 my $volid = $drive->{file
};
1519 if (vm_is_volid_owner
($storecfg, $vmid, $volid)) {
1520 add_unused_volume
($conf, $volid, $vmid);
1525 sub vmconfig_cleanup_pending
{
1528 # remove pending changes when nothing changed
1530 foreach my $opt (keys %{$conf->{pending
}}) {
1531 if (defined($conf->{$opt}) && ($conf->{pending
}->{$opt} eq $conf->{$opt})) {
1533 delete $conf->{pending
}->{$opt};
1537 # remove delete if option is not set
1538 my $pending_delete_hash = {};
1539 foreach my $opt (PVE
::Tools
::split_list
($conf->{pending
}->{delete})) {
1540 if (defined($conf->{$opt})) {
1541 $pending_delete_hash->{$opt} = 1;
1547 my @keylist = keys %$pending_delete_hash;
1548 if (scalar(@keylist)) {
1549 $conf->{pending
}->{delete} = join(',', @keylist);
1551 delete $conf->{pending
}->{delete};
1557 my $valid_smbios1_options = {
1558 manufacturer
=> '\S+',
1562 uuid
=> '[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}',
1567 # smbios: [manufacturer=str][,product=str][,version=str][,serial=str][,uuid=uuid][,sku=str][,family=str]
1573 foreach my $kvp (split(/,/, $data)) {
1574 return undef if $kvp !~ m/^(\S+)=(.+)$/;
1575 my ($k, $v) = split(/=/, $kvp);
1576 return undef if !defined($k) || !defined($v);
1577 return undef if !$valid_smbios1_options->{$k};
1578 return undef if $v !~ m/^$valid_smbios1_options->{$k}$/;
1589 foreach my $k (keys %$smbios1) {
1590 next if !defined($smbios1->{$k});
1591 next if !$valid_smbios1_options->{$k};
1592 $data .= ',' if $data;
1593 $data .= "$k=$smbios1->{$k}";
1598 PVE
::JSONSchema
::register_format
('pve-qm-smbios1', \
&verify_smbios1
);
1599 sub verify_smbios1
{
1600 my ($value, $noerr) = @_;
1602 return $value if parse_smbios1
($value);
1604 return undef if $noerr;
1606 die "unable to parse smbios (type 1) options\n";
1609 PVE
::JSONSchema
::register_format
('pve-qm-bootdisk', \
&verify_bootdisk
);
1610 sub verify_bootdisk
{
1611 my ($value, $noerr) = @_;
1613 return $value if valid_drivename
($value);
1615 return undef if $noerr;
1617 die "invalid boot disk '$value'\n";
1620 PVE
::JSONSchema
::register_format
('pve-qm-numanode', \
&verify_numa
);
1622 my ($value, $noerr) = @_;
1624 return $value if parse_numa
($value);
1626 return undef if $noerr;
1628 die "unable to parse numa options\n";
1631 PVE
::JSONSchema
::register_format
('pve-qm-net', \
&verify_net
);
1633 my ($value, $noerr) = @_;
1635 return $value if parse_net
($value);
1637 return undef if $noerr;
1639 die "unable to parse network options\n";
1642 PVE
::JSONSchema
::register_format
('pve-qm-drive', \
&verify_drive
);
1644 my ($value, $noerr) = @_;
1646 return $value if parse_drive
(undef, $value);
1648 return undef if $noerr;
1650 die "unable to parse drive options\n";
1653 PVE
::JSONSchema
::register_format
('pve-qm-hostpci', \
&verify_hostpci
);
1654 sub verify_hostpci
{
1655 my ($value, $noerr) = @_;
1657 return $value if parse_hostpci
($value);
1659 return undef if $noerr;
1661 die "unable to parse pci id\n";
1664 PVE
::JSONSchema
::register_format
('pve-qm-watchdog', \
&verify_watchdog
);
1665 sub verify_watchdog
{
1666 my ($value, $noerr) = @_;
1668 return $value if parse_watchdog
($value);
1670 return undef if $noerr;
1672 die "unable to parse watchdog options\n";
1675 sub parse_watchdog
{
1678 return undef if !$value;
1682 foreach my $p (split(/,/, $value)) {
1683 next if $p =~ m/^\s*$/;
1685 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1687 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1688 $res->{action
} = $2;
1697 PVE
::JSONSchema
::register_format
('pve-qm-startup', \
&verify_startup
);
1698 sub verify_startup
{
1699 my ($value, $noerr) = @_;
1701 return $value if parse_startup
($value);
1703 return undef if $noerr;
1705 die "unable to parse startup options\n";
1711 return undef if !$value;
1715 foreach my $p (split(/,/, $value)) {
1716 next if $p =~ m/^\s*$/;
1718 if ($p =~ m/^(order=)?(\d+)$/) {
1720 } elsif ($p =~ m/^up=(\d+)$/) {
1722 } elsif ($p =~ m/^down=(\d+)$/) {
1732 sub parse_usb_device
{
1735 return undef if !$value;
1737 my @dl = split(/,/, $value);
1741 foreach my $v (@dl) {
1742 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1744 $res->{vendorid
} = $2;
1745 $res->{productid
} = $4;
1746 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1748 $res->{hostbus
} = $1;
1749 $res->{hostport
} = $2;
1750 } elsif ($v =~ m/^spice$/) {
1757 return undef if !$found;
1762 PVE
::JSONSchema
::register_format
('pve-qm-usb-device', \
&verify_usb_device
);
1763 sub verify_usb_device
{
1764 my ($value, $noerr) = @_;
1766 return $value if parse_usb_device
($value);
1768 return undef if $noerr;
1770 die "unable to parse usb device\n";
1773 # add JSON properties for create and set function
1774 sub json_config_properties
{
1777 foreach my $opt (keys %$confdesc) {
1778 next if $opt eq 'parent' || $opt eq 'snaptime' || $opt eq 'vmstate';
1779 $prop->{$opt} = $confdesc->{$opt};
1786 my ($key, $value) = @_;
1788 die "unknown setting '$key'\n" if !$confdesc->{$key};
1790 my $type = $confdesc->{$key}->{type
};
1792 if (!defined($value)) {
1793 die "got undefined value\n";
1796 if ($value =~ m/[\n\r]/) {
1797 die "property contains a line feed\n";
1800 if ($type eq 'boolean') {
1801 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1802 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1803 die "type check ('boolean') failed - got '$value'\n";
1804 } elsif ($type eq 'integer') {
1805 return int($1) if $value =~ m/^(\d+)$/;
1806 die "type check ('integer') failed - got '$value'\n";
1807 } elsif ($type eq 'number') {
1808 return $value if $value =~ m/^(\d+)(\.\d+)?$/;
1809 die "type check ('number') failed - got '$value'\n";
1810 } elsif ($type eq 'string') {
1811 if (my $fmt = $confdesc->{$key}->{format
}) {
1812 if ($fmt eq 'pve-qm-drive') {
1813 # special case - we need to pass $key to parse_drive()
1814 my $drive = parse_drive
($key, $value);
1815 return $value if $drive;
1816 die "unable to parse drive options\n";
1818 PVE
::JSONSchema
::check_format
($fmt, $value);
1821 $value =~ s/^\"(.*)\"$/$1/;
1824 die "internal error"
1828 sub lock_config_full
{
1829 my ($vmid, $timeout, $code, @param) = @_;
1831 my $filename = config_file_lock
($vmid);
1833 my $res = lock_file
($filename, $timeout, $code, @param);
1840 sub lock_config_mode
{
1841 my ($vmid, $timeout, $shared, $code, @param) = @_;
1843 my $filename = config_file_lock
($vmid);
1845 my $res = lock_file_full
($filename, $timeout, $shared, $code, @param);
1853 my ($vmid, $code, @param) = @_;
1855 return lock_config_full
($vmid, 10, $code, @param);
1858 sub cfs_config_path
{
1859 my ($vmid, $node) = @_;
1861 $node = $nodename if !$node;
1862 return "nodes/$node/qemu-server/$vmid.conf";
1865 sub check_iommu_support
{
1866 #fixme : need to check IOMMU support
1867 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1875 my ($vmid, $node) = @_;
1877 my $cfspath = cfs_config_path
($vmid, $node);
1878 return "/etc/pve/$cfspath";
1881 sub config_file_lock
{
1884 return "$lock_dir/lock-$vmid.conf";
1890 my $conf = config_file
($vmid);
1891 utime undef, undef, $conf;
1895 my ($storecfg, $vmid, $keep_empty_config) = @_;
1897 my $conffile = config_file
($vmid);
1899 my $conf = load_config
($vmid);
1903 # only remove disks owned by this VM
1904 foreach_drive
($conf, sub {
1905 my ($ds, $drive) = @_;
1907 return if drive_is_cdrom
($drive);
1909 my $volid = $drive->{file
};
1911 return if !$volid || $volid =~ m
|^/|;
1913 my ($path, $owner) = PVE
::Storage
::path
($storecfg, $volid);
1914 return if !$path || !$owner || ($owner != $vmid);
1916 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1919 if ($keep_empty_config) {
1920 PVE
::Tools
::file_set_contents
($conffile, "memory: 128\n");
1925 # also remove unused disk
1927 my $dl = PVE
::Storage
::vdisk_list
($storecfg, undef, $vmid);
1930 PVE
::Storage
::foreach_volid
($dl, sub {
1931 my ($volid, $sid, $volname, $d) = @_;
1932 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1942 my ($vmid, $node) = @_;
1944 my $cfspath = cfs_config_path
($vmid, $node);
1946 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath);
1948 die "no such VM ('$vmid')\n" if !defined($conf);
1953 sub parse_vm_config
{
1954 my ($filename, $raw) = @_;
1956 return undef if !defined($raw);
1959 digest
=> Digest
::SHA
::sha1_hex
($raw),
1964 $filename =~ m
|/qemu-server/(\d
+)\
.conf
$|
1965 || die "got strange filename '$filename'";
1973 my @lines = split(/\n/, $raw);
1974 foreach my $line (@lines) {
1975 next if $line =~ m/^\s*$/;
1977 if ($line =~ m/^\[PENDING\]\s*$/i) {
1978 $section = 'pending';
1979 $conf->{description
} = $descr if $descr;
1981 $conf = $res->{$section} = {};
1984 } elsif ($line =~ m/^\[([a-z][a-z0-9_\-]+)\]\s*$/i) {
1986 $conf->{description
} = $descr if $descr;
1988 $conf = $res->{snapshots
}->{$section} = {};
1992 if ($line =~ m/^\#(.*)\s*$/) {
1993 $descr .= PVE
::Tools
::decode_text
($1) . "\n";
1997 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
1998 $descr .= PVE
::Tools
::decode_text
($2);
1999 } elsif ($line =~ m/snapstate:\s*(prepare|delete)\s*$/) {
2000 $conf->{snapstate
} = $1;
2001 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
2004 $conf->{$key} = $value;
2005 } elsif ($line =~ m/^delete:\s*(.*\S)\s*$/) {
2007 if ($section eq 'pending') {
2008 $conf->{delete} = $value; # we parse this later
2010 warn "vm $vmid - propertry 'delete' is only allowed in [PENDING]\n";
2012 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
2015 eval { $value = check_type
($key, $value); };
2017 warn "vm $vmid - unable to parse value of '$key' - $@";
2019 my $fmt = $confdesc->{$key}->{format
};
2020 if ($fmt && $fmt eq 'pve-qm-drive') {
2021 my $v = parse_drive
($key, $value);
2022 if (my $volid = filename_to_volume_id
($vmid, $v->{file
}, $v->{media
})) {
2023 $v->{file
} = $volid;
2024 $value = print_drive
($vmid, $v);
2026 warn "vm $vmid - unable to parse value of '$key'\n";
2031 if ($key eq 'cdrom') {
2032 $conf->{ide2
} = $value;
2034 $conf->{$key} = $value;
2040 $conf->{description
} = $descr if $descr;
2042 delete $res->{snapstate
}; # just to be sure
2047 sub write_vm_config
{
2048 my ($filename, $conf) = @_;
2050 delete $conf->{snapstate
}; # just to be sure
2052 if ($conf->{cdrom
}) {
2053 die "option ide2 conflicts with cdrom\n" if $conf->{ide2
};
2054 $conf->{ide2
} = $conf->{cdrom
};
2055 delete $conf->{cdrom
};
2058 # we do not use 'smp' any longer
2059 if ($conf->{sockets
}) {
2060 delete $conf->{smp
};
2061 } elsif ($conf->{smp
}) {
2062 $conf->{sockets
} = $conf->{smp
};
2063 delete $conf->{cores
};
2064 delete $conf->{smp
};
2067 my $used_volids = {};
2069 my $cleanup_config = sub {
2070 my ($cref, $pending, $snapname) = @_;
2072 foreach my $key (keys %$cref) {
2073 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots' ||
2074 $key eq 'snapstate' || $key eq 'pending';
2075 my $value = $cref->{$key};
2076 if ($key eq 'delete') {
2077 die "propertry 'delete' is only allowed in [PENDING]\n"
2079 # fixme: check syntax?
2082 eval { $value = check_type
($key, $value); };
2083 die "unable to parse value of '$key' - $@" if $@;
2085 $cref->{$key} = $value;
2087 if (!$snapname && valid_drivename
($key)) {
2088 my $drive = parse_drive
($key, $value);
2089 $used_volids->{$drive->{file
}} = 1 if $drive && $drive->{file
};
2094 &$cleanup_config($conf);
2096 &$cleanup_config($conf->{pending
}, 1);
2098 foreach my $snapname (keys %{$conf->{snapshots
}}) {
2099 die "internal error" if $snapname eq 'pending';
2100 &$cleanup_config($conf->{snapshots
}->{$snapname}, undef, $snapname);
2103 # remove 'unusedX' settings if we re-add a volume
2104 foreach my $key (keys %$conf) {
2105 my $value = $conf->{$key};
2106 if ($key =~ m/^unused/ && $used_volids->{$value}) {
2107 delete $conf->{$key};
2111 my $generate_raw_config = sub {
2116 # add description as comment to top of file
2117 my $descr = $conf->{description
} || '';
2118 foreach my $cl (split(/\n/, $descr)) {
2119 $raw .= '#' . PVE
::Tools
::encode_text
($cl) . "\n";
2122 foreach my $key (sort keys %$conf) {
2123 next if $key eq 'digest' || $key eq 'description' || $key eq 'pending' || $key eq 'snapshots';
2124 $raw .= "$key: $conf->{$key}\n";
2129 my $raw = &$generate_raw_config($conf);
2131 if (scalar(keys %{$conf->{pending
}})){
2132 $raw .= "\n[PENDING]\n";
2133 $raw .= &$generate_raw_config($conf->{pending
});
2136 foreach my $snapname (sort keys %{$conf->{snapshots
}}) {
2137 $raw .= "\n[$snapname]\n";
2138 $raw .= &$generate_raw_config($conf->{snapshots
}->{$snapname});
2144 sub update_config_nolock
{
2145 my ($vmid, $conf, $skiplock) = @_;
2147 check_lock
($conf) if !$skiplock;
2149 my $cfspath = cfs_config_path
($vmid);
2151 PVE
::Cluster
::cfs_write_file
($cfspath, $conf);
2155 my ($vmid, $conf, $skiplock) = @_;
2157 lock_config
($vmid, &update_config_nolock
, $conf, $skiplock);
2164 # we use static defaults from our JSON schema configuration
2165 foreach my $key (keys %$confdesc) {
2166 if (defined(my $default = $confdesc->{$key}->{default})) {
2167 $res->{$key} = $default;
2171 my $conf = PVE
::Cluster
::cfs_read_file
('datacenter.cfg');
2172 $res->{keyboard
} = $conf->{keyboard
} if $conf->{keyboard
};
2178 my $vmlist = PVE
::Cluster
::get_vmlist
();
2180 return $res if !$vmlist || !$vmlist->{ids
};
2181 my $ids = $vmlist->{ids
};
2183 foreach my $vmid (keys %$ids) {
2184 my $d = $ids->{$vmid};
2185 next if !$d->{node
} || $d->{node
} ne $nodename;
2186 next if !$d->{type
} || $d->{type
} ne 'qemu';
2187 $res->{$vmid}->{exists} = 1;
2192 # test if VM uses local resources (to prevent migration)
2193 sub check_local_resources
{
2194 my ($conf, $noerr) = @_;
2198 $loc_res = 1 if $conf->{hostusb
}; # old syntax
2199 $loc_res = 1 if $conf->{hostpci
}; # old syntax
2201 foreach my $k (keys %$conf) {
2202 next if $k =~ m/^usb/ && ($conf->{$k} eq 'spice');
2203 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
2206 die "VM uses local resources\n" if $loc_res && !$noerr;
2211 # check if used storages are available on all nodes (use by migrate)
2212 sub check_storage_availability
{
2213 my ($storecfg, $conf, $node) = @_;
2215 foreach_drive
($conf, sub {
2216 my ($ds, $drive) = @_;
2218 my $volid = $drive->{file
};
2221 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
2224 # check if storage is available on both nodes
2225 my $scfg = PVE
::Storage
::storage_check_node
($storecfg, $sid);
2226 PVE
::Storage
::storage_check_node
($storecfg, $sid, $node);
2230 # list nodes where all VM images are available (used by has_feature API)
2232 my ($conf, $storecfg) = @_;
2234 my $nodelist = PVE
::Cluster
::get_nodelist
();
2235 my $nodehash = { map { $_ => 1 } @$nodelist };
2236 my $nodename = PVE
::INotify
::nodename
();
2238 foreach_drive
($conf, sub {
2239 my ($ds, $drive) = @_;
2241 my $volid = $drive->{file
};
2244 my ($storeid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
2246 my $scfg = PVE
::Storage
::storage_config
($storecfg, $storeid);
2247 if ($scfg->{disable
}) {
2249 } elsif (my $avail = $scfg->{nodes
}) {
2250 foreach my $node (keys %$nodehash) {
2251 delete $nodehash->{$node} if !$avail->{$node};
2253 } elsif (!$scfg->{shared
}) {
2254 foreach my $node (keys %$nodehash) {
2255 delete $nodehash->{$node} if $node ne $nodename
2267 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
2271 my ($pidfile, $pid) = @_;
2273 my $fh = IO
::File-
>new("/proc/$pid/cmdline", "r");
2277 return undef if !$line;
2278 my @param = split(/\0/, $line);
2280 my $cmd = $param[0];
2281 return if !$cmd || ($cmd !~ m
|kvm
$| && $cmd !~ m
|qemu-system-x86_64
$|);
2283 for (my $i = 0; $i < scalar (@param); $i++) {
2286 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
2287 my $p = $param[$i+1];
2288 return 1 if $p && ($p eq $pidfile);
2297 my ($vmid, $nocheck, $node) = @_;
2299 my $filename = config_file
($vmid, $node);
2301 die "unable to find configuration file for VM $vmid - no such machine\n"
2302 if !$nocheck && ! -f
$filename;
2304 my $pidfile = pidfile_name
($vmid);
2306 if (my $fd = IO
::File-
>new("<$pidfile")) {
2311 my $mtime = $st->mtime;
2312 if ($mtime > time()) {
2313 warn "file '$filename' modified in future\n";
2316 if ($line =~ m/^(\d+)$/) {
2318 if (check_cmdline
($pidfile, $pid)) {
2319 if (my $pinfo = PVE
::ProcFSTools
::check_process_running
($pid)) {
2331 my $vzlist = config_list
();
2333 my $fd = IO
::Dir-
>new($var_run_tmpdir) || return $vzlist;
2335 while (defined(my $de = $fd->read)) {
2336 next if $de !~ m/^(\d+)\.pid$/;
2338 next if !defined($vzlist->{$vmid});
2339 if (my $pid = check_running
($vmid)) {
2340 $vzlist->{$vmid}->{pid
} = $pid;
2348 my ($storecfg, $conf) = @_;
2350 my $bootdisk = $conf->{bootdisk
};
2351 return undef if !$bootdisk;
2352 return undef if !valid_drivename
($bootdisk);
2354 return undef if !$conf->{$bootdisk};
2356 my $drive = parse_drive
($bootdisk, $conf->{$bootdisk});
2357 return undef if !defined($drive);
2359 return undef if drive_is_cdrom
($drive);
2361 my $volid = $drive->{file
};
2362 return undef if !$volid;
2364 return $drive->{size
};
2367 my $last_proc_pid_stat;
2369 # get VM status information
2370 # This must be fast and should not block ($full == false)
2371 # We only query KVM using QMP if $full == true (this can be slow)
2373 my ($opt_vmid, $full) = @_;
2377 my $storecfg = PVE
::Storage
::config
();
2379 my $list = vzlist
();
2380 my ($uptime) = PVE
::ProcFSTools
::read_proc_uptime
(1);
2382 my $cpucount = $cpuinfo->{cpus
} || 1;
2384 foreach my $vmid (keys %$list) {
2385 next if $opt_vmid && ($vmid ne $opt_vmid);
2387 my $cfspath = cfs_config_path
($vmid);
2388 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath) || {};
2391 $d->{pid
} = $list->{$vmid}->{pid
};
2393 # fixme: better status?
2394 $d->{status
} = $list->{$vmid}->{pid
} ?
'running' : 'stopped';
2396 my $size = disksize
($storecfg, $conf);
2397 if (defined($size)) {
2398 $d->{disk
} = 0; # no info available
2399 $d->{maxdisk
} = $size;
2405 $d->{cpus
} = ($conf->{sockets
} || 1) * ($conf->{cores
} || 1);
2406 $d->{cpus
} = $cpucount if $d->{cpus
} > $cpucount;
2407 $d->{cpus
} = $conf->{vcpus
} if $conf->{vcpus
};
2409 $d->{name
} = $conf->{name
} || "VM $vmid";
2410 $d->{maxmem
} = $conf->{memory
} ?
$conf->{memory
}*(1024*1024) : 0;
2412 if ($conf->{balloon
}) {
2413 $d->{balloon_min
} = $conf->{balloon
}*(1024*1024);
2414 $d->{shares
} = defined($conf->{shares
}) ?
$conf->{shares
} : 1000;
2425 $d->{diskwrite
} = 0;
2427 $d->{template
} = is_template
($conf);
2432 my $netdev = PVE
::ProcFSTools
::read_proc_net_dev
();
2433 foreach my $dev (keys %$netdev) {
2434 next if $dev !~ m/^tap([1-9]\d*)i/;
2436 my $d = $res->{$vmid};
2439 $d->{netout
} += $netdev->{$dev}->{receive
};
2440 $d->{netin
} += $netdev->{$dev}->{transmit
};
2443 my $ctime = gettimeofday
;
2445 foreach my $vmid (keys %$list) {
2447 my $d = $res->{$vmid};
2448 my $pid = $d->{pid
};
2451 my $pstat = PVE
::ProcFSTools
::read_proc_pid_stat
($pid);
2452 next if !$pstat; # not running
2454 my $used = $pstat->{utime} + $pstat->{stime
};
2456 $d->{uptime
} = int(($uptime - $pstat->{starttime
})/$cpuinfo->{user_hz
});
2458 if ($pstat->{vsize
}) {
2459 $d->{mem
} = int(($pstat->{rss
}/$pstat->{vsize
})*$d->{maxmem
});
2462 my $old = $last_proc_pid_stat->{$pid};
2464 $last_proc_pid_stat->{$pid} = {
2472 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz
};
2474 if ($dtime > 1000) {
2475 my $dutime = $used - $old->{used
};
2477 $d->{cpu
} = (($dutime/$dtime)* $cpucount) / $d->{cpus
};
2478 $last_proc_pid_stat->{$pid} = {
2484 $d->{cpu
} = $old->{cpu
};
2488 return $res if !$full;
2490 my $qmpclient = PVE
::QMPClient-
>new();
2492 my $ballooncb = sub {
2493 my ($vmid, $resp) = @_;
2495 my $info = $resp->{'return'};
2496 return if !$info->{max_mem
};
2498 my $d = $res->{$vmid};
2500 # use memory assigned to VM
2501 $d->{maxmem
} = $info->{max_mem
};
2502 $d->{balloon
} = $info->{actual
};
2504 if (defined($info->{total_mem
}) && defined($info->{free_mem
})) {
2505 $d->{mem
} = $info->{total_mem
} - $info->{free_mem
};
2506 $d->{freemem
} = $info->{free_mem
};
2511 my $blockstatscb = sub {
2512 my ($vmid, $resp) = @_;
2513 my $data = $resp->{'return'} || [];
2514 my $totalrdbytes = 0;
2515 my $totalwrbytes = 0;
2516 for my $blockstat (@$data) {
2517 $totalrdbytes = $totalrdbytes + $blockstat->{stats
}->{rd_bytes
};
2518 $totalwrbytes = $totalwrbytes + $blockstat->{stats
}->{wr_bytes
};
2520 $res->{$vmid}->{diskread
} = $totalrdbytes;
2521 $res->{$vmid}->{diskwrite
} = $totalwrbytes;
2524 my $statuscb = sub {
2525 my ($vmid, $resp) = @_;
2527 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
2528 # this fails if ballon driver is not loaded, so this must be
2529 # the last commnand (following command are aborted if this fails).
2530 $qmpclient->queue_cmd($vmid, $ballooncb, 'query-balloon');
2532 my $status = 'unknown';
2533 if (!defined($status = $resp->{'return'}->{status
})) {
2534 warn "unable to get VM status\n";
2538 $res->{$vmid}->{qmpstatus
} = $resp->{'return'}->{status
};
2541 foreach my $vmid (keys %$list) {
2542 next if $opt_vmid && ($vmid ne $opt_vmid);
2543 next if !$res->{$vmid}->{pid
}; # not running
2544 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2547 $qmpclient->queue_execute(undef, 1);
2549 foreach my $vmid (keys %$list) {
2550 next if $opt_vmid && ($vmid ne $opt_vmid);
2551 $res->{$vmid}->{qmpstatus
} = $res->{$vmid}->{status
} if !$res->{$vmid}->{qmpstatus
};
2558 my ($conf, $vmid, $memory, $sockets, $func) = @_;
2561 my $current_size = 1024;
2562 my $dimm_size = 512;
2563 return if $current_size == $memory;
2565 for (my $j = 0; $j < 8; $j++) {
2566 for (my $i = 0; $i < 32; $i++) {
2567 my $name = "dimm${dimm_id}";
2569 my $numanode = $i % $sockets;
2570 $current_size += $dimm_size;
2571 &$func($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory);
2572 return $current_size if $current_size >= $memory;
2579 my ($conf, $func) = @_;
2581 foreach my $ds (keys %$conf) {
2582 next if !valid_drivename
($ds);
2584 my $drive = parse_drive
($ds, $conf->{$ds});
2587 &$func($ds, $drive);
2592 my ($conf, $func) = @_;
2596 my $test_volid = sub {
2597 my ($volid, $is_cdrom) = @_;
2601 $volhash->{$volid} = $is_cdrom || 0;
2604 foreach_drive
($conf, sub {
2605 my ($ds, $drive) = @_;
2606 &$test_volid($drive->{file
}, drive_is_cdrom
($drive));
2609 foreach my $snapname (keys %{$conf->{snapshots
}}) {
2610 my $snap = $conf->{snapshots
}->{$snapname};
2611 &$test_volid($snap->{vmstate
}, 0);
2612 foreach_drive
($snap, sub {
2613 my ($ds, $drive) = @_;
2614 &$test_volid($drive->{file
}, drive_is_cdrom
($drive));
2618 foreach my $volid (keys %$volhash) {
2619 &$func($volid, $volhash->{$volid});
2623 sub vga_conf_has_spice
{
2626 return 0 if !$vga || $vga !~ m/^qxl([234])?$/;
2631 sub config_to_command
{
2632 my ($storecfg, $vmid, $conf, $defaults, $forcemachine) = @_;
2635 my $globalFlags = [];
2636 my $machineFlags = [];
2642 my $kvmver = kvm_user_version
();
2643 my $vernum = 0; # unknown
2644 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2645 $vernum = $1*1000000+$2*1000;
2646 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
2647 $vernum = $1*1000000+$2*1000+$3;
2650 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
2652 my $have_ovz = -f
'/proc/vz/vestat';
2654 my $q35 = machine_type_is_q35
($conf);
2655 my $hotplug_features = parse_hotplug_features
(defined($conf->{hotplug
}) ?
$conf->{hotplug
} : '1');
2656 my $machine_type = $forcemachine || $conf->{machine
};
2658 push @$cmd, '/usr/bin/kvm';
2660 push @$cmd, '-id', $vmid;
2664 my $qmpsocket = qmp_socket
($vmid);
2665 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2666 push @$cmd, '-mon', "chardev=qmp,mode=control";
2668 my $socket = vnc_socket
($vmid);
2669 push @$cmd, '-vnc', "unix:$socket,x509,password";
2671 push @$cmd, '-pidfile' , pidfile_name
($vmid);
2673 push @$cmd, '-daemonize';
2675 if ($conf->{smbios1
}) {
2676 push @$cmd, '-smbios', "type=1,$conf->{smbios1}";
2680 # the q35 chipset support native usb2, so we enable usb controller
2681 # by default for this machine type
2682 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-q35.cfg';
2684 $pciaddr = print_pci_addr
("piix3", $bridges);
2685 push @$devices, '-device', "piix3-usb-uhci,id=uhci$pciaddr.0x2";
2688 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2689 next if !$conf->{"usb$i"};
2692 # include usb device config
2693 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
2696 my $vga = $conf->{vga
};
2698 my $qxlnum = vga_conf_has_spice
($vga);
2699 $vga = 'qxl' if $qxlnum;
2702 if ($conf->{ostype
} && ($conf->{ostype
} eq 'win8' ||
2703 $conf->{ostype
} eq 'win7' ||
2704 $conf->{ostype
} eq 'w2k8')) {
2711 # enable absolute mouse coordinates (needed by vnc)
2713 if (defined($conf->{tablet
})) {
2714 $tablet = $conf->{tablet
};
2716 $tablet = $defaults->{tablet
};
2717 $tablet = 0 if $qxlnum; # disable for spice because it is not needed
2718 $tablet = 0 if $vga =~ m/^serial\d+$/; # disable if we use serial terminal (no vga card)
2721 push @$devices, '-device', print_tabletdevice_full
($conf) if $tablet;
2724 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2725 my $d = parse_hostpci
($conf->{"hostpci$i"});
2728 my $pcie = $d->{pcie
};
2730 die "q35 machine model is not enabled" if !$q35;
2731 $pciaddr = print_pcie_addr
("hostpci$i");
2733 $pciaddr = print_pci_addr
("hostpci$i", $bridges);
2736 my $rombar = $d->{rombar
} && $d->{rombar
} eq 'off' ?
",rombar=0" : "";
2737 my $driver = $d->{driver
} && $d->{driver
} eq 'vfio' ?
"vfio-pci" : "pci-assign";
2738 my $xvga = $d->{'x-vga'} && $d->{'x-vga'} eq 'on' ?
",x-vga=on" : "";
2739 if ($xvga && $xvga ne '') {
2740 push @$cpuFlags, 'kvm=off';
2743 $driver = "vfio-pci" if $xvga ne '';
2744 my $pcidevices = $d->{pciid
};
2745 my $multifunction = 1 if @$pcidevices > 1;
2748 foreach my $pcidevice (@$pcidevices) {
2750 my $id = "hostpci$i";
2751 $id .= ".$j" if $multifunction;
2752 my $addr = $pciaddr;
2753 $addr .= ".$j" if $multifunction;
2754 my $devicestr = "$driver,host=$pcidevice->{id}.$pcidevice->{function},id=$id$addr";
2757 $devicestr .= "$rombar$xvga";
2758 $devicestr .= ",multifunction=on" if $multifunction;
2761 push @$devices, '-device', $devicestr;
2767 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2768 my $d = parse_usb_device
($conf->{"usb$i"});
2770 if ($d->{vendorid
} && $d->{productid
}) {
2771 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
2772 } elsif (defined($d->{hostbus
}) && defined($d->{hostport
})) {
2773 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
2774 } elsif ($d->{spice
}) {
2775 # usb redir support for spice
2776 push @$devices, '-chardev', "spicevmc,id=usbredirchardev$i,name=usbredir";
2777 push @$devices, '-device', "usb-redir,chardev=usbredirchardev$i,id=usbredirdev$i,bus=ehci.0";
2782 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
2783 if (my $path = $conf->{"serial$i"}) {
2784 if ($path eq 'socket') {
2785 my $socket = "/var/run/qemu-server/${vmid}.serial$i";
2786 push @$devices, '-chardev', "socket,id=serial$i,path=$socket,server,nowait";
2787 push @$devices, '-device', "isa-serial,chardev=serial$i";
2789 die "no such serial device\n" if ! -c
$path;
2790 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2791 push @$devices, '-device', "isa-serial,chardev=serial$i";
2797 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
2798 if (my $path = $conf->{"parallel$i"}) {
2799 die "no such parallel device\n" if ! -c
$path;
2800 my $devtype = $path =~ m!^/dev/usb/lp! ?
'tty' : 'parport';
2801 push @$devices, '-chardev', "$devtype,id=parallel$i,path=$path";
2802 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
2806 my $vmname = $conf->{name
} || "vm$vmid";
2808 push @$cmd, '-name', $vmname;
2811 $sockets = $conf->{smp
} if $conf->{smp
}; # old style - no longer iused
2812 $sockets = $conf->{sockets
} if $conf->{sockets
};
2814 my $cores = $conf->{cores
} || 1;
2816 my $maxcpus = $sockets * $cores;
2818 my $vcpus = $conf->{vcpus
} ?
$conf->{vcpus
} : $maxcpus;
2820 my $allowed_vcpus = $cpuinfo->{cpus
};
2822 die "MAX $maxcpus vcpus allowed per VM on this node\n"
2823 if ($allowed_vcpus < $maxcpus);
2825 push @$cmd, '-smp', "$vcpus,sockets=$sockets,cores=$cores,maxcpus=$maxcpus";
2827 push @$cmd, '-nodefaults';
2829 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
2831 my $bootindex_hash = {};
2833 foreach my $o (split(//, $bootorder)) {
2834 $bootindex_hash->{$o} = $i*100;
2838 push @$cmd, '-boot', "menu=on,strict=on,reboot-timeout=1000";
2840 push @$cmd, '-no-acpi' if defined($conf->{acpi
}) && $conf->{acpi
} == 0;
2842 push @$cmd, '-no-reboot' if defined($conf->{reboot
}) && $conf->{reboot
} == 0;
2844 push @$cmd, '-vga', $vga if $vga && $vga !~ m/^serial\d+$/; # for kvm 77 and later
2847 my $tdf = defined($conf->{tdf
}) ?
$conf->{tdf
} : $defaults->{tdf
};
2849 my $nokvm = defined($conf->{kvm
}) && $conf->{kvm
} == 0 ?
1 : 0;
2850 my $useLocaltime = $conf->{localtime};
2852 if (my $ost = $conf->{ostype
}) {
2853 # other, wxp, w2k, w2k3, w2k8, wvista, win7, win8, l24, l26, solaris
2855 if ($ost =~ m/^w/) { # windows
2856 $useLocaltime = 1 if !defined($conf->{localtime});
2858 # use time drift fix when acpi is enabled
2859 if (!(defined($conf->{acpi
}) && $conf->{acpi
} == 0)) {
2860 $tdf = 1 if !defined($conf->{tdf
});
2864 if ($ost eq 'win7' || $ost eq 'win8' || $ost eq 'w2k8' ||
2866 push @$globalFlags, 'kvm-pit.lost_tick_policy=discard';
2867 push @$cmd, '-no-hpet';
2868 if (qemu_machine_feature_enabled
($machine_type, $kvmver, 2, 3)) {
2869 push @$cpuFlags , 'hv_spinlocks=0x1fff' if !$nokvm;
2870 push @$cpuFlags , 'hv_vapic' if !$nokvm;
2871 push @$cpuFlags , 'hv_time' if !$nokvm;
2874 push @$cpuFlags , 'hv_spinlocks=0xffff' if !$nokvm;
2878 if ($ost eq 'win7' || $ost eq 'win8') {
2879 push @$cpuFlags , 'hv_relaxed' if !$nokvm;
2883 push @$rtcFlags, 'driftfix=slew' if $tdf;
2886 push @$machineFlags, 'accel=tcg';
2888 die "No accelerator found!\n" if !$cpuinfo->{hvm
};
2891 if ($machine_type) {
2892 push @$machineFlags, "type=${machine_type}";
2895 if ($conf->{startdate
}) {
2896 push @$rtcFlags, "base=$conf->{startdate}";
2897 } elsif ($useLocaltime) {
2898 push @$rtcFlags, 'base=localtime';
2901 my $cpu = $nokvm ?
"qemu64" : "kvm64";
2902 $cpu = $conf->{cpu
} if $conf->{cpu
};
2904 push @$cpuFlags , '+lahf_lm' if $cpu eq 'kvm64';
2906 push @$cpuFlags , '+x2apic' if !$nokvm && $conf->{ostype
} ne 'solaris';
2908 push @$cpuFlags , '-x2apic' if $conf->{ostype
} eq 'solaris';
2910 push @$cpuFlags, '+sep' if $cpu eq 'kvm64' || $cpu eq 'kvm32';
2912 if (qemu_machine_feature_enabled
($machine_type, $kvmver, 2, 3)) {
2914 push @$cpuFlags , '+kvm_pv_unhalt' if !$nokvm;
2915 push @$cpuFlags , '+kvm_pv_eoi' if !$nokvm;
2918 $cpu .= "," . join(',', @$cpuFlags) if scalar(@$cpuFlags);
2920 push @$cmd, '-cpu', "$cpu,enforce";
2922 my $memory = $conf->{memory
} || $defaults->{memory
};
2923 my $static_memory = 0;
2924 my $dimm_memory = 0;
2926 if ($hotplug_features->{memory
}) {
2927 die "Numa need to be enabled for memory hotplug\n" if !$conf->{numa
};
2928 die "Total memory is bigger than ${MAX_MEM}MB\n" if $memory > $MAX_MEM;
2929 $static_memory = $STATICMEM;
2930 die "minimum memory must be ${static_memory}MB\n" if($memory < $static_memory);
2931 $dimm_memory = $memory - $static_memory;
2932 push @$cmd, '-m', "size=${static_memory},slots=255,maxmem=${MAX_MEM}M";
2936 $static_memory = $memory;
2937 push @$cmd, '-m', $static_memory;
2940 if ($conf->{numa
}) {
2942 my $numa_totalmemory = undef;
2943 for (my $i = 0; $i < $MAX_NUMA; $i++) {
2944 next if !$conf->{"numa$i"};
2945 my $numa = parse_numa
($conf->{"numa$i"});
2948 die "missing numa node$i memory value\n" if !$numa->{memory
};
2949 my $numa_memory = $numa->{memory
};
2950 $numa_totalmemory += $numa_memory;
2951 my $numa_object = "memory-backend-ram,id=ram-node$i,size=${numa_memory}M";
2954 my $cpus_start = $numa->{cpus
}->{start
};
2955 die "missing numa node$i cpus\n" if !defined($cpus_start);
2956 my $cpus_end = $numa->{cpus
}->{end
} if defined($numa->{cpus
}->{end
});
2957 my $cpus = $cpus_start;
2958 if (defined($cpus_end)) {
2959 $cpus .= "-$cpus_end";
2960 die "numa node$i : cpu range $cpus is incorrect\n" if $cpus_end <= $cpus_start;
2964 my $hostnodes_start = $numa->{hostnodes
}->{start
};
2965 if (defined($hostnodes_start)) {
2966 my $hostnodes_end = $numa->{hostnodes
}->{end
} if defined($numa->{hostnodes
}->{end
});
2967 my $hostnodes = $hostnodes_start;
2968 if (defined($hostnodes_end)) {
2969 $hostnodes .= "-$hostnodes_end";
2970 die "host node $hostnodes range is incorrect\n" if $hostnodes_end <= $hostnodes_start;
2973 my $hostnodes_end_range = defined($hostnodes_end) ?
$hostnodes_end : $hostnodes_start;
2974 for (my $i = $hostnodes_start; $i <= $hostnodes_end_range; $i++ ) {
2975 die "host numa node$i don't exist\n" if ! -d
"/sys/devices/system/node/node$i/";
2979 my $policy = $numa->{policy
};
2980 die "you need to define a policy for hostnode $hostnodes\n" if !$policy;
2981 $numa_object .= ",host-nodes=$hostnodes,policy=$policy";
2984 push @$cmd, '-object', $numa_object;
2985 push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=ram-node$i";
2988 die "total memory for NUMA nodes must be equal to vm static memory\n"
2989 if $numa_totalmemory && $numa_totalmemory != $static_memory;
2991 #if no custom tology, we split memory and cores across numa nodes
2992 if(!$numa_totalmemory) {
2994 my $numa_memory = ($static_memory / $sockets) . "M";
2996 for (my $i = 0; $i < $sockets; $i++) {
2998 my $cpustart = ($cores * $i);
2999 my $cpuend = ($cpustart + $cores - 1) if $cores && $cores > 1;
3000 my $cpus = $cpustart;
3001 $cpus .= "-$cpuend" if $cpuend;
3003 push @$cmd, '-object', "memory-backend-ram,size=$numa_memory,id=ram-node$i";
3004 push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=ram-node$i";
3009 if ($hotplug_features->{memory
}) {
3010 foreach_dimm
($conf, $vmid, $memory, $sockets, sub {
3011 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
3012 push @$cmd, "-object" , "memory-backend-ram,id=mem-$name,size=${dimm_size}M";
3013 push @$cmd, "-device", "pc-dimm,id=$name,memdev=mem-$name,node=$numanode";
3015 #if dimm_memory is not aligned to dimm map
3016 if($current_size > $memory) {
3017 $conf->{memory
} = $current_size;
3018 update_config_nolock
($vmid, $conf, 1);
3023 push @$cmd, '-S' if $conf->{freeze
};
3025 # set keyboard layout
3026 my $kb = $conf->{keyboard
} || $defaults->{keyboard
};
3027 push @$cmd, '-k', $kb if $kb;
3030 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
3031 #push @$cmd, '-soundhw', 'es1370';
3032 #push @$cmd, '-soundhw', $soundhw if $soundhw;
3034 if($conf->{agent
}) {
3035 my $qgasocket = qmp_socket
($vmid, 1);
3036 my $pciaddr = print_pci_addr
("qga0", $bridges);
3037 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
3038 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
3039 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
3046 if ($conf->{ostype
} && $conf->{ostype
} =~ m/^w/){
3047 for(my $i = 1; $i < $qxlnum; $i++){
3048 my $pciaddr = print_pci_addr
("vga$i", $bridges);
3049 push @$cmd, '-device', "qxl,id=vga$i,ram_size=67108864,vram_size=33554432$pciaddr";
3052 # assume other OS works like Linux
3053 push @$cmd, '-global', 'qxl-vga.ram_size=134217728';
3054 push @$cmd, '-global', 'qxl-vga.vram_size=67108864';
3058 my $pciaddr = print_pci_addr
("spice", $bridges);
3060 $spice_port = PVE
::Tools
::next_spice_port
();
3062 push @$devices, '-spice', "tls-port=${spice_port},addr=127.0.0.1,tls-ciphers=DES-CBC3-SHA,seamless-migration=on";
3064 push @$devices, '-device', "virtio-serial,id=spice$pciaddr";
3065 push @$devices, '-chardev', "spicevmc,id=vdagent,name=vdagent";
3066 push @$devices, '-device', "virtserialport,chardev=vdagent,name=com.redhat.spice.0";
3069 # enable balloon by default, unless explicitly disabled
3070 if (!defined($conf->{balloon
}) || $conf->{balloon
}) {
3071 $pciaddr = print_pci_addr
("balloon0", $bridges);
3072 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr";
3075 if ($conf->{watchdog
}) {
3076 my $wdopts = parse_watchdog
($conf->{watchdog
});
3077 $pciaddr = print_pci_addr
("watchdog", $bridges);
3078 my $watchdog = $wdopts->{model
} || 'i6300esb';
3079 push @$devices, '-device', "$watchdog$pciaddr";
3080 push @$devices, '-watchdog-action', $wdopts->{action
} if $wdopts->{action
};
3084 my $scsicontroller = {};
3085 my $ahcicontroller = {};
3086 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : $defaults->{scsihw
};
3088 # Add iscsi initiator name if available
3089 if (my $initiator = get_initiator_name
()) {
3090 push @$devices, '-iscsi', "initiator-name=$initiator";
3093 foreach_drive
($conf, sub {
3094 my ($ds, $drive) = @_;
3096 if (PVE
::Storage
::parse_volume_id
($drive->{file
}, 1)) {
3097 push @$vollist, $drive->{file
};
3100 $use_virtio = 1 if $ds =~ m/^virtio/;
3102 if (drive_is_cdrom
($drive)) {
3103 if ($bootindex_hash->{d
}) {
3104 $drive->{bootindex
} = $bootindex_hash->{d
};
3105 $bootindex_hash->{d
} += 1;
3108 if ($bootindex_hash->{c
}) {
3109 $drive->{bootindex
} = $bootindex_hash->{c
} if $conf->{bootdisk
} && ($conf->{bootdisk
} eq $ds);
3110 $bootindex_hash->{c
} += 1;
3114 if($drive->{interface
} eq 'virtio'){
3115 push @$cmd, '-object', "iothread,id=iothread-$ds" if $drive->{iothread
};
3118 if ($drive->{interface
} eq 'scsi') {
3120 my ($maxdev, $controller, $controller_prefix) = scsihw_infos
($conf, $drive);
3122 $pciaddr = print_pci_addr
("$controller_prefix$controller", $bridges);
3123 my $scsihw_type = $scsihw =~ m/^virtio-scsi-single/ ?
"virtio-scsi-pci" : $scsihw;
3126 if($conf->{scsihw
} && $conf->{scsihw
} eq "virtio-scsi-single" && $drive->{iothread
}){
3127 $iothread .= ",iothread=iothread-$controller_prefix$controller";
3128 push @$cmd, '-object', "iothread,id=iothread-$controller_prefix$controller";
3131 push @$devices, '-device', "$scsihw_type,id=$controller_prefix$controller$pciaddr$iothread" if !$scsicontroller->{$controller};
3132 $scsicontroller->{$controller}=1;
3135 if ($drive->{interface
} eq 'sata') {
3136 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
3137 $pciaddr = print_pci_addr
("ahci$controller", $bridges);
3138 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
3139 $ahcicontroller->{$controller}=1;
3142 my $drive_cmd = print_drive_full
($storecfg, $vmid, $drive);
3143 push @$devices, '-drive',$drive_cmd;
3144 push @$devices, '-device', print_drivedevice_full
($storecfg, $conf, $vmid, $drive, $bridges);
3147 for (my $i = 0; $i < $MAX_NETS; $i++) {
3148 next if !$conf->{"net$i"};
3149 my $d = parse_net
($conf->{"net$i"});
3152 $use_virtio = 1 if $d->{model
} eq 'virtio';
3154 if ($bootindex_hash->{n
}) {
3155 $d->{bootindex
} = $bootindex_hash->{n
};
3156 $bootindex_hash->{n
} += 1;
3159 my $netdevfull = print_netdev_full
($vmid,$conf,$d,"net$i");
3160 push @$devices, '-netdev', $netdevfull;
3162 my $netdevicefull = print_netdevice_full
($vmid,$conf,$d,"net$i",$bridges);
3163 push @$devices, '-device', $netdevicefull;
3168 if (qemu_machine_feature_enabled
($machine_type, $kvmver, 2, 3)) {
3173 $bridges->{3} = 1 if $scsihw =~ m/^virtio-scsi-single/;
3175 while (my ($k, $v) = each %$bridges) {
3176 $pciaddr = print_pci_addr
("pci.$k");
3177 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
3181 # hack: virtio with fairsched is unreliable, so we do not use fairsched
3182 # when the VM uses virtio devices.
3183 if (!$use_virtio && $have_ovz) {
3185 my $cpuunits = defined($conf->{cpuunits
}) ?
3186 $conf->{cpuunits
} : $defaults->{cpuunits
};
3188 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
3190 # fixme: cpulimit is currently ignored
3191 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
3195 if ($conf->{args
}) {
3196 my $aa = PVE
::Tools
::split_args
($conf->{args
});
3200 push @$cmd, @$devices;
3201 push @$cmd, '-rtc', join(',', @$rtcFlags)
3202 if scalar(@$rtcFlags);
3203 push @$cmd, '-machine', join(',', @$machineFlags)
3204 if scalar(@$machineFlags);
3205 push @$cmd, '-global', join(',', @$globalFlags)
3206 if scalar(@$globalFlags);
3208 return wantarray ?
($cmd, $vollist, $spice_port) : $cmd;
3213 return "${var_run_tmpdir}/$vmid.vnc";
3219 my $res = vm_mon_cmd
($vmid, 'query-spice');
3221 return $res->{'tls-port'} || $res->{'port'} || die "no spice port\n";
3225 my ($vmid, $qga) = @_;
3226 my $sockettype = $qga ?
'qga' : 'qmp';
3227 return "${var_run_tmpdir}/$vmid.$sockettype";
3232 return "${var_run_tmpdir}/$vmid.pid";
3235 sub vm_devices_list
{
3238 my $res = vm_mon_cmd
($vmid, 'query-pci');
3240 foreach my $pcibus (@$res) {
3241 foreach my $device (@{$pcibus->{devices
}}) {
3242 next if !$device->{'qdev_id'};
3243 if ($device->{'pci_bridge'}) {
3244 $devices->{$device->{'qdev_id'}} = 1;
3245 foreach my $bridge_device (@{$device->{'pci_bridge'}->{devices
}}) {
3246 next if !$bridge_device->{'qdev_id'};
3247 $devices->{$bridge_device->{'qdev_id'}} = 1;
3248 $devices->{$device->{'qdev_id'}}++;
3251 $devices->{$device->{'qdev_id'}} = 1;
3256 my $resblock = vm_mon_cmd
($vmid, 'query-block');
3257 foreach my $block (@$resblock) {
3258 if($block->{device
} =~ m/^drive-(\S+)/){
3263 my $resmice = vm_mon_cmd
($vmid, 'query-mice');
3264 foreach my $mice (@$resmice) {
3265 if ($mice->{name
} eq 'QEMU HID Tablet') {
3266 $devices->{tablet
} = 1;
3275 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
3277 my $q35 = machine_type_is_q35
($conf);
3279 my $devices_list = vm_devices_list
($vmid);
3280 return 1 if defined($devices_list->{$deviceid});
3282 qemu_add_pci_bridge
($storecfg, $conf, $vmid, $deviceid); # add PCI bridge if we need it for the device
3284 if ($deviceid eq 'tablet') {
3286 qemu_deviceadd
($vmid, print_tabletdevice_full
($conf));
3288 } elsif ($deviceid =~ m/^(virtio)(\d+)$/) {
3290 qemu_iothread_add
($vmid, $deviceid, $device);
3292 qemu_driveadd
($storecfg, $vmid, $device);
3293 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
3295 qemu_deviceadd
($vmid, $devicefull);
3296 eval { qemu_deviceaddverify
($vmid, $deviceid); };
3298 eval { qemu_drivedel
($vmid, $deviceid); };
3303 } elsif ($deviceid =~ m/^(virtioscsi|scsihw)(\d+)$/) {
3306 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : "lsi";
3307 my $pciaddr = print_pci_addr
($deviceid);
3308 my $scsihw_type = $scsihw eq 'virtio-scsi-single' ?
"virtio-scsi-pci" : $scsihw;
3310 my $devicefull = "$scsihw_type,id=$deviceid$pciaddr";
3312 if($deviceid =~ m/^virtioscsi(\d+)$/ && $device->{iothread
}) {
3313 qemu_iothread_add
($vmid, $deviceid, $device);
3314 $devicefull .= ",iothread=iothread-$deviceid";
3317 qemu_deviceadd
($vmid, $devicefull);
3318 qemu_deviceaddverify
($vmid, $deviceid);
3320 } elsif ($deviceid =~ m/^(scsi)(\d+)$/) {
3322 qemu_findorcreatescsihw
($storecfg,$conf, $vmid, $device);
3323 qemu_driveadd
($storecfg, $vmid, $device);
3325 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
3326 eval { qemu_deviceadd
($vmid, $devicefull); };
3328 eval { qemu_drivedel
($vmid, $deviceid); };
3333 } elsif ($deviceid =~ m/^(net)(\d+)$/) {
3335 return undef if !qemu_netdevadd
($vmid, $conf, $device, $deviceid);
3336 my $netdevicefull = print_netdevice_full
($vmid, $conf, $device, $deviceid);
3337 qemu_deviceadd
($vmid, $netdevicefull);
3338 eval { qemu_deviceaddverify
($vmid, $deviceid); };
3340 eval { qemu_netdevdel
($vmid, $deviceid); };
3345 } elsif (!$q35 && $deviceid =~ m/^(pci\.)(\d+)$/) {
3348 my $pciaddr = print_pci_addr
($deviceid);
3349 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
3351 qemu_deviceadd
($vmid, $devicefull);
3352 qemu_deviceaddverify
($vmid, $deviceid);
3355 die "can't hotplug device '$deviceid'\n";
3361 # fixme: this should raise exceptions on error!
3362 sub vm_deviceunplug
{
3363 my ($vmid, $conf, $deviceid) = @_;
3365 my $devices_list = vm_devices_list
($vmid);
3366 return 1 if !defined($devices_list->{$deviceid});
3368 die "can't unplug bootdisk" if $conf->{bootdisk
} && $conf->{bootdisk
} eq $deviceid;
3370 if ($deviceid eq 'tablet') {
3372 qemu_devicedel
($vmid, $deviceid);
3374 } elsif ($deviceid =~ m/^(virtio)(\d+)$/) {
3376 qemu_devicedel
($vmid, $deviceid);
3377 qemu_devicedelverify
($vmid, $deviceid);
3378 qemu_drivedel
($vmid, $deviceid);
3379 qemu_iothread_del
($conf, $vmid, $deviceid);
3381 } elsif ($deviceid =~ m/^(virtioscsi|scsihw)(\d+)$/) {
3383 qemu_devicedel
($vmid, $deviceid);
3384 qemu_devicedelverify
($vmid, $deviceid);
3385 qemu_iothread_del
($conf, $vmid, $deviceid);
3387 } elsif ($deviceid =~ m/^(scsi)(\d+)$/) {
3389 #qemu 2.3 segfault on drive_del with virtioscsi + iothread
3390 my $device = parse_drive
($deviceid, $conf->{$deviceid});
3391 die "virtioscsi with iothread is not hot-unplugglable currently" if $device->{iothread
};
3393 qemu_devicedel
($vmid, $deviceid);
3394 qemu_drivedel
($vmid, $deviceid);
3395 qemu_deletescsihw
($conf, $vmid, $deviceid);
3397 } elsif ($deviceid =~ m/^(net)(\d+)$/) {
3399 qemu_devicedel
($vmid, $deviceid);
3400 qemu_devicedelverify
($vmid, $deviceid);
3401 qemu_netdevdel
($vmid, $deviceid);
3404 die "can't unplug device '$deviceid'\n";
3410 sub qemu_deviceadd
{
3411 my ($vmid, $devicefull) = @_;
3413 $devicefull = "driver=".$devicefull;
3414 my %options = split(/[=,]/, $devicefull);
3416 vm_mon_cmd
($vmid, "device_add" , %options);
3419 sub qemu_devicedel
{
3420 my ($vmid, $deviceid) = @_;
3422 my $ret = vm_mon_cmd
($vmid, "device_del", id
=> $deviceid);
3425 sub qemu_iothread_add
{
3426 my($vmid, $deviceid, $device) = @_;
3428 if ($device->{iothread
}) {
3429 my $iothreads = vm_iothreads_list
($vmid);
3430 qemu_objectadd
($vmid, "iothread-$deviceid", "iothread") if !$iothreads->{"iothread-$deviceid"};
3434 sub qemu_iothread_del
{
3435 my($conf, $vmid, $deviceid) = @_;
3437 my $device = parse_drive
($deviceid, $conf->{$deviceid});
3438 if ($device->{iothread
}) {
3439 my $iothreads = vm_iothreads_list
($vmid);
3440 qemu_objectdel
($vmid, "iothread-$deviceid") if $iothreads->{"iothread-$deviceid"};
3444 sub qemu_objectadd
{
3445 my($vmid, $objectid, $qomtype) = @_;
3447 vm_mon_cmd
($vmid, "object-add", id
=> $objectid, "qom-type" => $qomtype);
3452 sub qemu_objectdel
{
3453 my($vmid, $objectid) = @_;
3455 vm_mon_cmd
($vmid, "object-del", id
=> $objectid);
3461 my ($storecfg, $vmid, $device) = @_;
3463 my $drive = print_drive_full
($storecfg, $vmid, $device);
3464 $drive =~ s/\\/\\\\/g;
3465 my $ret = vm_human_monitor_command
($vmid, "drive_add auto \"$drive\"");
3467 # If the command succeeds qemu prints: "OK
"
3468 return 1 if $ret =~ m/OK/s;
3470 die "adding drive failed
: $ret\n";
3474 my($vmid, $deviceid) = @_;
3476 my $ret = vm_human_monitor_command($vmid, "drive_del drive-
$deviceid");
3479 return 1 if $ret eq "";
3481 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
3482 return 1 if $ret =~ m/Device \'.*?\' not found/s;
3484 die "deleting drive
$deviceid failed
: $ret\n";
3487 sub qemu_deviceaddverify {
3488 my ($vmid, $deviceid) = @_;
3490 for (my $i = 0; $i <= 5; $i++) {
3491 my $devices_list = vm_devices_list($vmid);
3492 return 1 if defined($devices_list->{$deviceid});
3496 die "error on hotplug device
'$deviceid'\n";
3500 sub qemu_devicedelverify {
3501 my ($vmid, $deviceid) = @_;
3503 # need to verify that the device is correctly removed as device_del
3504 # is async and empty return is not reliable
3506 for (my $i = 0; $i <= 5; $i++) {
3507 my $devices_list = vm_devices_list($vmid);
3508 return 1 if !defined($devices_list->{$deviceid});
3512 die "error on hot-unplugging device
'$deviceid'\n";
3515 sub qemu_findorcreatescsihw {
3516 my ($storecfg, $conf, $vmid, $device) = @_;
3518 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device);
3520 my $scsihwid="$controller_prefix$controller";
3521 my $devices_list = vm_devices_list($vmid);
3523 if(!defined($devices_list->{$scsihwid})) {
3524 vm_deviceplug($storecfg, $conf, $vmid, $scsihwid, $device);
3530 sub qemu_deletescsihw {
3531 my ($conf, $vmid, $opt) = @_;
3533 my $device = parse_drive($opt, $conf->{$opt});
3535 if ($conf->{scsihw} && ($conf->{scsihw} eq 'virtio-scsi-single')) {
3536 vm_deviceunplug($vmid, $conf, "virtioscsi
$device->{index}");
3540 my ($maxdev, $controller, $controller_prefix) = scsihw_infos($conf, $device);
3542 my $devices_list = vm_devices_list($vmid);
3543 foreach my $opt (keys %{$devices_list}) {
3544 if (PVE::QemuServer::valid_drivename($opt)) {
3545 my $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt});
3546 if($drive->{interface} eq 'scsi' && $drive->{index} < (($maxdev-1)*($controller+1))) {
3552 my $scsihwid="scsihw
$controller";
3554 vm_deviceunplug($vmid, $conf, $scsihwid);
3559 sub qemu_add_pci_bridge {
3560 my ($storecfg, $conf, $vmid, $device) = @_;
3566 print_pci_addr($device, $bridges);
3568 while (my ($k, $v) = each %$bridges) {
3571 return 1 if !defined($bridgeid) || $bridgeid < 1;
3573 my $bridge = "pci
.$bridgeid";
3574 my $devices_list = vm_devices_list($vmid);
3576 if (!defined($devices_list->{$bridge})) {
3577 vm_deviceplug($storecfg, $conf, $vmid, $bridge);
3583 sub qemu_set_link_status {
3584 my ($vmid, $device, $up) = @_;
3586 vm_mon_cmd($vmid, "set_link
", name => $device,
3587 up => $up ? JSON::true : JSON::false);
3590 sub qemu_netdevadd {
3591 my ($vmid, $conf, $device, $deviceid) = @_;
3593 my $netdev = print_netdev_full($vmid, $conf, $device, $deviceid);
3594 my %options = split(/[=,]/, $netdev);
3596 vm_mon_cmd($vmid, "netdev_add
", %options);
3600 sub qemu_netdevdel {
3601 my ($vmid, $deviceid) = @_;
3603 vm_mon_cmd($vmid, "netdev_del
", id => $deviceid);
3606 sub qemu_cpu_hotplug {
3607 my ($vmid, $conf, $vcpus) = @_;
3610 $sockets = $conf->{smp} if $conf->{smp}; # old style - no longer iused
3611 $sockets = $conf->{sockets} if $conf->{sockets};
3612 my $cores = $conf->{cores} || 1;
3613 my $maxcpus = $sockets * $cores;
3615 $vcpus = $maxcpus if !$vcpus;
3617 die "you can
't add more vcpus than maxcpus\n"
3618 if $vcpus > $maxcpus;
3620 my $currentvcpus = $conf->{vcpus} || $maxcpus;
3621 die "online cpu unplug is not yet possible\n"
3622 if $vcpus < $currentvcpus;
3624 my $currentrunningvcpus = vm_mon_cmd($vmid, "query-cpus");
3625 die "vcpus in running vm is different than configuration\n"
3626 if scalar(@{$currentrunningvcpus}) != $currentvcpus;
3628 for (my $i = $currentvcpus; $i < $vcpus; $i++) {
3629 vm_mon_cmd($vmid, "cpu-add", id => int($i));
3633 sub qemu_memory_hotplug {
3634 my ($vmid, $conf, $defaults, $opt, $value) = @_;
3636 return $value if !check_running($vmid);
3638 my $memory = $conf->{memory} || $defaults->{memory};
3639 $value = $defaults->{memory} if !$value;
3640 return $value if $value == $memory;
3642 my $static_memory = $STATICMEM;
3643 my $dimm_memory = $memory - $static_memory;
3645 die "memory can't be lower than
$static_memory MB
" if $value < $static_memory;
3646 die "memory unplug
is not yet available
" if $value < $memory;
3647 die "you cannot add more memory than
$MAX_MEM MB
!\n" if $memory > $MAX_MEM;
3651 $sockets = $conf->{sockets} if $conf->{sockets};
3653 foreach_dimm($conf, $vmid, $value, $sockets, sub {
3654 my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
3656 return if $current_size <= $conf->{memory};
3658 eval { vm_mon_cmd($vmid, "object-add
", 'qom-type' => "memory-backend-ram
", id => "mem-
$name", props => { size => int($dimm_size*1024*1024) } ) };
3660 eval { qemu_objectdel($vmid, "mem-
$name"); };
3664 eval { vm_mon_cmd($vmid, "device_add
", driver => "pc-dimm
", id => "$name", memdev => "mem-
$name", node => $numanode) };
3666 eval { qemu_objectdel($vmid, "mem-
$name"); };
3669 #update conf after each succesful module hotplug
3670 $conf->{memory} = $current_size;
3671 update_config_nolock($vmid, $conf, 1);
3675 sub qemu_block_set_io_throttle {
3676 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
3678 return if !check_running($vmid) ;
3680 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));
3684 # old code, only used to shutdown old VM after update
3686 my ($fh, $timeout) = @_;
3688 my $sel = new IO::Select;
3695 while (scalar (@ready = $sel->can_read($timeout))) {
3697 if ($count = $fh->sysread($buf, 8192)) {
3698 if ($buf =~ /^(.*)\(qemu\) $/s) {
3705 if (!defined($count)) {
3712 die "monitor
read timeout
\n" if !scalar(@ready);
3717 # old code, only used to shutdown old VM after update
3718 sub vm_monitor_command {
3719 my ($vmid, $cmdstr, $nocheck) = @_;
3724 die "VM
$vmid not running
\n" if !check_running($vmid, $nocheck);
3726 my $sname = "${var_run_tmpdir
}/$vmid.mon
";
3728 my $sock = IO::Socket::UNIX->new( Peer => $sname ) ||
3729 die "unable to
connect to VM
$vmid socket - $!\n";
3733 # hack: migrate sometime blocks the monitor (when migrate_downtime
3735 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3736 $timeout = 60*60; # 1 hour
3740 my $data = __read_avail($sock, $timeout);
3742 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
3743 die "got unexpected qemu monitor banner
\n";
3746 my $sel = new IO::Select;
3749 if (!scalar(my @ready = $sel->can_write($timeout))) {
3750 die "monitor
write error
- timeout
";
3753 my $fullcmd = "$cmdstr\r";
3755 # syslog('info', "VM
$vmid monitor command
: $cmdstr");
3758 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
3759 die "monitor
write error
- $!";
3762 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
3766 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
3767 $timeout = 60*60; # 1 hour
3768 } elsif ($cmdstr =~ m/^(eject|change)/) {
3769 $timeout = 60; # note: cdrom mount command is slow
3771 if ($res = __read_avail($sock, $timeout)) {
3773 my @lines = split("\r?
\n", $res);
3775 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
3777 $res = join("\n", @lines);
3785 syslog("err
", "VM
$vmid monitor command failed
- $err");
3792 sub qemu_block_resize {
3793 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
3795 my $running = check_running($vmid);
3797 return if !PVE::Storage::volume_resize($storecfg, $volid, $size, $running);
3799 return if !$running;
3801 vm_mon_cmd($vmid, "block_resize
", device => $deviceid, size => int($size));
3805 sub qemu_volume_snapshot {
3806 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3808 my $running = check_running($vmid);
3810 return if !PVE::Storage::volume_snapshot($storecfg, $volid, $snap, $running);
3812 return if !$running;
3814 vm_mon_cmd($vmid, "snapshot-drive
", device => $deviceid, name => $snap);
3818 sub qemu_volume_snapshot_delete {
3819 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
3821 my $running = check_running($vmid);
3823 return if !PVE::Storage::volume_snapshot_delete($storecfg, $volid, $snap, $running);
3825 return if !$running;
3827 vm_mon_cmd($vmid, "delete-drive-snapshot
", device => $deviceid, name => $snap);
3830 sub set_migration_caps {
3836 "auto-converge
" => 1,
3838 "x-rdma-pin-all
" => 0,
3842 my $supported_capabilities = vm_mon_cmd_nocheck($vmid, "query-migrate-capabilities
");
3844 for my $supported_capability (@$supported_capabilities) {
3846 capability => $supported_capability->{capability},
3847 state => $enabled_cap->{$supported_capability->{capability}} ? JSON::true : JSON::false,
3851 vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities
", capabilities => $cap_ref);
3854 my $fast_plug_option = {
3862 # hotplug changes in [PENDING]
3863 # $selection hash can be used to only apply specified options, for
3864 # example: { cores => 1 } (only apply changed 'cores')
3865 # $errors ref is used to return error messages
3866 sub vmconfig_hotplug_pending {
3867 my ($vmid, $conf, $storecfg, $selection, $errors) = @_;
3869 my $defaults = load_defaults();
3871 # commit values which do not have any impact on running VM first
3872 # Note: those option cannot raise errors, we we do not care about
3873 # $selection and always apply them.
3875 my $add_error = sub {
3876 my ($opt, $msg) = @_;
3877 $errors->{$opt} = "hotplug problem
- $msg";
3881 foreach my $opt (keys %{$conf->{pending}}) { # add/change
3882 if ($fast_plug_option->{$opt}) {
3883 $conf->{$opt} = $conf->{pending}->{$opt};
3884 delete $conf->{pending}->{$opt};
3890 update_config_nolock($vmid, $conf, 1);
3891 $conf = load_config($vmid); # update/reload
3894 my $hotplug_features = parse_hotplug_features(defined($conf->{hotplug}) ? $conf->{hotplug} : '1');
3896 my @delete = PVE::Tools::split_list($conf->{pending}->{delete});
3897 foreach my $opt (@delete) {
3898 next if $selection && !$selection->{$opt};
3900 if ($opt eq 'hotplug') {
3901 die "skip
\n" if ($conf->{hotplug} =~ /memory/);
3902 } elsif ($opt eq 'tablet') {
3903 die "skip
\n" if !$hotplug_features->{usb};
3904 if ($defaults->{tablet}) {
3905 vm_deviceplug($storecfg, $conf, $vmid, $opt);
3907 vm_deviceunplug($vmid, $conf, $opt);
3909 } elsif ($opt eq 'vcpus') {
3910 die "skip
\n" if !$hotplug_features->{cpu};
3911 qemu_cpu_hotplug($vmid, $conf, undef);
3912 } elsif ($opt eq 'balloon') {
3913 # enable balloon device is not hotpluggable
3914 die "skip
\n" if !defined($conf->{balloon}) || $conf->{balloon};
3915 } elsif ($fast_plug_option->{$opt}) {
3917 } elsif ($opt =~ m/^net(\d+)$/) {
3918 die "skip
\n" if !$hotplug_features->{network};
3919 vm_deviceunplug($vmid, $conf, $opt);
3920 } elsif (valid_drivename($opt)) {
3921 die "skip
\n" if !$hotplug_features->{disk} || $opt =~ m/(ide|sata)(\d+)/;
3922 vm_deviceunplug($vmid, $conf, $opt);
3923 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}));
3924 } elsif ($opt =~ m/^memory$/) {
3925 die "skip
\n" if !$hotplug_features->{memory};
3926 qemu_memory_hotplug($vmid, $conf, $defaults, $opt);
3932 &$add_error($opt, $err) if $err ne "skip
\n";
3934 # save new config if hotplug was successful
3935 delete $conf->{$opt};
3936 vmconfig_undelete_pending_option($conf, $opt);
3937 update_config_nolock($vmid, $conf, 1);
3938 $conf = load_config($vmid); # update/reload
3942 foreach my $opt (keys %{$conf->{pending}}) {
3943 next if $selection && !$selection->{$opt};
3944 my $value = $conf->{pending}->{$opt};
3946 if ($opt eq 'hotplug') {
3947 die "skip
\n" if ($value =~ /memory/) || ($value !~ /memory/ && $conf->{hotplug} =~ /memory/);
3948 } elsif ($opt eq 'tablet') {
3949 die "skip
\n" if !$hotplug_features->{usb};
3951 vm_deviceplug($storecfg, $conf, $vmid, $opt);
3952 } elsif ($value == 0) {
3953 vm_deviceunplug($vmid, $conf, $opt);
3955 } elsif ($opt eq 'vcpus') {
3956 die "skip
\n" if !$hotplug_features->{cpu};
3957 qemu_cpu_hotplug($vmid, $conf, $value);
3958 } elsif ($opt eq 'balloon') {
3959 # enable/disable balloning device is not hotpluggable
3960 my $old_balloon_enabled = !!(!defined($conf->{balloon}) || $conf->{balloon});
3961 my $new_balloon_enabled = !!(!defined($conf->{pending}->{balloon}) || $conf->{pending}->{balloon});
3962 die "skip
\n" if $old_balloon_enabled != $new_balloon_enabled;
3964 # allow manual ballooning if shares is set to zero
3965 if ((defined($conf->{shares}) && ($conf->{shares} == 0))) {
3966 my $balloon = $conf->{pending}->{balloon} || $conf->{memory} || $defaults->{memory};
3967 vm_mon_cmd($vmid, "balloon
", value => $balloon*1024*1024);
3969 } elsif ($opt =~ m/^net(\d+)$/) {
3970 # some changes can be done without hotplug
3971 vmconfig_update_net($storecfg, $conf, $hotplug_features->{network},
3972 $vmid, $opt, $value);
3973 } elsif (valid_drivename($opt)) {
3974 # some changes can be done without hotplug
3975 vmconfig_update_disk($storecfg, $conf, $hotplug_features->{disk},
3976 $vmid, $opt, $value, 1);
3977 } elsif ($opt =~ m/^memory$/) { #dimms
3978 die "skip
\n" if !$hotplug_features->{memory};
3979 $value = qemu_memory_hotplug($vmid, $conf, $defaults, $opt, $value);
3981 die "skip
\n"; # skip non-hot-pluggable options
3985 &$add_error($opt, $err) if $err ne "skip
\n";
3987 # save new config if hotplug was successful
3988 $conf->{$opt} = $value;
3989 delete $conf->{pending}->{$opt};
3990 update_config_nolock($vmid, $conf, 1);
3991 $conf = load_config($vmid); # update/reload
3996 sub vmconfig_apply_pending {
3997 my ($vmid, $conf, $storecfg) = @_;
4001 my @delete = PVE::Tools::split_list($conf->{pending}->{delete});
4002 foreach my $opt (@delete) { # delete
4003 die "internal error
" if $opt =~ m/^unused/;
4004 $conf = load_config($vmid); # update/reload
4005 if (!defined($conf->{$opt})) {
4006 vmconfig_undelete_pending_option($conf, $opt);
4007 update_config_nolock($vmid, $conf, 1);
4008 } elsif (valid_drivename($opt)) {
4009 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}));
4010 vmconfig_undelete_pending_option($conf, $opt);
4011 delete $conf->{$opt};
4012 update_config_nolock($vmid, $conf, 1);
4014 vmconfig_undelete_pending_option($conf, $opt);
4015 delete $conf->{$opt};
4016 update_config_nolock($vmid, $conf, 1);
4020 $conf = load_config($vmid); # update/reload
4022 foreach my $opt (keys %{$conf->{pending}}) { # add/change
4023 $conf = load_config($vmid); # update/reload
4025 if (defined($conf->{$opt}) && ($conf->{$opt} eq $conf->{pending}->{$opt})) {
4026 # skip if nothing changed
4027 } elsif (valid_drivename($opt)) {
4028 vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}))
4029 if defined($conf->{$opt});
4030 $conf->{$opt} = $conf->{pending}->{$opt};
4032 $conf->{$opt} = $conf->{pending}->{$opt};
4035 delete $conf->{pending}->{$opt};
4036 update_config_nolock($vmid, $conf, 1);
4040 my $safe_num_ne = sub {
4043 return 0 if !defined($a) && !defined($b);
4044 return 1 if !defined($a);
4045 return 1 if !defined($b);
4050 my $safe_string_ne = sub {
4053 return 0 if !defined($a) && !defined($b);
4054 return 1 if !defined($a);
4055 return 1 if !defined($b);
4060 sub vmconfig_update_net {
4061 my ($storecfg, $conf, $hotplug, $vmid, $opt, $value) = @_;
4063 my $newnet = parse_net($value);
4065 if ($conf->{$opt}) {
4066 my $oldnet = parse_net($conf->{$opt});
4068 if (&$safe_string_ne($oldnet->{model}, $newnet->{model}) ||
4069 &$safe_string_ne($oldnet->{macaddr}, $newnet->{macaddr}) ||
4070 &$safe_num_ne($oldnet->{queues}, $newnet->{queues}) ||
4071 !($newnet->{bridge} && $oldnet->{bridge})) { # bridge/nat mode change
4073 # for non online change, we try to hot-unplug
4074 die "skip
\n" if !$hotplug;
4075 vm_deviceunplug($vmid, $conf, $opt);
4078 die "internal error
" if $opt !~ m/net(\d+)/;
4079 my $iface = "tap
${vmid
}i
$1";
4081 if (&$safe_num_ne($oldnet->{rate}, $newnet->{rate})) {
4082 PVE::Network::tap_rate_limit($iface, $newnet->{rate});
4085 if (&$safe_string_ne($oldnet->{bridge}, $newnet->{bridge}) ||
4086 &$safe_num_ne($oldnet->{tag}, $newnet->{tag}) ||
4087 &$safe_num_ne($oldnet->{firewall}, $newnet->{firewall})) {
4088 PVE::Network::tap_unplug($iface);
4089 PVE::Network::tap_plug($iface, $newnet->{bridge}, $newnet->{tag}, $newnet->{firewall});
4092 if (&$safe_string_ne($oldnet->{link_down}, $newnet->{link_down})) {
4093 qemu_set_link_status($vmid, $opt, !$newnet->{link_down});
4101 vm_deviceplug($storecfg, $conf, $vmid, $opt, $newnet);
4107 sub vmconfig_update_disk {
4108 my ($storecfg, $conf, $hotplug, $vmid, $opt, $value, $force) = @_;
4110 # fixme: do we need force?
4112 my $drive = parse_drive($opt, $value);
4114 if ($conf->{$opt}) {
4116 if (my $old_drive = parse_drive($opt, $conf->{$opt})) {
4118 my $media = $drive->{media} || 'disk';
4119 my $oldmedia = $old_drive->{media} || 'disk';
4120 die "unable to change media type
\n" if $media ne $oldmedia;
4122 if (!drive_is_cdrom($old_drive)) {
4124 if ($drive->{file} ne $old_drive->{file}) {
4126 die "skip
\n" if !$hotplug;
4128 # unplug and register as unused
4129 vm_deviceunplug($vmid, $conf, $opt);
4130 vmconfig_register_unused_drive($storecfg, $vmid, $conf, $old_drive)
4133 # update existing disk
4135 # skip non hotpluggable value
4136 if (&$safe_num_ne($drive->{discard}, $old_drive->{discard}) ||
4137 &$safe_string_ne($drive->{iothread}, $old_drive->{iothread}) ||
4138 &$safe_string_ne($drive->{cache}, $old_drive->{cache})) {
4143 if (&$safe_num_ne($drive->{mbps}, $old_drive->{mbps}) ||
4144 &$safe_num_ne($drive->{mbps_rd}, $old_drive->{mbps_rd}) ||
4145 &$safe_num_ne($drive->{mbps_wr}, $old_drive->{mbps_wr}) ||
4146 &$safe_num_ne($drive->{iops}, $old_drive->{iops}) ||
4147 &$safe_num_ne($drive->{iops_rd}, $old_drive->{iops_rd}) ||
4148 &$safe_num_ne($drive->{iops_wr}, $old_drive->{iops_wr}) ||
4149 &$safe_num_ne($drive->{mbps_max}, $old_drive->{mbps_max}) ||
4150 &$safe_num_ne($drive->{mbps_rd_max}, $old_drive->{mbps_rd_max}) ||
4151 &$safe_num_ne($drive->{mbps_wr_max}, $old_drive->{mbps_wr_max}) ||
4152 &$safe_num_ne($drive->{iops_max}, $old_drive->{iops_max}) ||
4153 &$safe_num_ne($drive->{iops_rd_max}, $old_drive->{iops_rd_max}) ||
4154 &$safe_num_ne($drive->{iops_wr_max}, $old_drive->{iops_wr_max})) {
4156 qemu_block_set_io_throttle($vmid,"drive-
$opt",
4157 ($drive->{mbps} || 0)*1024*1024,
4158 ($drive->{mbps_rd} || 0)*1024*1024,
4159 ($drive->{mbps_wr} || 0)*1024*1024,
4160 $drive->{iops} || 0,
4161 $drive->{iops_rd} || 0,
4162 $drive->{iops_wr} || 0,
4163 ($drive->{mbps_max} || 0)*1024*1024,
4164 ($drive->{mbps_rd_max} || 0)*1024*1024,
4165 ($drive->{mbps_wr_max} || 0)*1024*1024,
4166 $drive->{iops_max} || 0,
4167 $drive->{iops_rd_max} || 0,
4168 $drive->{iops_wr_max} || 0);
4177 if ($drive->{file} eq 'none') {
4178 vm_mon_cmd($vmid, "eject
",force => JSON::true,device => "drive-
$opt");
4180 my $path = get_iso_path($storecfg, $vmid, $drive->{file});
4181 vm_mon_cmd($vmid, "eject
", force => JSON::true,device => "drive-
$opt"); # force eject if locked
4182 vm_mon_cmd($vmid, "change
", device => "drive-
$opt",target => "$path") if $path;
4190 die "skip
\n" if !$hotplug || $opt =~ m/(ide|sata)(\d+)/;
4192 vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive);
4196 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;
4198 lock_config($vmid, sub {
4199 my $conf = load_config($vmid, $migratedfrom);
4201 die "you can
't start a vm if it's a template
\n" if is_template($conf);
4203 check_lock($conf) if !$skiplock;
4205 die "VM
$vmid already running
\n" if check_running($vmid, undef, $migratedfrom);
4207 if (!$statefile && scalar(keys %{$conf->{pending}})) {
4208 vmconfig_apply_pending($vmid, $conf, $storecfg);
4209 $conf = load_config($vmid); # update/reload
4212 my $defaults = load_defaults();
4214 # set environment variable useful inside network script
4215 $ENV{PVE_MIGRATED_FROM} = $migratedfrom if $migratedfrom;
4217 my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine);
4219 my $migrate_port = 0;
4222 if ($statefile eq 'tcp') {
4223 my $localip = "localhost
";
4224 my $datacenterconf = PVE::Cluster::cfs_read_file('datacenter.cfg');
4225 if ($datacenterconf->{migration_unsecure}) {
4226 my $nodename = PVE::INotify::nodename();
4227 $localip = PVE::Cluster::remote_node_ip($nodename, 1);
4229 $migrate_port = PVE::Tools::next_migrate_port();
4230 $migrate_uri = "tcp
:${localip
}:${migrate_port
}";
4231 push @$cmd, '-incoming', $migrate_uri;
4234 push @$cmd, '-loadstate', $statefile;
4241 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
4242 my $d = parse_hostpci($conf->{"hostpci
$i"});
4244 my $pcidevices = $d->{pciid};
4245 foreach my $pcidevice (@$pcidevices) {
4246 my $pciid = $pcidevice->{id}.".".$pcidevice->{function};
4248 my $info = pci_device_info("0000:$pciid");
4249 die "IOMMU
not present
\n" if !check_iommu_support();
4250 die "no pci device info
for device
'$pciid'\n" if !$info;
4252 if ($d->{driver} && $d->{driver} eq "vfio
") {
4253 die "can
't unbind/bind pci group to vfio '$pciid'\n" if !pci_dev_group_bind_to_vfio($pciid);
4255 die "can't unbind
/bind to stub pci device
'$pciid'\n" if !pci_dev_bind_to_stub($info);
4258 die "can
't reset pci device '$pciid'\n" if $info->{has_fl_reset} and !pci_dev_reset($info);
4262 PVE::Storage::activate_volumes($storecfg, $vollist);
4264 eval { run_command($cmd, timeout => $statefile ? undef : 30,
4267 die "start failed: $err" if $err;
4269 print "migration listens on $migrate_uri\n" if $migrate_uri;
4271 if ($statefile && $statefile ne 'tcp
') {
4272 eval { vm_mon_cmd_nocheck($vmid, "cont"); };
4276 if ($migratedfrom) {
4279 set_migration_caps($vmid);
4284 print "spice listens on port $spice_port\n";
4285 if ($spice_ticket) {
4286 vm_mon_cmd_nocheck($vmid, "set_password", protocol => 'spice
', password => $spice_ticket);
4287 vm_mon_cmd_nocheck($vmid, "expire_password", protocol => 'spice
', time => "+30");
4293 if (!$statefile && (!defined($conf->{balloon}) || $conf->{balloon})) {
4294 vm_mon_cmd_nocheck($vmid, "balloon", value => $conf->{balloon}*1024*1024)
4295 if $conf->{balloon};
4298 foreach my $opt (keys %$conf) {
4299 next if $opt !~ m/^net\d+$/;
4300 my $nicconf = parse_net($conf->{$opt});
4301 qemu_set_link_status($vmid, $opt, 0) if $nicconf->{link_down};
4305 vm_mon_cmd_nocheck($vmid, 'qom-set
',
4306 path => "machine/peripheral/balloon0",
4307 property => "guest-stats-polling-interval",
4308 value => 2) if (!defined($conf->{balloon}) || $conf->{balloon});
4314 my ($vmid, $execute, %params) = @_;
4316 my $cmd = { execute => $execute, arguments => \%params };
4317 vm_qmp_command($vmid, $cmd);
4320 sub vm_mon_cmd_nocheck {
4321 my ($vmid, $execute, %params) = @_;
4323 my $cmd = { execute => $execute, arguments => \%params };
4324 vm_qmp_command($vmid, $cmd, 1);
4327 sub vm_qmp_command {
4328 my ($vmid, $cmd, $nocheck) = @_;
4333 if ($cmd->{arguments} && $cmd->{arguments}->{timeout}) {
4334 $timeout = $cmd->{arguments}->{timeout};
4335 delete $cmd->{arguments}->{timeout};
4339 die "VM $vmid not running\n" if !check_running($vmid, $nocheck);
4340 my $sname = qmp_socket($vmid);
4341 if (-e $sname) { # test if VM is reasonambe new and supports qmp/qga
4342 my $qmpclient = PVE::QMPClient->new();
4344 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
4345 } elsif (-e "${var_run_tmpdir}/$vmid.mon") {
4346 die "can't execute complex command on old monitor
- stop
/start your vm to fix the problem
\n"
4347 if scalar(%{$cmd->{arguments}});
4348 vm_monitor_command($vmid, $cmd->{execute}, $nocheck);
4350 die "unable to
open monitor
socket\n";
4354 syslog("err
", "VM
$vmid qmp command failed
- $err");
4361 sub vm_human_monitor_command {
4362 my ($vmid, $cmdline) = @_;
4367 execute => 'human-monitor-command',
4368 arguments => { 'command-line' => $cmdline},
4371 return vm_qmp_command($vmid, $cmd);
4374 sub vm_commandline {
4375 my ($storecfg, $vmid) = @_;
4377 my $conf = load_config($vmid);
4379 my $defaults = load_defaults();
4381 my $cmd = config_to_command($storecfg, $vmid, $conf, $defaults);
4383 return join(' ', @$cmd);
4387 my ($vmid, $skiplock) = @_;
4389 lock_config($vmid, sub {
4391 my $conf = load_config($vmid);
4393 check_lock($conf) if !$skiplock;
4395 vm_mon_cmd($vmid, "system_reset
");
4399 sub get_vm_volumes {
4403 foreach_volid($conf, sub {
4404 my ($volid, $is_cdrom) = @_;
4406 return if $volid =~ m|^/|;
4408 my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
4411 push @$vollist, $volid;
4417 sub vm_stop_cleanup {
4418 my ($storecfg, $vmid, $conf, $keepActive, $apply_pending_changes) = @_;
4421 fairsched_rmnod($vmid); # try to destroy group
4424 my $vollist = get_vm_volumes($conf);
4425 PVE::Storage::deactivate_volumes($storecfg, $vollist);
4428 foreach my $ext (qw(mon qmp pid vnc qga)) {
4429 unlink "/var/run/qemu-server/${vmid}.$ext";
4432 vmconfig_apply_pending
($vmid, $conf, $storecfg) if $apply_pending_changes;
4434 warn $@ if $@; # avoid errors - just warn
4437 # Note: use $nockeck to skip tests if VM configuration file exists.
4438 # We need that when migration VMs to other nodes (files already moved)
4439 # Note: we set $keepActive in vzdump stop mode - volumes need to stay active
4441 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
4443 $force = 1 if !defined($force) && !$shutdown;
4446 my $pid = check_running
($vmid, $nocheck, $migratedfrom);
4447 kill 15, $pid if $pid;
4448 my $conf = load_config
($vmid, $migratedfrom);
4449 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive, 0);
4453 lock_config
($vmid, sub {
4455 my $pid = check_running
($vmid, $nocheck);
4460 $conf = load_config
($vmid);
4461 check_lock
($conf) if !$skiplock;
4462 if (!defined($timeout) && $shutdown && $conf->{startup
}) {
4463 my $opts = parse_startup
($conf->{startup
});
4464 $timeout = $opts->{down
} if $opts->{down
};
4468 $timeout = 60 if !defined($timeout);
4472 if (defined($conf) && $conf->{agent
}) {
4473 vm_qmp_command
($vmid, { execute
=> "guest-shutdown" }, $nocheck);
4475 vm_qmp_command
($vmid, { execute
=> "system_powerdown" }, $nocheck);
4478 vm_qmp_command
($vmid, { execute
=> "quit" }, $nocheck);
4485 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
4490 if ($count >= $timeout) {
4492 warn "VM still running - terminating now with SIGTERM\n";
4495 die "VM quit/powerdown failed - got timeout\n";
4498 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive, 1) if $conf;
4503 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
4506 die "VM quit/powerdown failed\n";
4514 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
4519 if ($count >= $timeout) {
4520 warn "VM still running - terminating now with SIGKILL\n";
4525 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive, 1) if $conf;
4530 my ($vmid, $skiplock) = @_;
4532 lock_config
($vmid, sub {
4534 my $conf = load_config
($vmid);
4536 check_lock
($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
4538 vm_mon_cmd
($vmid, "stop");
4543 my ($vmid, $skiplock) = @_;
4545 lock_config
($vmid, sub {
4547 my $conf = load_config
($vmid);
4549 check_lock
($conf) if !($skiplock || ($conf->{lock} && $conf->{lock} eq 'backup'));
4551 vm_mon_cmd
($vmid, "cont");
4556 my ($vmid, $skiplock, $key) = @_;
4558 lock_config
($vmid, sub {
4560 my $conf = load_config
($vmid);
4562 # there is no qmp command, so we use the human monitor command
4563 vm_human_monitor_command
($vmid, "sendkey $key");
4568 my ($storecfg, $vmid, $skiplock) = @_;
4570 lock_config
($vmid, sub {
4572 my $conf = load_config
($vmid);
4574 check_lock
($conf) if !$skiplock;
4576 if (!check_running
($vmid)) {
4577 fairsched_rmnod
($vmid); # try to destroy group
4578 destroy_vm
($storecfg, $vmid);
4580 die "VM $vmid is running - destroy failed\n";
4588 my ($filename, $buf) = @_;
4590 my $fh = IO
::File-
>new($filename, "w");
4591 return undef if !$fh;
4593 my $res = print $fh $buf;
4600 sub pci_device_info
{
4605 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
4606 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
4608 my $irq = file_read_firstline
("$pcisysfs/devices/$name/irq");
4609 return undef if !defined($irq) || $irq !~ m/^\d+$/;
4611 my $vendor = file_read_firstline
("$pcisysfs/devices/$name/vendor");
4612 return undef if !defined($vendor) || $vendor !~ s/^0x//;
4614 my $product = file_read_firstline
("$pcisysfs/devices/$name/device");
4615 return undef if !defined($product) || $product !~ s/^0x//;
4620 product
=> $product,
4626 has_fl_reset
=> -f
"$pcisysfs/devices/$name/reset" || 0,
4635 my $name = $dev->{name
};
4637 my $fn = "$pcisysfs/devices/$name/reset";
4639 return file_write
($fn, "1");
4642 sub pci_dev_bind_to_stub
{
4645 my $name = $dev->{name
};
4647 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
4648 return 1 if -d
$testdir;
4650 my $data = "$dev->{vendor} $dev->{product}";
4651 return undef if !file_write
("$pcisysfs/drivers/pci-stub/new_id", $data);
4653 my $fn = "$pcisysfs/devices/$name/driver/unbind";
4654 if (!file_write
($fn, $name)) {
4655 return undef if -f
$fn;
4658 $fn = "$pcisysfs/drivers/pci-stub/bind";
4659 if (! -d
$testdir) {
4660 return undef if !file_write
($fn, $name);
4666 sub pci_dev_bind_to_vfio
{
4669 my $name = $dev->{name
};
4671 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
4673 if (!-d
$vfio_basedir) {
4674 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
4676 die "Cannot find vfio-pci module!\n" if !-d
$vfio_basedir;
4678 my $testdir = "$vfio_basedir/$name";
4679 return 1 if -d
$testdir;
4681 my $data = "$dev->{vendor} $dev->{product}";
4682 return undef if !file_write
("$vfio_basedir/new_id", $data);
4684 my $fn = "$pcisysfs/devices/$name/driver/unbind";
4685 if (!file_write
($fn, $name)) {
4686 return undef if -f
$fn;
4689 $fn = "$vfio_basedir/bind";
4690 if (! -d
$testdir) {
4691 return undef if !file_write
($fn, $name);
4697 sub pci_dev_group_bind_to_vfio
{
4700 my $vfio_basedir = "$pcisysfs/drivers/vfio-pci";
4702 if (!-d
$vfio_basedir) {
4703 system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null");
4705 die "Cannot find vfio-pci module!\n" if !-d
$vfio_basedir;
4707 # get IOMMU group devices
4708 opendir(my $D, "$pcisysfs/devices/0000:$pciid/iommu_group/devices/") || die "Cannot open iommu_group: $!\n";
4709 my @devs = grep /^0000:/, readdir($D);
4712 foreach my $pciid (@devs) {
4713 $pciid =~ m/^([:\.\da-f]+)$/ or die "PCI ID $pciid not valid!\n";
4715 # pci bridges, switches or root ports are not supported
4716 # they have a pci_bus subdirectory so skip them
4717 next if (-e
"$pcisysfs/devices/$pciid/pci_bus");
4719 my $info = pci_device_info
($1);
4720 pci_dev_bind_to_vfio
($info) || die "Cannot bind $pciid to vfio\n";
4726 sub print_pci_addr
{
4727 my ($id, $bridges) = @_;
4731 piix3
=> { bus
=> 0, addr
=> 1 },
4732 #addr2 : first videocard
4733 balloon0
=> { bus
=> 0, addr
=> 3 },
4734 watchdog
=> { bus
=> 0, addr
=> 4 },
4735 scsihw0
=> { bus
=> 0, addr
=> 5 },
4736 'pci.3' => { bus
=> 0, addr
=> 5 }, #can also be used for virtio-scsi-single bridge
4737 scsihw1
=> { bus
=> 0, addr
=> 6 },
4738 ahci0
=> { bus
=> 0, addr
=> 7 },
4739 qga0
=> { bus
=> 0, addr
=> 8 },
4740 spice
=> { bus
=> 0, addr
=> 9 },
4741 virtio0
=> { bus
=> 0, addr
=> 10 },
4742 virtio1
=> { bus
=> 0, addr
=> 11 },
4743 virtio2
=> { bus
=> 0, addr
=> 12 },
4744 virtio3
=> { bus
=> 0, addr
=> 13 },
4745 virtio4
=> { bus
=> 0, addr
=> 14 },
4746 virtio5
=> { bus
=> 0, addr
=> 15 },
4747 hostpci0
=> { bus
=> 0, addr
=> 16 },
4748 hostpci1
=> { bus
=> 0, addr
=> 17 },
4749 net0
=> { bus
=> 0, addr
=> 18 },
4750 net1
=> { bus
=> 0, addr
=> 19 },
4751 net2
=> { bus
=> 0, addr
=> 20 },
4752 net3
=> { bus
=> 0, addr
=> 21 },
4753 net4
=> { bus
=> 0, addr
=> 22 },
4754 net5
=> { bus
=> 0, addr
=> 23 },
4755 vga1
=> { bus
=> 0, addr
=> 24 },
4756 vga2
=> { bus
=> 0, addr
=> 25 },
4757 vga3
=> { bus
=> 0, addr
=> 26 },
4758 hostpci2
=> { bus
=> 0, addr
=> 27 },
4759 hostpci3
=> { bus
=> 0, addr
=> 28 },
4760 #addr29 : usb-host (pve-usb.cfg)
4761 'pci.1' => { bus
=> 0, addr
=> 30 },
4762 'pci.2' => { bus
=> 0, addr
=> 31 },
4763 'net6' => { bus
=> 1, addr
=> 1 },
4764 'net7' => { bus
=> 1, addr
=> 2 },
4765 'net8' => { bus
=> 1, addr
=> 3 },
4766 'net9' => { bus
=> 1, addr
=> 4 },
4767 'net10' => { bus
=> 1, addr
=> 5 },
4768 'net11' => { bus
=> 1, addr
=> 6 },
4769 'net12' => { bus
=> 1, addr
=> 7 },
4770 'net13' => { bus
=> 1, addr
=> 8 },
4771 'net14' => { bus
=> 1, addr
=> 9 },
4772 'net15' => { bus
=> 1, addr
=> 10 },
4773 'net16' => { bus
=> 1, addr
=> 11 },
4774 'net17' => { bus
=> 1, addr
=> 12 },
4775 'net18' => { bus
=> 1, addr
=> 13 },
4776 'net19' => { bus
=> 1, addr
=> 14 },
4777 'net20' => { bus
=> 1, addr
=> 15 },
4778 'net21' => { bus
=> 1, addr
=> 16 },
4779 'net22' => { bus
=> 1, addr
=> 17 },
4780 'net23' => { bus
=> 1, addr
=> 18 },
4781 'net24' => { bus
=> 1, addr
=> 19 },
4782 'net25' => { bus
=> 1, addr
=> 20 },
4783 'net26' => { bus
=> 1, addr
=> 21 },
4784 'net27' => { bus
=> 1, addr
=> 22 },
4785 'net28' => { bus
=> 1, addr
=> 23 },
4786 'net29' => { bus
=> 1, addr
=> 24 },
4787 'net30' => { bus
=> 1, addr
=> 25 },
4788 'net31' => { bus
=> 1, addr
=> 26 },
4789 'virtio6' => { bus
=> 2, addr
=> 1 },
4790 'virtio7' => { bus
=> 2, addr
=> 2 },
4791 'virtio8' => { bus
=> 2, addr
=> 3 },
4792 'virtio9' => { bus
=> 2, addr
=> 4 },
4793 'virtio10' => { bus
=> 2, addr
=> 5 },
4794 'virtio11' => { bus
=> 2, addr
=> 6 },
4795 'virtio12' => { bus
=> 2, addr
=> 7 },
4796 'virtio13' => { bus
=> 2, addr
=> 8 },
4797 'virtio14' => { bus
=> 2, addr
=> 9 },
4798 'virtio15' => { bus
=> 2, addr
=> 10 },
4799 'virtioscsi0' => { bus
=> 3, addr
=> 1 },
4800 'virtioscsi1' => { bus
=> 3, addr
=> 2 },
4801 'virtioscsi2' => { bus
=> 3, addr
=> 3 },
4802 'virtioscsi3' => { bus
=> 3, addr
=> 4 },
4803 'virtioscsi4' => { bus
=> 3, addr
=> 5 },
4804 'virtioscsi5' => { bus
=> 3, addr
=> 6 },
4805 'virtioscsi6' => { bus
=> 3, addr
=> 7 },
4806 'virtioscsi7' => { bus
=> 3, addr
=> 8 },
4807 'virtioscsi8' => { bus
=> 3, addr
=> 9 },
4808 'virtioscsi9' => { bus
=> 3, addr
=> 10 },
4809 'virtioscsi10' => { bus
=> 3, addr
=> 11 },
4810 'virtioscsi11' => { bus
=> 3, addr
=> 12 },
4811 'virtioscsi12' => { bus
=> 3, addr
=> 13 },
4812 'virtioscsi13' => { bus
=> 3, addr
=> 14 },
4813 'virtioscsi14' => { bus
=> 3, addr
=> 15 },
4814 'virtioscsi15' => { bus
=> 3, addr
=> 16 },
4815 'virtioscsi16' => { bus
=> 3, addr
=> 17 },
4816 'virtioscsi17' => { bus
=> 3, addr
=> 18 },
4817 'virtioscsi18' => { bus
=> 3, addr
=> 19 },
4818 'virtioscsi19' => { bus
=> 3, addr
=> 20 },
4819 'virtioscsi20' => { bus
=> 3, addr
=> 21 },
4820 'virtioscsi21' => { bus
=> 3, addr
=> 22 },
4821 'virtioscsi22' => { bus
=> 3, addr
=> 23 },
4822 'virtioscsi23' => { bus
=> 3, addr
=> 24 },
4823 'virtioscsi24' => { bus
=> 3, addr
=> 25 },
4824 'virtioscsi25' => { bus
=> 3, addr
=> 26 },
4825 'virtioscsi26' => { bus
=> 3, addr
=> 27 },
4826 'virtioscsi27' => { bus
=> 3, addr
=> 28 },
4827 'virtioscsi28' => { bus
=> 3, addr
=> 29 },
4828 'virtioscsi29' => { bus
=> 3, addr
=> 30 },
4829 'virtioscsi30' => { bus
=> 3, addr
=> 31 },
4833 if (defined($devices->{$id}->{bus
}) && defined($devices->{$id}->{addr
})) {
4834 my $addr = sprintf("0x%x", $devices->{$id}->{addr
});
4835 my $bus = $devices->{$id}->{bus
};
4836 $res = ",bus=pci.$bus,addr=$addr";
4837 $bridges->{$bus} = 1 if $bridges;
4843 sub print_pcie_addr
{
4848 hostpci0
=> { bus
=> "ich9-pcie-port-1", addr
=> 0 },
4849 hostpci1
=> { bus
=> "ich9-pcie-port-2", addr
=> 0 },
4850 hostpci2
=> { bus
=> "ich9-pcie-port-3", addr
=> 0 },
4851 hostpci3
=> { bus
=> "ich9-pcie-port-4", addr
=> 0 },
4854 if (defined($devices->{$id}->{bus
}) && defined($devices->{$id}->{addr
})) {
4855 my $addr = sprintf("0x%x", $devices->{$id}->{addr
});
4856 my $bus = $devices->{$id}->{bus
};
4857 $res = ",bus=$bus,addr=$addr";
4863 # vzdump restore implementaion
4865 sub tar_archive_read_firstfile
{
4866 my $archive = shift;
4868 die "ERROR: file '$archive' does not exist\n" if ! -f
$archive;
4870 # try to detect archive type first
4871 my $pid = open (TMP
, "tar tf '$archive'|") ||
4872 die "unable to open file '$archive'\n";
4873 my $firstfile = <TMP
>;
4877 die "ERROR: archive contaions no data\n" if !$firstfile;
4883 sub tar_restore_cleanup
{
4884 my ($storecfg, $statfile) = @_;
4886 print STDERR
"starting cleanup\n";
4888 if (my $fd = IO
::File-
>new($statfile, "r")) {
4889 while (defined(my $line = <$fd>)) {
4890 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
4893 if ($volid =~ m
|^/|) {
4894 unlink $volid || die 'unlink failed\n';
4896 PVE
::Storage
::vdisk_free
($storecfg, $volid);
4898 print STDERR
"temporary volume '$volid' sucessfuly removed\n";
4900 print STDERR
"unable to cleanup '$volid' - $@" if $@;
4902 print STDERR
"unable to parse line in statfile - $line";
4909 sub restore_archive
{
4910 my ($archive, $vmid, $user, $opts) = @_;
4912 my $format = $opts->{format
};
4915 if ($archive =~ m/\.tgz$/ || $archive =~ m/\.tar\.gz$/) {
4916 $format = 'tar' if !$format;
4918 } elsif ($archive =~ m/\.tar$/) {
4919 $format = 'tar' if !$format;
4920 } elsif ($archive =~ m/.tar.lzo$/) {
4921 $format = 'tar' if !$format;
4923 } elsif ($archive =~ m/\.vma$/) {
4924 $format = 'vma' if !$format;
4925 } elsif ($archive =~ m/\.vma\.gz$/) {
4926 $format = 'vma' if !$format;
4928 } elsif ($archive =~ m/\.vma\.lzo$/) {
4929 $format = 'vma' if !$format;
4932 $format = 'vma' if !$format; # default
4935 # try to detect archive format
4936 if ($format eq 'tar') {
4937 return restore_tar_archive
($archive, $vmid, $user, $opts);
4939 return restore_vma_archive
($archive, $vmid, $user, $opts, $comp);
4943 sub restore_update_config_line
{
4944 my ($outfd, $cookie, $vmid, $map, $line, $unique) = @_;
4946 return if $line =~ m/^\#qmdump\#/;
4947 return if $line =~ m/^\#vzdump\#/;
4948 return if $line =~ m/^lock:/;
4949 return if $line =~ m/^unused\d+:/;
4950 return if $line =~ m/^parent:/;
4951 return if $line =~ m/^template:/; # restored VM is never a template
4953 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
4954 # try to convert old 1.X settings
4955 my ($id, $ind, $ethcfg) = ($1, $2, $3);
4956 foreach my $devconfig (PVE
::Tools
::split_list
($ethcfg)) {
4957 my ($model, $macaddr) = split(/\=/, $devconfig);
4958 $macaddr = PVE
::Tools
::random_ether_addr
() if !$macaddr || $unique;
4961 bridge
=> "vmbr$ind",
4962 macaddr
=> $macaddr,
4964 my $netstr = print_net
($net);
4966 print $outfd "net$cookie->{netcount}: $netstr\n";
4967 $cookie->{netcount
}++;
4969 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && $unique) {
4970 my ($id, $netstr) = ($1, $2);
4971 my $net = parse_net
($netstr);
4972 $net->{macaddr
} = PVE
::Tools
::random_ether_addr
() if $net->{macaddr
};
4973 $netstr = print_net
($net);
4974 print $outfd "$id: $netstr\n";
4975 } elsif ($line =~ m/^((ide|scsi|virtio|sata)\d+):\s*(\S+)\s*$/) {
4978 if ($line =~ m/backup=no/) {
4979 print $outfd "#$line";
4980 } elsif ($virtdev && $map->{$virtdev}) {
4981 my $di = parse_drive
($virtdev, $value);
4982 delete $di->{format
}; # format can change on restore
4983 $di->{file
} = $map->{$virtdev};
4984 $value = print_drive
($vmid, $di);
4985 print $outfd "$virtdev: $value\n";
4995 my ($cfg, $vmid) = @_;
4997 my $info = PVE
::Storage
::vdisk_list
($cfg, undef, $vmid);
4999 my $volid_hash = {};
5000 foreach my $storeid (keys %$info) {
5001 foreach my $item (@{$info->{$storeid}}) {
5002 next if !($item->{volid
} && $item->{size
});
5003 $item->{path
} = PVE
::Storage
::path
($cfg, $item->{volid
});
5004 $volid_hash->{$item->{volid
}} = $item;
5011 sub get_used_paths
{
5012 my ($vmid, $storecfg, $conf, $scan_snapshots, $skip_drive) = @_;
5016 my $scan_config = sub {
5017 my ($cref, $snapname) = @_;
5019 foreach my $key (keys %$cref) {
5020 my $value = $cref->{$key};
5021 if (valid_drivename
($key)) {
5022 next if $skip_drive && $key eq $skip_drive;
5023 my $drive = parse_drive
($key, $value);
5024 next if !$drive || !$drive->{file
} || drive_is_cdrom
($drive);
5025 if ($drive->{file
} =~ m!^/!) {
5026 $used_path->{$drive->{file
}}++; # = 1;
5028 my ($storeid, $volname) = PVE
::Storage
::parse_volume_id
($drive->{file
}, 1);
5030 my $scfg = PVE
::Storage
::storage_config
($storecfg, $storeid, 1);
5032 my $path = PVE
::Storage
::path
($storecfg, $drive->{file
}, $snapname);
5033 $used_path->{$path}++; # = 1;
5039 &$scan_config($conf);
5043 if ($scan_snapshots) {
5044 foreach my $snapname (keys %{$conf->{snapshots
}}) {
5045 &$scan_config($conf->{snapshots
}->{$snapname}, $snapname);
5052 sub update_disksize
{
5053 my ($vmid, $conf, $volid_hash) = @_;
5059 # Note: it is allowed to define multiple storages with same path (alias), so
5060 # we need to check both 'volid' and real 'path' (two different volid can point
5061 # to the same path).
5066 foreach my $opt (keys %$conf) {
5067 if (valid_drivename
($opt)) {
5068 my $drive = parse_drive
($opt, $conf->{$opt});
5069 my $volid = $drive->{file
};
5072 $used->{$volid} = 1;
5073 if ($volid_hash->{$volid} &&
5074 (my $path = $volid_hash->{$volid}->{path
})) {
5075 $usedpath->{$path} = 1;
5078 next if drive_is_cdrom
($drive);
5079 next if !$volid_hash->{$volid};
5081 $drive->{size
} = $volid_hash->{$volid}->{size
};
5082 my $new = print_drive
($vmid, $drive);
5083 if ($new ne $conf->{$opt}) {
5085 $conf->{$opt} = $new;
5090 # remove 'unusedX' entry if volume is used
5091 foreach my $opt (keys %$conf) {
5092 next if $opt !~ m/^unused\d+$/;
5093 my $volid = $conf->{$opt};
5094 my $path = $volid_hash->{$volid}->{path
} if $volid_hash->{$volid};
5095 if ($used->{$volid} || ($path && $usedpath->{$path})) {
5097 delete $conf->{$opt};
5101 foreach my $volid (sort keys %$volid_hash) {
5102 next if $volid =~ m/vm-$vmid-state-/;
5103 next if $used->{$volid};
5104 my $path = $volid_hash->{$volid}->{path
};
5105 next if !$path; # just to be sure
5106 next if $usedpath->{$path};
5108 add_unused_volume
($conf, $volid);
5109 $usedpath->{$path} = 1; # avoid to add more than once (aliases)
5116 my ($vmid, $nolock) = @_;
5118 my $cfg = PVE
::Cluster
::cfs_read_file
("storage.cfg");
5120 my $volid_hash = scan_volids
($cfg, $vmid);
5122 my $updatefn = sub {
5125 my $conf = load_config
($vmid);
5130 foreach my $volid (keys %$volid_hash) {
5131 my $info = $volid_hash->{$volid};
5132 $vm_volids->{$volid} = $info if $info->{vmid
} && $info->{vmid
} == $vmid;
5135 my $changes = update_disksize
($vmid, $conf, $vm_volids);
5137 update_config_nolock
($vmid, $conf, 1) if $changes;
5140 if (defined($vmid)) {
5144 lock_config
($vmid, $updatefn, $vmid);
5147 my $vmlist = config_list
();
5148 foreach my $vmid (keys %$vmlist) {
5152 lock_config
($vmid, $updatefn, $vmid);
5158 sub restore_vma_archive
{
5159 my ($archive, $vmid, $user, $opts, $comp) = @_;
5161 my $input = $archive eq '-' ?
"<&STDIN" : undef;
5162 my $readfrom = $archive;
5167 my $qarchive = PVE
::Tools
::shellquote
($archive);
5168 if ($comp eq 'gzip') {
5169 $uncomp = "zcat $qarchive|";
5170 } elsif ($comp eq 'lzop') {
5171 $uncomp = "lzop -d -c $qarchive|";
5173 die "unknown compression method '$comp'\n";
5178 my $tmpdir = "/var/tmp/vzdumptmp$$";
5181 # disable interrupts (always do cleanups)
5182 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
5183 warn "got interrupt - ignored\n";
5186 my $mapfifo = "/var/tmp/vzdumptmp$$.fifo";
5187 POSIX
::mkfifo
($mapfifo, 0600);
5190 my $openfifo = sub {
5191 open($fifofh, '>', $mapfifo) || die $!;
5194 my $cmd = "${uncomp}vma extract -v -r $mapfifo $readfrom $tmpdir";
5201 my $rpcenv = PVE
::RPCEnvironment
::get
();
5203 my $conffile = config_file
($vmid);
5204 my $tmpfn = "$conffile.$$.tmp";
5206 # Note: $oldconf is undef if VM does not exists
5207 my $oldconf = PVE
::Cluster
::cfs_read_file
(cfs_config_path
($vmid));
5209 my $print_devmap = sub {
5210 my $virtdev_hash = {};
5212 my $cfgfn = "$tmpdir/qemu-server.conf";
5214 # we can read the config - that is already extracted
5215 my $fh = IO
::File-
>new($cfgfn, "r") ||
5216 "unable to read qemu-server.conf - $!\n";
5218 while (defined(my $line = <$fh>)) {
5219 if ($line =~ m/^\#qmdump\#map:(\S+):(\S+):(\S*):(\S*):$/) {
5220 my ($virtdev, $devname, $storeid, $format) = ($1, $2, $3, $4);
5221 die "archive does not contain data for drive '$virtdev'\n"
5222 if !$devinfo->{$devname};
5223 if (defined($opts->{storage
})) {
5224 $storeid = $opts->{storage
} || 'local';
5225 } elsif (!$storeid) {
5228 $format = 'raw' if !$format;
5229 $devinfo->{$devname}->{devname
} = $devname;
5230 $devinfo->{$devname}->{virtdev
} = $virtdev;
5231 $devinfo->{$devname}->{format
} = $format;
5232 $devinfo->{$devname}->{storeid
} = $storeid;
5234 # check permission on storage
5235 my $pool = $opts->{pool
}; # todo: do we need that?
5236 if ($user ne 'root@pam') {
5237 $rpcenv->check($user, "/storage/$storeid", ['Datastore.AllocateSpace']);
5240 $virtdev_hash->{$virtdev} = $devinfo->{$devname};
5244 foreach my $devname (keys %$devinfo) {
5245 die "found no device mapping information for device '$devname'\n"
5246 if !$devinfo->{$devname}->{virtdev
};
5249 my $cfg = cfs_read_file
('storage.cfg');
5251 # create empty/temp config
5253 PVE
::Tools
::file_set_contents
($conffile, "memory: 128\n");
5254 foreach_drive
($oldconf, sub {
5255 my ($ds, $drive) = @_;
5257 return if drive_is_cdrom
($drive);
5259 my $volid = $drive->{file
};
5261 return if !$volid || $volid =~ m
|^/|;
5263 my ($path, $owner) = PVE
::Storage
::path
($cfg, $volid);
5264 return if !$path || !$owner || ($owner != $vmid);
5266 # Note: only delete disk we want to restore
5267 # other volumes will become unused
5268 if ($virtdev_hash->{$ds}) {
5269 PVE
::Storage
::vdisk_free
($cfg, $volid);
5275 foreach my $virtdev (sort keys %$virtdev_hash) {
5276 my $d = $virtdev_hash->{$virtdev};
5277 my $alloc_size = int(($d->{size
} + 1024 - 1)/1024);
5278 my $scfg = PVE
::Storage
::storage_config
($cfg, $d->{storeid
});
5280 # test if requested format is supported
5281 my ($defFormat, $validFormats) = PVE
::Storage
::storage_default_format
($cfg, $d->{storeid
});
5282 my $supported = grep { $_ eq $d->{format
} } @$validFormats;
5283 $d->{format
} = $defFormat if !$supported;
5285 my $volid = PVE
::Storage
::vdisk_alloc
($cfg, $d->{storeid
}, $vmid,
5286 $d->{format
}, undef, $alloc_size);
5287 print STDERR
"new volume ID is '$volid'\n";
5288 $d->{volid
} = $volid;
5289 my $path = PVE
::Storage
::path
($cfg, $volid);
5291 my $write_zeros = 1;
5292 # fixme: what other storages types initialize volumes with zero?
5293 if ($scfg->{type
} eq 'dir' || $scfg->{type
} eq 'nfs' || $scfg->{type
} eq 'glusterfs' ||
5294 $scfg->{type
} eq 'sheepdog' || $scfg->{type
} eq 'rbd') {
5298 print $fifofh "${write_zeros}:$d->{devname}=$path\n";
5300 print "map '$d->{devname}' to '$path' (write zeros = ${write_zeros})\n";
5301 $map->{$virtdev} = $volid;
5304 $fh->seek(0, 0) || die "seek failed - $!\n";
5306 my $outfd = new IO
::File
($tmpfn, "w") ||
5307 die "unable to write config for VM $vmid\n";
5309 my $cookie = { netcount
=> 0 };
5310 while (defined(my $line = <$fh>)) {
5311 restore_update_config_line
($outfd, $cookie, $vmid, $map, $line, $opts->{unique
});
5320 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
5321 die "interrupted by signal\n";
5323 local $SIG{ALRM
} = sub { die "got timeout\n"; };
5325 $oldtimeout = alarm($timeout);
5332 if ($line =~ m/^DEV:\sdev_id=(\d+)\ssize:\s(\d+)\sdevname:\s(\S+)$/) {
5333 my ($dev_id, $size, $devname) = ($1, $2, $3);
5334 $devinfo->{$devname} = { size
=> $size, dev_id
=> $dev_id };
5335 } elsif ($line =~ m/^CTIME: /) {
5336 # we correctly received the vma config, so we can disable
5337 # the timeout now for disk allocation (set to 10 minutes, so
5338 # that we always timeout if something goes wrong)
5341 print $fifofh "done\n";
5342 my $tmp = $oldtimeout || 0;
5343 $oldtimeout = undef;
5349 print "restore vma archive: $cmd\n";
5350 run_command
($cmd, input
=> $input, outfunc
=> $parser, afterfork
=> $openfifo);
5354 alarm($oldtimeout) if $oldtimeout;
5362 my $cfg = cfs_read_file
('storage.cfg');
5363 foreach my $devname (keys %$devinfo) {
5364 my $volid = $devinfo->{$devname}->{volid
};
5367 if ($volid =~ m
|^/|) {
5368 unlink $volid || die 'unlink failed\n';
5370 PVE
::Storage
::vdisk_free
($cfg, $volid);
5372 print STDERR
"temporary volume '$volid' sucessfuly removed\n";
5374 print STDERR
"unable to cleanup '$volid' - $@" if $@;
5381 rename($tmpfn, $conffile) ||
5382 die "unable to commit configuration file '$conffile'\n";
5384 PVE
::Cluster
::cfs_update
(); # make sure we read new file
5386 eval { rescan
($vmid, 1); };
5390 sub restore_tar_archive
{
5391 my ($archive, $vmid, $user, $opts) = @_;
5393 if ($archive ne '-') {
5394 my $firstfile = tar_archive_read_firstfile
($archive);
5395 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
5396 if $firstfile ne 'qemu-server.conf';
5399 my $storecfg = cfs_read_file
('storage.cfg');
5401 # destroy existing data - keep empty config
5402 my $vmcfgfn = config_file
($vmid);
5403 destroy_vm
($storecfg, $vmid, 1) if -f
$vmcfgfn;
5405 my $tocmd = "/usr/lib/qemu-server/qmextract";
5407 $tocmd .= " --storage " . PVE
::Tools
::shellquote
($opts->{storage
}) if $opts->{storage
};
5408 $tocmd .= " --pool " . PVE
::Tools
::shellquote
($opts->{pool
}) if $opts->{pool
};
5409 $tocmd .= ' --prealloc' if $opts->{prealloc
};
5410 $tocmd .= ' --info' if $opts->{info
};
5412 # tar option "xf" does not autodetect compression when read from STDIN,
5413 # so we pipe to zcat
5414 my $cmd = "zcat -f|tar xf " . PVE
::Tools
::shellquote
($archive) . " " .
5415 PVE
::Tools
::shellquote
("--to-command=$tocmd");
5417 my $tmpdir = "/var/tmp/vzdumptmp$$";
5420 local $ENV{VZDUMP_TMPDIR
} = $tmpdir;
5421 local $ENV{VZDUMP_VMID
} = $vmid;
5422 local $ENV{VZDUMP_USER
} = $user;
5424 my $conffile = config_file
($vmid);
5425 my $tmpfn = "$conffile.$$.tmp";
5427 # disable interrupts (always do cleanups)
5428 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
5429 print STDERR
"got interrupt - ignored\n";
5434 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
5435 die "interrupted by signal\n";
5438 if ($archive eq '-') {
5439 print "extracting archive from STDIN\n";
5440 run_command
($cmd, input
=> "<&STDIN");
5442 print "extracting archive '$archive'\n";
5446 return if $opts->{info
};
5450 my $statfile = "$tmpdir/qmrestore.stat";
5451 if (my $fd = IO
::File-
>new($statfile, "r")) {
5452 while (defined (my $line = <$fd>)) {
5453 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
5454 $map->{$1} = $2 if $1;
5456 print STDERR
"unable to parse line in statfile - $line\n";
5462 my $confsrc = "$tmpdir/qemu-server.conf";
5464 my $srcfd = new IO
::File
($confsrc, "r") ||
5465 die "unable to open file '$confsrc'\n";
5467 my $outfd = new IO
::File
($tmpfn, "w") ||
5468 die "unable to write config for VM $vmid\n";
5470 my $cookie = { netcount
=> 0 };
5471 while (defined (my $line = <$srcfd>)) {
5472 restore_update_config_line
($outfd, $cookie, $vmid, $map, $line, $opts->{unique
});
5484 tar_restore_cleanup
($storecfg, "$tmpdir/qmrestore.stat") if !$opts->{info
};
5491 rename $tmpfn, $conffile ||
5492 die "unable to commit configuration file '$conffile'\n";
5494 PVE
::Cluster
::cfs_update
(); # make sure we read new file
5496 eval { rescan
($vmid, 1); };
5501 # Internal snapshots
5503 # NOTE: Snapshot create/delete involves several non-atomic
5504 # action, and can take a long time.
5505 # So we try to avoid locking the file and use 'lock' variable
5506 # inside the config file instead.
5508 my $snapshot_copy_config = sub {
5509 my ($source, $dest) = @_;
5511 foreach my $k (keys %$source) {
5512 next if $k eq 'snapshots';
5513 next if $k eq 'snapstate';
5514 next if $k eq 'snaptime';
5515 next if $k eq 'vmstate';
5516 next if $k eq 'lock';
5517 next if $k eq 'digest';
5518 next if $k eq 'description';
5519 next if $k =~ m/^unused\d+$/;
5521 $dest->{$k} = $source->{$k};
5525 my $snapshot_apply_config = sub {
5526 my ($conf, $snap) = @_;
5528 # copy snapshot list
5530 snapshots
=> $conf->{snapshots
},
5533 # keep description and list of unused disks
5534 foreach my $k (keys %$conf) {
5535 next if !($k =~ m/^unused\d+$/ || $k eq 'description');
5536 $newconf->{$k} = $conf->{$k};
5539 &$snapshot_copy_config($snap, $newconf);
5544 sub foreach_writable_storage
{
5545 my ($conf, $func) = @_;
5549 foreach my $ds (keys %$conf) {
5550 next if !valid_drivename
($ds);
5552 my $drive = parse_drive
($ds, $conf->{$ds});
5554 next if drive_is_cdrom
($drive);
5556 my $volid = $drive->{file
};
5558 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
5559 $sidhash->{$sid} = $sid if $sid;
5562 foreach my $sid (sort keys %$sidhash) {
5567 my $alloc_vmstate_volid = sub {
5568 my ($storecfg, $vmid, $conf, $snapname) = @_;
5570 # Note: we try to be smart when selecting a $target storage
5574 # search shared storage first
5575 foreach_writable_storage
($conf, sub {
5577 my $scfg = PVE
::Storage
::storage_config
($storecfg, $sid);
5578 return if !$scfg->{shared
};
5580 $target = $sid if !$target || $scfg->{path
}; # prefer file based storage
5584 # now search local storage
5585 foreach_writable_storage
($conf, sub {
5587 my $scfg = PVE
::Storage
::storage_config
($storecfg, $sid);
5588 return if $scfg->{shared
};
5590 $target = $sid if !$target || $scfg->{path
}; # prefer file based storage;
5594 $target = 'local' if !$target;
5596 my $driver_state_size = 500; # assume 32MB is enough to safe all driver state;
5597 # we abort live save after $conf->{memory}, so we need at max twice that space
5598 my $size = $conf->{memory
}*2 + $driver_state_size;
5600 my $name = "vm-$vmid-state-$snapname";
5601 my $scfg = PVE
::Storage
::storage_config
($storecfg, $target);
5602 $name .= ".raw" if $scfg->{path
}; # add filename extension for file base storage
5603 my $volid = PVE
::Storage
::vdisk_alloc
($storecfg, $target, $vmid, 'raw', $name, $size*1024);
5608 my $snapshot_prepare = sub {
5609 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
5613 my $updatefn = sub {
5615 my $conf = load_config
($vmid);
5617 die "you can't take a snapshot if it's a template\n"
5618 if is_template
($conf);
5622 $conf->{lock} = 'snapshot';
5624 die "snapshot name '$snapname' already used\n"
5625 if defined($conf->{snapshots
}->{$snapname});
5627 my $storecfg = PVE
::Storage
::config
();
5628 die "snapshot feature is not available" if !has_feature
('snapshot', $conf, $storecfg);
5630 $snap = $conf->{snapshots
}->{$snapname} = {};
5632 if ($save_vmstate && check_running
($vmid)) {
5633 $snap->{vmstate
} = &$alloc_vmstate_volid($storecfg, $vmid, $conf, $snapname);
5636 &$snapshot_copy_config($conf, $snap);
5638 $snap->{snapstate
} = "prepare";
5639 $snap->{snaptime
} = time();
5640 $snap->{description
} = $comment if $comment;
5642 # always overwrite machine if we save vmstate. This makes sure we
5643 # can restore it later using correct machine type
5644 $snap->{machine
} = get_current_qemu_machine
($vmid) if $snap->{vmstate
};
5646 update_config_nolock
($vmid, $conf, 1);
5649 lock_config
($vmid, $updatefn);
5654 my $snapshot_commit = sub {
5655 my ($vmid, $snapname) = @_;
5657 my $updatefn = sub {
5659 my $conf = load_config
($vmid);
5661 die "missing snapshot lock\n"
5662 if !($conf->{lock} && $conf->{lock} eq 'snapshot');
5664 my $has_machine_config = defined($conf->{machine
});
5666 my $snap = $conf->{snapshots
}->{$snapname};
5668 die "snapshot '$snapname' does not exist\n" if !defined($snap);
5670 die "wrong snapshot state\n"
5671 if !($snap->{snapstate
} && $snap->{snapstate
} eq "prepare");
5673 delete $snap->{snapstate
};
5674 delete $conf->{lock};
5676 my $newconf = &$snapshot_apply_config($conf, $snap);
5678 delete $newconf->{machine
} if !$has_machine_config;
5680 $newconf->{parent
} = $snapname;
5682 update_config_nolock
($vmid, $newconf, 1);
5685 lock_config
($vmid, $updatefn);
5688 sub snapshot_rollback
{
5689 my ($vmid, $snapname) = @_;
5693 my $storecfg = PVE
::Storage
::config
();
5695 my $conf = load_config
($vmid);
5697 my $get_snapshot_config = sub {
5699 die "you can't rollback if vm is a template\n" if is_template
($conf);
5701 my $res = $conf->{snapshots
}->{$snapname};
5703 die "snapshot '$snapname' does not exist\n" if !defined($res);
5708 my $snap = &$get_snapshot_config();
5710 foreach_drive
($snap, sub {
5711 my ($ds, $drive) = @_;
5713 return if drive_is_cdrom
($drive);
5715 my $volid = $drive->{file
};
5717 PVE
::Storage
::volume_rollback_is_possible
($storecfg, $volid, $snapname);
5720 my $updatefn = sub {
5722 $conf = load_config
($vmid);
5724 $snap = &$get_snapshot_config();
5726 die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
5727 if $snap->{snapstate
};
5731 vm_stop
($storecfg, $vmid, undef, undef, 5, undef, undef);
5734 die "unable to rollback vm $vmid: vm is running\n"
5735 if check_running
($vmid);
5738 $conf->{lock} = 'rollback';
5740 die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
5741 delete $conf->{lock};
5747 my $has_machine_config = defined($conf->{machine
});
5749 # copy snapshot config to current config
5750 $conf = &$snapshot_apply_config($conf, $snap);
5751 $conf->{parent
} = $snapname;
5753 # Note: old code did not store 'machine', so we try to be smart
5754 # and guess the snapshot was generated with kvm 1.4 (pc-i440fx-1.4).
5755 $forcemachine = $conf->{machine
} || 'pc-i440fx-1.4';
5756 # we remove the 'machine' configuration if not explicitly specified
5757 # in the original config.
5758 delete $conf->{machine
} if $snap->{vmstate
} && !$has_machine_config;
5761 update_config_nolock
($vmid, $conf, 1);
5763 if (!$prepare && $snap->{vmstate
}) {
5764 my $statefile = PVE
::Storage
::path
($storecfg, $snap->{vmstate
});
5765 vm_start
($storecfg, $vmid, $statefile, undef, undef, undef, $forcemachine);
5769 lock_config
($vmid, $updatefn);
5771 foreach_drive
($snap, sub {
5772 my ($ds, $drive) = @_;
5774 return if drive_is_cdrom
($drive);
5776 my $volid = $drive->{file
};
5777 my $device = "drive-$ds";
5779 PVE
::Storage
::volume_snapshot_rollback
($storecfg, $volid, $snapname);
5783 lock_config
($vmid, $updatefn);
5786 my $savevm_wait = sub {
5790 my $stat = vm_mon_cmd_nocheck
($vmid, "query-savevm");
5791 if (!$stat->{status
}) {
5792 die "savevm not active\n";
5793 } elsif ($stat->{status
} eq 'active') {
5796 } elsif ($stat->{status
} eq 'completed') {
5799 die "query-savevm returned status '$stat->{status}'\n";
5804 sub snapshot_create
{
5805 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
5807 my $snap = &$snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
5809 $save_vmstate = 0 if !$snap->{vmstate
}; # vm is not running
5811 my $config = load_config
($vmid);
5813 my $running = check_running
($vmid);
5815 my $freezefs = $running && $config->{agent
};
5816 $freezefs = 0 if $snap->{vmstate
}; # not needed if we save RAM
5821 eval { vm_mon_cmd
($vmid, "guest-fsfreeze-freeze"); };
5822 warn "guest-fsfreeze-freeze problems - $@" if $@;
5826 # create internal snapshots of all drives
5828 my $storecfg = PVE
::Storage
::config
();
5831 if ($snap->{vmstate
}) {
5832 my $path = PVE
::Storage
::path
($storecfg, $snap->{vmstate
});
5833 vm_mon_cmd
($vmid, "savevm-start", statefile
=> $path);
5834 &$savevm_wait($vmid);
5836 vm_mon_cmd
($vmid, "savevm-start");
5840 foreach_drive
($snap, sub {
5841 my ($ds, $drive) = @_;
5843 return if drive_is_cdrom
($drive);
5845 my $volid = $drive->{file
};
5846 my $device = "drive-$ds";
5848 qemu_volume_snapshot
($vmid, $device, $storecfg, $volid, $snapname);
5849 $drivehash->{$ds} = 1;
5855 eval { vm_mon_cmd
($vmid, "savevm-end") };
5859 eval { vm_mon_cmd
($vmid, "guest-fsfreeze-thaw"); };
5860 warn "guest-fsfreeze-thaw problems - $@" if $@;
5863 # savevm-end is async, we need to wait
5865 my $stat = vm_mon_cmd_nocheck
($vmid, "query-savevm");
5866 if (!$stat->{bytes
}) {
5869 print "savevm not yet finished\n";
5877 warn "snapshot create failed: starting cleanup\n";
5878 eval { snapshot_delete
($vmid, $snapname, 0, $drivehash); };
5883 &$snapshot_commit($vmid, $snapname);
5886 # Note: $drivehash is only set when called from snapshot_create.
5887 sub snapshot_delete
{
5888 my ($vmid, $snapname, $force, $drivehash) = @_;
5895 my $unlink_parent = sub {
5896 my ($confref, $new_parent) = @_;
5898 if ($confref->{parent
} && $confref->{parent
} eq $snapname) {
5900 $confref->{parent
} = $new_parent;
5902 delete $confref->{parent
};
5907 my $updatefn = sub {
5908 my ($remove_drive) = @_;
5910 my $conf = load_config
($vmid);
5914 die "you can't delete a snapshot if vm is a template\n"
5915 if is_template
($conf);
5918 $snap = $conf->{snapshots
}->{$snapname};
5920 die "snapshot '$snapname' does not exist\n" if !defined($snap);
5922 # remove parent refs
5924 &$unlink_parent($conf, $snap->{parent
});
5925 foreach my $sn (keys %{$conf->{snapshots
}}) {
5926 next if $sn eq $snapname;
5927 &$unlink_parent($conf->{snapshots
}->{$sn}, $snap->{parent
});
5931 if ($remove_drive) {
5932 if ($remove_drive eq 'vmstate') {
5933 delete $snap->{$remove_drive};
5935 my $drive = parse_drive
($remove_drive, $snap->{$remove_drive});
5936 my $volid = $drive->{file
};
5937 delete $snap->{$remove_drive};
5938 add_unused_volume
($conf, $volid);
5943 $snap->{snapstate
} = 'delete';
5945 delete $conf->{snapshots
}->{$snapname};
5946 delete $conf->{lock} if $drivehash;
5947 foreach my $volid (@$unused) {
5948 add_unused_volume
($conf, $volid);
5952 update_config_nolock
($vmid, $conf, 1);
5955 lock_config
($vmid, $updatefn);
5957 # now remove vmstate file
5959 my $storecfg = PVE
::Storage
::config
();
5961 if ($snap->{vmstate
}) {
5962 eval { PVE
::Storage
::vdisk_free
($storecfg, $snap->{vmstate
}); };
5964 die $err if !$force;
5967 # save changes (remove vmstate from snapshot)
5968 lock_config
($vmid, $updatefn, 'vmstate') if !$force;
5971 # now remove all internal snapshots
5972 foreach_drive
($snap, sub {
5973 my ($ds, $drive) = @_;
5975 return if drive_is_cdrom
($drive);
5977 my $volid = $drive->{file
};
5978 my $device = "drive-$ds";
5980 if (!$drivehash || $drivehash->{$ds}) {
5981 eval { qemu_volume_snapshot_delete
($vmid, $device, $storecfg, $volid, $snapname); };
5983 die $err if !$force;
5988 # save changes (remove drive fron snapshot)
5989 lock_config
($vmid, $updatefn, $ds) if !$force;
5990 push @$unused, $volid;
5993 # now cleanup config
5995 lock_config
($vmid, $updatefn);
5999 my ($feature, $conf, $storecfg, $snapname, $running) = @_;
6002 foreach_drive
($conf, sub {
6003 my ($ds, $drive) = @_;
6005 return if drive_is_cdrom
($drive);
6006 my $volid = $drive->{file
};
6007 $err = 1 if !PVE
::Storage
::volume_has_feature
($storecfg, $feature, $volid, $snapname, $running);
6010 return $err ?
0 : 1;
6013 sub template_create
{
6014 my ($vmid, $conf, $disk) = @_;
6016 my $storecfg = PVE
::Storage
::config
();
6018 foreach_drive
($conf, sub {
6019 my ($ds, $drive) = @_;
6021 return if drive_is_cdrom
($drive);
6022 return if $disk && $ds ne $disk;
6024 my $volid = $drive->{file
};
6025 return if !PVE
::Storage
::volume_has_feature
($storecfg, 'template', $volid);
6027 my $voliddst = PVE
::Storage
::vdisk_create_base
($storecfg, $volid);
6028 $drive->{file
} = $voliddst;
6029 $conf->{$ds} = print_drive
($vmid, $drive);
6030 update_config_nolock
($vmid, $conf, 1);
6037 return 1 if defined $conf->{template
} && $conf->{template
} == 1;
6040 sub qemu_img_convert
{
6041 my ($src_volid, $dst_volid, $size, $snapname) = @_;
6043 my $storecfg = PVE
::Storage
::config
();
6044 my ($src_storeid, $src_volname) = PVE
::Storage
::parse_volume_id
($src_volid, 1);
6045 my ($dst_storeid, $dst_volname) = PVE
::Storage
::parse_volume_id
($dst_volid, 1);
6047 if ($src_storeid && $dst_storeid) {
6048 my $src_scfg = PVE
::Storage
::storage_config
($storecfg, $src_storeid);
6049 my $dst_scfg = PVE
::Storage
::storage_config
($storecfg, $dst_storeid);
6051 my $src_format = qemu_img_format
($src_scfg, $src_volname);
6052 my $dst_format = qemu_img_format
($dst_scfg, $dst_volname);
6054 my $src_path = PVE
::Storage
::path
($storecfg, $src_volid, $snapname);
6055 my $dst_path = PVE
::Storage
::path
($storecfg, $dst_volid);
6058 push @$cmd, '/usr/bin/qemu-img', 'convert', '-t', 'writeback', '-p', '-n';
6059 push @$cmd, '-s', $snapname if($snapname && $src_format eq "qcow2");
6060 push @$cmd, '-f', $src_format, '-O', $dst_format, $src_path, $dst_path;
6064 if($line =~ m/\((\S+)\/100\
%\)/){
6066 my $transferred = int($size * $percent / 100);
6067 my $remaining = $size - $transferred;
6069 print "transferred: $transferred bytes remaining: $remaining bytes total: $size bytes progression: $percent %\n";
6074 eval { run_command
($cmd, timeout
=> undef, outfunc
=> $parser); };
6076 die "copy failed: $err" if $err;
6080 sub qemu_img_format
{
6081 my ($scfg, $volname) = @_;
6083 if ($scfg->{path
} && $volname =~ m/\.(raw|qcow2|qed|vmdk)$/) {
6085 } elsif ($scfg->{type
} eq 'iscsi') {
6086 return "host_device";
6092 sub qemu_drive_mirror
{
6093 my ($vmid, $drive, $dst_volid, $vmiddst) = @_;
6100 my $storecfg = PVE
::Storage
::config
();
6101 my ($dst_storeid, $dst_volname) = PVE
::Storage
::parse_volume_id
($dst_volid);
6103 my $dst_scfg = PVE
::Storage
::storage_config
($storecfg, $dst_storeid);
6106 if ($dst_volname =~ m/\.(raw|qcow2)$/){
6110 my $dst_path = PVE
::Storage
::path
($storecfg, $dst_volid);
6112 my $opts = { timeout
=> 10, device
=> "drive-$drive", mode
=> "existing", sync
=> "full", target
=> $dst_path };
6113 $opts->{format
} = $format if $format;
6115 #fixme : sometime drive-mirror timeout, but works fine after.
6116 # (I have see the problem with big volume > 200GB), so we need to eval
6117 eval { vm_mon_cmd
($vmid, "drive-mirror", %$opts); };
6118 # ignore errors here
6122 my $stats = vm_mon_cmd
($vmid, "query-block-jobs");
6123 my $stat = @$stats[0];
6124 die "mirroring job seem to have die. Maybe do you have bad sectors?" if !$stat;
6125 die "error job is not mirroring" if $stat->{type
} ne "mirror";
6127 my $busy = $stat->{busy
};
6129 if (my $total = $stat->{len
}) {
6130 my $transferred = $stat->{offset
} || 0;
6131 my $remaining = $total - $transferred;
6132 my $percent = sprintf "%.2f", ($transferred * 100 / $total);
6134 print "transferred: $transferred bytes remaining: $remaining bytes total: $total bytes progression: $percent % busy: $busy\n";
6137 if ($stat->{len
} == $stat->{offset
}) {
6138 if ($busy eq 'false') {
6140 last if $vmiddst != $vmid;
6142 # try to switch the disk if source and destination are on the same guest
6143 eval { vm_mon_cmd
($vmid, "block-job-complete", device
=> "drive-$drive") };
6145 die $@ if $@ !~ m/cannot be completed/;
6148 if ($count > $maxwait) {
6149 # if too much writes to disk occurs at the end of migration
6150 #the disk needs to be freezed to be able to complete the migration
6151 vm_suspend
($vmid,1);
6156 $old_len = $stat->{offset
};
6160 vm_resume
($vmid, 1) if $frozen;
6165 my $cancel_job = sub {
6166 vm_mon_cmd
($vmid, "block-job-cancel", device
=> "drive-$drive");
6168 my $stats = vm_mon_cmd
($vmid, "query-block-jobs");
6169 my $stat = @$stats[0];
6176 eval { &$cancel_job(); };
6177 die "mirroring error: $err";
6180 if ($vmiddst != $vmid) {
6181 # if we clone a disk for a new target vm, we don't switch the disk
6182 &$cancel_job(); # so we call block-job-cancel
6187 my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
6188 $newvmid, $storage, $format, $full, $newvollist) = @_;
6193 print "create linked clone of drive $drivename ($drive->{file})\n";
6194 $newvolid = PVE
::Storage
::vdisk_clone
($storecfg, $drive->{file
}, $newvmid, $snapname);
6195 push @$newvollist, $newvolid;
6197 my ($storeid, $volname) = PVE
::Storage
::parse_volume_id
($drive->{file
});
6198 $storeid = $storage if $storage;
6200 my ($defFormat, $validFormats) = PVE
::Storage
::storage_default_format
($storecfg, $storeid);
6202 $format = $drive->{format
} || $defFormat;
6205 # test if requested format is supported - else use default
6206 my $supported = grep { $_ eq $format } @$validFormats;
6207 $format = $defFormat if !$supported;
6209 my ($size) = PVE
::Storage
::volume_size_info
($storecfg, $drive->{file
}, 3);
6211 print "create full clone of drive $drivename ($drive->{file})\n";
6212 $newvolid = PVE
::Storage
::vdisk_alloc
($storecfg, $storeid, $newvmid, $format, undef, ($size/1024));
6213 push @$newvollist, $newvolid;
6215 if (!$running || $snapname) {
6216 qemu_img_convert
($drive->{file
}, $newvolid, $size, $snapname);
6218 qemu_drive_mirror
($vmid, $drivename, $newvolid, $newvmid);
6222 my ($size) = PVE
::Storage
::volume_size_info
($storecfg, $newvolid, 3);
6225 $disk->{format
} = undef;
6226 $disk->{file
} = $newvolid;
6227 $disk->{size
} = $size;
6232 # this only works if VM is running
6233 sub get_current_qemu_machine
{
6236 my $cmd = { execute
=> 'query-machines', arguments
=> {} };
6237 my $res = vm_qmp_command
($vmid, $cmd);
6239 my ($current, $default);
6240 foreach my $e (@$res) {
6241 $default = $e->{name
} if $e->{'is-default'};
6242 $current = $e->{name
} if $e->{'is-current'};
6245 # fallback to the default machine if current is not supported by qemu
6246 return $current || $default || 'pc';
6249 sub qemu_machine_feature_enabled
{
6250 my ($machine, $kvmver, $version_major, $version_minor) = @_;
6255 if ($machine && $machine =~ m/^(pc(-i440fx|-q35)?-(\d+)\.(\d+))/) {
6257 $current_major = $3;
6258 $current_minor = $4;
6260 } elsif ($kvmver =~ m/^(\d+)\.(\d+)/) {
6262 $current_major = $1;
6263 $current_minor = $2;
6266 return 1 if $current_major >= $version_major && $current_minor >= $version_minor;
6275 dir_glob_foreach
("$pcisysfs/devices", '[a-f0-9]{4}:([a-f0-9]{2}:[a-f0-9]{2})\.([0-9])', sub {
6276 my (undef, $id, $function) = @_;
6277 my $res = { id
=> $id, function
=> $function};
6278 push @{$devices->{$id}}, $res;
6284 sub vm_iothreads_list
{
6287 my $res = vm_mon_cmd
($vmid, 'query-iothreads');
6290 foreach my $iothread (@$res) {
6291 $iothreads->{ $iothread->{id
} } = $iothread->{"thread-id"};
6298 my ($conf, $drive) = @_;
6302 if ($conf->{scsihw
} && ($conf->{scsihw
} =~ m/^lsi/)) {
6304 } elsif ($conf->{scsihw
} && ($conf->{scsihw
} eq 'virtio-scsi-single')) {
6310 my $controller = int($drive->{index} / $maxdev);
6311 my $controller_prefix = ($conf->{scsihw
} && $conf->{scsihw
} eq 'virtio-scsi-single') ?
"virtioscsi" : "scsihw";
6313 return ($maxdev, $controller, $controller_prefix);