1 package PVE
::QemuServer
;
21 use Storable
qw(dclone);
22 use PVE
::Exception
qw(raise raise_param_exc);
24 use PVE
::Tools
qw(run_command lock_file file_read_firstline);
25 use PVE
::JSONSchema
qw(get_standard_option);
26 use PVE
::Cluster
qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
30 use Time
::HiRes
qw(gettimeofday);
32 my $cpuinfo = PVE
::ProcFSTools
::read_cpuinfo
();
34 # Note about locking: we use flock on the config file protect
35 # against concurent actions.
36 # Aditionaly, we have a 'lock' setting in the config file. This
37 # can be set to 'migrate', 'backup', 'snapshot' or 'rollback'. Most actions are not
38 # allowed when such lock is set. But you can ignore this kind of
39 # lock with the --skiplock flag.
41 cfs_register_file
('/qemu-server/',
45 PVE
::JSONSchema
::register_standard_option
('skiplock', {
46 description
=> "Ignore locks - only root is allowed to use this option.",
51 PVE
::JSONSchema
::register_standard_option
('pve-qm-stateuri', {
52 description
=> "Some command save/restore state from this location.",
58 PVE
::JSONSchema
::register_standard_option
('pve-snapshot-name', {
59 description
=> "The name of the snapshot.",
60 type
=> 'string', format
=> 'pve-configid',
64 #no warnings 'redefine';
66 unless(defined(&_VZSYSCALLS_H_
)) {
67 eval 'sub _VZSYSCALLS_H_ () {1;}' unless defined(&_VZSYSCALLS_H_
);
68 require 'sys/syscall.ph';
69 if(defined(&__x86_64__
)) {
70 eval 'sub __NR_fairsched_vcpus () {499;}' unless defined(&__NR_fairsched_vcpus
);
71 eval 'sub __NR_fairsched_mknod () {504;}' unless defined(&__NR_fairsched_mknod
);
72 eval 'sub __NR_fairsched_rmnod () {505;}' unless defined(&__NR_fairsched_rmnod
);
73 eval 'sub __NR_fairsched_chwt () {506;}' unless defined(&__NR_fairsched_chwt
);
74 eval 'sub __NR_fairsched_mvpr () {507;}' unless defined(&__NR_fairsched_mvpr
);
75 eval 'sub __NR_fairsched_rate () {508;}' unless defined(&__NR_fairsched_rate
);
76 eval 'sub __NR_setluid () {501;}' unless defined(&__NR_setluid
);
77 eval 'sub __NR_setublimit () {502;}' unless defined(&__NR_setublimit
);
79 elsif(defined( &__i386__
) ) {
80 eval 'sub __NR_fairsched_mknod () {500;}' unless defined(&__NR_fairsched_mknod
);
81 eval 'sub __NR_fairsched_rmnod () {501;}' unless defined(&__NR_fairsched_rmnod
);
82 eval 'sub __NR_fairsched_chwt () {502;}' unless defined(&__NR_fairsched_chwt
);
83 eval 'sub __NR_fairsched_mvpr () {503;}' unless defined(&__NR_fairsched_mvpr
);
84 eval 'sub __NR_fairsched_rate () {504;}' unless defined(&__NR_fairsched_rate
);
85 eval 'sub __NR_fairsched_vcpus () {505;}' unless defined(&__NR_fairsched_vcpus
);
86 eval 'sub __NR_setluid () {511;}' unless defined(&__NR_setluid
);
87 eval 'sub __NR_setublimit () {512;}' unless defined(&__NR_setublimit
);
89 die("no fairsched syscall for this arch");
91 require 'asm/ioctl.ph';
92 eval 'sub KVM_GET_API_VERSION () { &_IO(0xAE, 0x);}' unless defined(&KVM_GET_API_VERSION
);
96 my ($parent, $weight, $desired) = @_;
98 return syscall(&__NR_fairsched_mknod
, int($parent), int($weight), int($desired));
101 sub fairsched_rmnod
{
104 return syscall(&__NR_fairsched_rmnod
, int($id));
108 my ($pid, $newid) = @_;
110 return syscall(&__NR_fairsched_mvpr
, int($pid), int($newid));
113 sub fairsched_vcpus
{
114 my ($id, $vcpus) = @_;
116 return syscall(&__NR_fairsched_vcpus
, int($id), int($vcpus));
120 my ($id, $op, $rate) = @_;
122 return syscall(&__NR_fairsched_rate
, int($id), int($op), int($rate));
125 use constant FAIRSCHED_SET_RATE
=> 0;
126 use constant FAIRSCHED_DROP_RATE
=> 1;
127 use constant FAIRSCHED_GET_RATE
=> 2;
129 sub fairsched_cpulimit
{
130 my ($id, $limit) = @_;
132 my $cpulim1024 = int($limit * 1024 / 100);
133 my $op = $cpulim1024 ? FAIRSCHED_SET_RATE
: FAIRSCHED_DROP_RATE
;
135 return fairsched_rate
($id, $op, $cpulim1024);
138 my $nodename = PVE
::INotify
::nodename
();
140 mkdir "/etc/pve/nodes/$nodename";
141 my $confdir = "/etc/pve/nodes/$nodename/qemu-server";
144 my $var_run_tmpdir = "/var/run/qemu-server";
145 mkdir $var_run_tmpdir;
147 my $lock_dir = "/var/lock/qemu-server";
150 my $pcisysfs = "/sys/bus/pci";
156 description
=> "Specifies whether a VM will be started during system bootup.",
162 description
=> "Automatic restart after crash (currently ignored).",
168 description
=> "Activate hotplug for disk and network device",
174 description
=> "Allow reboot. If set to '0' the VM exit on reboot.",
180 description
=> "Lock/unlock the VM.",
181 enum
=> [qw(migrate backup snapshot rollback)],
186 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.",
193 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.",
201 description
=> "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.",
208 description
=> "Amount of target RAM for the VM in MB.",
214 description
=> "Keybord layout for vnc server. Default is read from the datacenter configuration file.",
215 enum
=> PVE
::Tools
::kvmkeymaplist
(),
220 type
=> 'string', format
=> 'dns-name',
221 description
=> "Set a name for the VM. Only used on the configuration web interface.",
226 description
=> "scsi controller model",
227 enum
=> [qw(lsi virtio-scsi-pci megasas)],
233 description
=> "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.",
238 enum
=> [qw(other wxp w2k w2k3 w2k8 wvista win7 win8 l24 l26)],
239 description
=> <<EODESC,
240 Used to enable special optimization/features for specific
243 other => unspecified OS
244 wxp => Microsoft Windows XP
245 w2k => Microsoft Windows 2000
246 w2k3 => Microsoft Windows 2003
247 w2k8 => Microsoft Windows 2008
248 wvista => Microsoft Windows Vista
249 win7 => Microsoft Windows 7
250 win8 => Microsoft Windows 8/2012
251 l24 => Linux 2.4 Kernel
252 l26 => Linux 2.6/3.X Kernel
254 other|l24|l26 ... no special behaviour
255 wxp|w2k|w2k3|w2k8|wvista|win7|win8 ... use --localtime switch
261 description
=> "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n).",
262 pattern
=> '[acdn]{1,4}',
267 type
=> 'string', format
=> 'pve-qm-bootdisk',
268 description
=> "Enable booting from specified disk.",
269 pattern
=> '(ide|sata|scsi|virtio)\d+',
274 description
=> "The number of CPUs. Please use option -sockets instead.",
281 description
=> "The number of CPU sockets.",
288 description
=> "The number of cores per socket.",
295 description
=> "Enable/disable ACPI.",
301 description
=> "Enable/disable Qemu GuestAgent.",
307 description
=> "Enable/disable KVM hardware virtualization.",
313 description
=> "Enable/disable time drift fix.",
319 description
=> "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
324 description
=> "Freeze CPU at startup (use 'c' monitor command to start execution).",
329 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",
330 enum
=> [qw(std cirrus vmware)],
334 type
=> 'string', format
=> 'pve-qm-watchdog',
335 typetext
=> '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
336 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)",
341 typetext
=> "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
342 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'.",
343 pattern
=> '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
348 type
=> 'string', format
=> 'pve-qm-startup',
349 typetext
=> '[[order=]\d+] [,up=\d+] [,down=\d+] ',
350 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.",
355 description
=> <<EODESCR,
356 Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
358 args: -no-reboot -no-hpet
365 description
=> "Enable/disable the usb tablet device. This device is usually needed to allow absolute mouse positioning. Else the mouse runs out of sync with normal vnc clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches.",
370 description
=> "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
374 migrate_downtime
=> {
377 description
=> "Set maximum tolerated downtime (in seconds) for migrations.",
383 type
=> 'string', format
=> 'pve-qm-drive',
384 typetext
=> 'volume',
385 description
=> "This is an alias for option -ide2",
389 description
=> "Emulated CPU type.",
391 enum
=> [ qw(486 athlon pentium pentium2 pentium3 coreduo core2duo kvm32 kvm64 qemu32 qemu64 phenom cpu64-rhel6 cpu64-rhel5 Conroe Penryn Nehalem Westmere Opteron_G1 Opteron_G2 Opteron_G3 host) ],
394 parent
=> get_standard_option
('pve-snapshot-name', {
396 description
=> "Parent snapshot name. This is used internally, and should not be modified.",
400 description
=> "Timestamp for snapshots.",
406 type
=> 'string', format
=> 'pve-volume-id',
407 description
=> "Reference to a volume which stores the VM state. This is used internally for snapshots.",
411 # what about other qemu settings ?
413 #machine => 'string',
426 ##soundhw => 'string',
428 while (my ($k, $v) = each %$confdesc) {
429 PVE
::JSONSchema
::register_standard_option
("pve-qm-$k", $v);
432 my $MAX_IDE_DISKS = 4;
433 my $MAX_SCSI_DISKS = 14;
434 my $MAX_VIRTIO_DISKS = 16;
435 my $MAX_SATA_DISKS = 6;
436 my $MAX_USB_DEVICES = 5;
438 my $MAX_UNUSED_DISKS = 8;
439 my $MAX_HOSTPCI_DEVICES = 2;
440 my $MAX_SERIAL_PORTS = 4;
441 my $MAX_PARALLEL_PORTS = 3;
443 my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
444 'ne2k_isa', 'i82551', 'i82557b', 'i82559er'];
445 my $nic_model_list_txt = join(' ', sort @$nic_model_list);
450 type
=> 'string', format
=> 'pve-qm-net',
451 typetext
=> "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,rate=<mbps>][,tag=<vlanid>]",
452 description
=> <<EODESCR,
453 Specify network devices.
455 MODEL is one of: $nic_model_list_txt
457 XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
458 automatically generated if not specified.
460 The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
462 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'.
464 If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
470 The DHCP server assign addresses to the guest starting from 10.0.2.15.
474 PVE
::JSONSchema
::register_standard_option
("pve-qm-net", $netdesc);
476 for (my $i = 0; $i < $MAX_NETS; $i++) {
477 $confdesc->{"net$i"} = $netdesc;
484 type
=> 'string', format
=> 'pve-qm-drive',
485 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]',
486 description
=> "Use volume as IDE hard disk or CD-ROM (n is 0 to " .($MAX_IDE_DISKS -1) . ").",
488 PVE
::JSONSchema
::register_standard_option
("pve-qm-ide", $idedesc);
492 type
=> 'string', format
=> 'pve-qm-drive',
493 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]',
494 description
=> "Use volume as SCSI hard disk or CD-ROM (n is 0 to " . ($MAX_SCSI_DISKS - 1) . ").",
496 PVE
::JSONSchema
::register_standard_option
("pve-qm-scsi", $scsidesc);
500 type
=> 'string', format
=> 'pve-qm-drive',
501 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]',
502 description
=> "Use volume as SATA hard disk or CD-ROM (n is 0 to " . ($MAX_SATA_DISKS - 1). ").",
504 PVE
::JSONSchema
::register_standard_option
("pve-qm-sata", $satadesc);
508 type
=> 'string', format
=> 'pve-qm-drive',
509 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]',
510 description
=> "Use volume as VIRTIO hard disk (n is 0 to " . ($MAX_VIRTIO_DISKS - 1) . ").",
512 PVE
::JSONSchema
::register_standard_option
("pve-qm-virtio", $virtiodesc);
516 type
=> 'string', format
=> 'pve-qm-usb-device',
517 typetext
=> 'host=HOSTUSBDEVICE',
518 description
=> <<EODESCR,
519 Configure an USB device (n is 0 to 4). This can be used to
520 pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
522 'bus-port(.port)*' (decimal numbers) or
523 'vendor_id:product_id' (hexadeciaml numbers)
525 You can use the 'lsusb -t' command to list existing usb devices.
527 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
531 PVE
::JSONSchema
::register_standard_option
("pve-qm-usb", $usbdesc);
535 type
=> 'string', format
=> 'pve-qm-hostpci',
536 typetext
=> "HOSTPCIDEVICE",
537 description
=> <<EODESCR,
538 Map host pci devices. HOSTPCIDEVICE syntax is:
540 'bus:dev.func' (hexadecimal numbers)
542 You can us the 'lspci' command to list existing pci devices.
544 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
546 Experimental: user reported problems with this option.
549 PVE
::JSONSchema
::register_standard_option
("pve-qm-hostpci", $hostpcidesc);
554 pattern
=> '/dev/ttyS\d+',
555 description
=> <<EODESCR,
556 Map host serial devices (n is 0 to 3).
558 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
560 Experimental: user reported problems with this option.
567 pattern
=> '/dev/parport\d+',
568 description
=> <<EODESCR,
569 Map host parallel devices (n is 0 to 2).
571 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
573 Experimental: user reported problems with this option.
577 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
578 $confdesc->{"parallel$i"} = $paralleldesc;
581 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
582 $confdesc->{"serial$i"} = $serialdesc;
585 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
586 $confdesc->{"hostpci$i"} = $hostpcidesc;
589 for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
590 $drivename_hash->{"ide$i"} = 1;
591 $confdesc->{"ide$i"} = $idedesc;
594 for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
595 $drivename_hash->{"sata$i"} = 1;
596 $confdesc->{"sata$i"} = $satadesc;
599 for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
600 $drivename_hash->{"scsi$i"} = 1;
601 $confdesc->{"scsi$i"} = $scsidesc ;
604 for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
605 $drivename_hash->{"virtio$i"} = 1;
606 $confdesc->{"virtio$i"} = $virtiodesc;
609 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
610 $confdesc->{"usb$i"} = $usbdesc;
615 type
=> 'string', format
=> 'pve-volume-id',
616 description
=> "Reference to unused volumes.",
619 for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
620 $confdesc->{"unused$i"} = $unuseddesc;
623 my $kvm_api_version = 0;
627 return $kvm_api_version if $kvm_api_version;
629 my $fh = IO
::File-
>new("</dev/kvm") ||
632 if (my $v = $fh->ioctl(KVM_GET_API_VERSION
(), 0)) {
633 $kvm_api_version = $v;
638 return $kvm_api_version;
641 my $kvm_user_version;
643 sub kvm_user_version
{
645 return $kvm_user_version if $kvm_user_version;
647 $kvm_user_version = 'unknown';
649 my $tmp = `kvm -help 2>/dev/null`;
651 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?) /) {
652 $kvm_user_version = $2;
655 return $kvm_user_version;
659 my $kernel_has_vhost_net = -c
'/dev/vhost-net';
662 # order is important - used to autoselect boot disk
663 return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
664 (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
665 (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
666 (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
669 sub valid_drivename
{
672 return defined($drivename_hash->{$dev});
677 return defined($confdesc->{$key});
681 return $nic_model_list;
684 sub os_list_description
{
689 w2k
=> 'Windows 2000',
690 w2k3
=>, 'Windows 2003',
691 w2k8
=> 'Windows 2008',
692 wvista
=> 'Windows Vista',
694 win8
=> 'Windows 8/2012',
704 return $cdrom_path if $cdrom_path;
706 return $cdrom_path = "/dev/cdrom" if -l
"/dev/cdrom";
707 return $cdrom_path = "/dev/cdrom1" if -l
"/dev/cdrom1";
708 return $cdrom_path = "/dev/cdrom2" if -l
"/dev/cdrom2";
712 my ($storecfg, $vmid, $cdrom) = @_;
714 if ($cdrom eq 'cdrom') {
715 return get_cdrom_path
();
716 } elsif ($cdrom eq 'none') {
718 } elsif ($cdrom =~ m
|^/|) {
721 return PVE
::Storage
::path
($storecfg, $cdrom);
725 # try to convert old style file names to volume IDs
726 sub filename_to_volume_id
{
727 my ($vmid, $file, $media) = @_;
729 if (!($file eq 'none' || $file eq 'cdrom' ||
730 $file =~ m
|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
732 return undef if $file =~ m
|/|;
734 if ($media && $media eq 'cdrom') {
735 $file = "local:iso/$file";
737 $file = "local:$vmid/$file";
744 sub verify_media_type
{
745 my ($opt, $vtype, $media) = @_;
750 if ($media eq 'disk') {
752 } elsif ($media eq 'cdrom') {
755 die "internal error";
758 return if ($vtype eq $etype);
760 raise_param_exc
({ $opt => "unexpected media type ($vtype != $etype)" });
763 sub cleanup_drive_path
{
764 my ($opt, $storecfg, $drive) = @_;
766 # try to convert filesystem paths to volume IDs
768 if (($drive->{file
} !~ m/^(cdrom|none)$/) &&
769 ($drive->{file
} !~ m
|^/dev/.+|) &&
770 ($drive->{file
} !~ m/^([^:]+):(.+)$/) &&
771 ($drive->{file
} !~ m/^\d+$/)) {
772 my ($vtype, $volid) = PVE
::Storage
::path_to_volume_id
($storecfg, $drive->{file
});
773 raise_param_exc
({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
774 $drive->{media
} = 'cdrom' if !$drive->{media
} && $vtype eq 'iso';
775 verify_media_type
($opt, $vtype, $drive->{media
});
776 $drive->{file
} = $volid;
779 $drive->{media
} = 'cdrom' if !$drive->{media
} && $drive->{file
} =~ m/^(cdrom|none)$/;
782 sub create_conf_nolock
{
783 my ($vmid, $settings) = @_;
785 my $filename = config_file
($vmid);
787 die "configuration file '$filename' already exists\n" if -f
$filename;
789 my $defaults = load_defaults
();
791 $settings->{name
} = "vm$vmid" if !$settings->{name
};
792 $settings->{memory
} = $defaults->{memory
} if !$settings->{memory
};
795 foreach my $opt (keys %$settings) {
796 next if !$confdesc->{$opt};
798 my $value = $settings->{$opt};
801 $data .= "$opt: $value\n";
804 PVE
::Tools
::file_set_contents
($filename, $data);
807 my $parse_size = sub {
810 return undef if $value !~ m/^(\d+(\.\d+)?)([KMG])?$/;
811 my ($size, $unit) = ($1, $3);
814 $size = $size * 1024;
815 } elsif ($unit eq 'M') {
816 $size = $size * 1024 * 1024;
817 } elsif ($unit eq 'G') {
818 $size = $size * 1024 * 1024 * 1024;
824 my $format_size = sub {
829 my $kb = int($size/1024);
830 return $size if $kb*1024 != $size;
832 my $mb = int($kb/1024);
833 return "${kb}K" if $mb*1024 != $kb;
835 my $gb = int($mb/1024);
836 return "${mb}M" if $gb*1024 != $mb;
841 # ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
842 # [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
843 # [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
844 # [,aio=native|threads]
847 my ($key, $data) = @_;
851 # $key may be undefined - used to verify JSON parameters
852 if (!defined($key)) {
853 $res->{interface
} = 'unknown'; # should not harm when used to verify parameters
855 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
856 $res->{interface
} = $1;
862 foreach my $p (split (/,/, $data)) {
863 next if $p =~ m/^\s*$/;
865 if ($p =~ m/^(file|volume|cyls|heads|secs|trans|media|snapshot|cache|format|rerror|werror|backup|aio|bps|mbps|bps_rd|mbps_rd|bps_wr|mbps_wr|iops|iops_rd|iops_wr|size)=(.+)$/) {
866 my ($k, $v) = ($1, $2);
868 $k = 'file' if $k eq 'volume';
870 return undef if defined $res->{$k};
872 if ($k eq 'bps' || $k eq 'bps_rd' || $k eq 'bps_wr') {
873 return undef if !$v || $v !~ m/^\d+/;
875 $v = sprintf("%.3f", $v / (1024*1024));
879 if (!$res->{file
} && $p !~ m/=/) {
887 return undef if !$res->{file
};
889 return undef if $res->{cache
} &&
890 $res->{cache
} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
891 return undef if $res->{snapshot
} && $res->{snapshot
} !~ m/^(on|off)$/;
892 return undef if $res->{cyls
} && $res->{cyls
} !~ m/^\d+$/;
893 return undef if $res->{heads
} && $res->{heads
} !~ m/^\d+$/;
894 return undef if $res->{secs
} && $res->{secs
} !~ m/^\d+$/;
895 return undef if $res->{media
} && $res->{media
} !~ m/^(disk|cdrom)$/;
896 return undef if $res->{trans
} && $res->{trans
} !~ m/^(none|lba|auto)$/;
897 return undef if $res->{format
} && $res->{format
} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
898 return undef if $res->{rerror
} && $res->{rerror
} !~ m/^(ignore|report|stop)$/;
899 return undef if $res->{werror
} && $res->{werror
} !~ m/^(enospc|ignore|report|stop)$/;
900 return undef if $res->{backup
} && $res->{backup
} !~ m/^(yes|no)$/;
901 return undef if $res->{aio
} && $res->{aio
} !~ m/^(native|threads)$/;
904 return undef if $res->{mbps_rd
} && $res->{mbps
};
905 return undef if $res->{mbps_wr
} && $res->{mbps
};
907 return undef if $res->{mbps
} && $res->{mbps
} !~ m/^\d+(\.\d+)?$/;
908 return undef if $res->{mbps_rd
} && $res->{mbps_rd
} !~ m/^\d+(\.\d+)?$/;
909 return undef if $res->{mbps_wr
} && $res->{mbps_wr
} !~ m/^\d+(\.\d+)?$/;
911 return undef if $res->{iops_rd
} && $res->{iops
};
912 return undef if $res->{iops_wr
} && $res->{iops
};
913 return undef if $res->{iops
} && $res->{iops
} !~ m/^\d+$/;
914 return undef if $res->{iops_rd
} && $res->{iops_rd
} !~ m/^\d+$/;
915 return undef if $res->{iops_wr
} && $res->{iops_wr
} !~ m/^\d+$/;
919 return undef if !defined($res->{size
} = &$parse_size($res->{size
}));
922 if ($res->{media
} && ($res->{media
} eq 'cdrom')) {
923 return undef if $res->{snapshot
} || $res->{trans
} || $res->{format
};
924 return undef if $res->{heads
} || $res->{secs
} || $res->{cyls
};
925 return undef if $res->{interface
} eq 'virtio';
928 # rerror does not work with scsi drives
929 if ($res->{rerror
}) {
930 return undef if $res->{interface
} eq 'scsi';
936 my @qemu_drive_options = qw(heads secs cyls trans media format cache snapshot rerror werror aio iops iops_rd iops_wr);
939 my ($vmid, $drive) = @_;
942 foreach my $o (@qemu_drive_options, 'mbps', 'mbps_rd', 'mbps_wr', 'backup') {
943 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
946 if ($drive->{size
}) {
947 $opts .= ",size=" . &$format_size($drive->{size
});
950 return "$drive->{file}$opts";
954 my($fh, $noerr) = @_;
957 my $SG_GET_VERSION_NUM = 0x2282;
959 my $versionbuf = "\x00" x
8;
960 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
962 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
965 my $version = unpack("I", $versionbuf);
966 if ($version < 30000) {
967 die "scsi generic interface too old\n" if !$noerr;
971 my $buf = "\x00" x
36;
972 my $sensebuf = "\x00" x
8;
973 my $cmd = pack("C x3 C x11", 0x12, 36);
975 # see /usr/include/scsi/sg.h
976 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";
978 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
979 length($sensebuf), 0, length($buf), $buf,
980 $cmd, $sensebuf, 6000);
982 $ret = ioctl($fh, $SG_IO, $packet);
984 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
988 my @res = unpack($sg_io_hdr_t, $packet);
989 if ($res[17] || $res[18]) {
990 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
995 ($res->{device
}, $res->{removable
}, $res->{venodor
},
996 $res->{product
}, $res->{revision
}) = unpack("C C x6 A8 A16 A4", $buf);
1004 my $fh = IO
::File-
>new("+<$path") || return undef;
1005 my $res = scsi_inquiry
($fh, 1);
1011 sub print_drivedevice_full
{
1012 my ($storecfg, $conf, $vmid, $drive, $bridges) = @_;
1017 if ($drive->{interface
} eq 'virtio') {
1018 my $pciaddr = print_pci_addr
("$drive->{interface}$drive->{index}", $bridges);
1019 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
1020 } elsif ($drive->{interface
} eq 'scsi') {
1021 $maxdev = ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi') ?
256 : 7;
1022 my $controller = int($drive->{index} / $maxdev);
1023 my $unit = $drive->{index} % $maxdev;
1024 my $devicetype = 'hd';
1026 if (drive_is_cdrom
($drive)) {
1029 if ($drive->{file
} =~ m
|^/|) {
1030 $path = $drive->{file
};
1032 $path = PVE
::Storage
::path
($storecfg, $drive->{file
});
1035 if($path =~ m/^iscsi\:\/\
//){
1036 $devicetype = 'generic';
1039 $devicetype = 'block' if path_is_scsi
($path);
1043 if (!$conf->{scsihw
} || $conf->{scsihw
} eq 'lsi'){
1044 $device = "scsi-$devicetype,bus=scsihw$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}" if !$conf->{scsihw
} || $conf->{scsihw
} eq 'lsi';
1046 $device = "scsi-$devicetype,bus=scsihw$controller.0,channel=0,scsi-id=0,lun=$drive->{index},drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1049 } elsif ($drive->{interface
} eq 'ide'){
1051 my $controller = int($drive->{index} / $maxdev);
1052 my $unit = $drive->{index} % $maxdev;
1053 my $devicetype = ($drive->{media
} && $drive->{media
} eq 'cdrom') ?
"cd" : "hd";
1055 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1056 } elsif ($drive->{interface
} eq 'sata'){
1057 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
1058 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1059 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1060 } elsif ($drive->{interface
} eq 'usb') {
1062 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1064 die "unsupported interface type";
1067 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex
};
1072 sub print_drive_full
{
1073 my ($storecfg, $vmid, $drive) = @_;
1076 foreach my $o (@qemu_drive_options) {
1077 next if $o eq 'bootindex';
1078 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
1081 foreach my $o (qw(bps bps_rd bps_wr)) {
1082 my $v = $drive->{"m$o"};
1083 $opts .= ",$o=" . int($v*1024*1024) if $v;
1086 # use linux-aio by default (qemu default is threads)
1087 $opts .= ",aio=native" if !$drive->{aio
};
1090 my $volid = $drive->{file
};
1091 if (drive_is_cdrom
($drive)) {
1092 $path = get_iso_path
($storecfg, $vmid, $volid);
1094 if ($volid =~ m
|^/|) {
1097 $path = PVE
::Storage
::path
($storecfg, $volid);
1099 if (!$drive->{cache
} && ($path =~ m
|^/dev/| || $path =~ m
|\
.raw
$|)) {
1100 $opts .= ",cache=none";
1104 my $pathinfo = $path ?
"file=$path," : '';
1106 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1109 sub print_netdevice_full
{
1110 my ($vmid, $conf, $net, $netid, $bridges) = @_;
1112 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
1114 my $device = $net->{model
};
1115 if ($net->{model
} eq 'virtio') {
1116 $device = 'virtio-net-pci';
1119 # qemu > 0.15 always try to boot from network - we disable that by
1120 # not loading the pxe rom file
1121 my $extra = ($bootorder !~ m/n/) ?
"romfile=," : '';
1122 my $pciaddr = print_pci_addr
("$netid", $bridges);
1123 my $tmpstr = "$device,${extra}mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
1124 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex
} ;
1128 sub print_netdev_full
{
1129 my ($vmid, $conf, $net, $netid) = @_;
1132 if ($netid =~ m/^net(\d+)$/) {
1136 die "got strange net id '$i'\n" if $i >= ${MAX_NETS
};
1138 my $ifname = "tap${vmid}i$i";
1140 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1141 die "interface name '$ifname' is too long (max 15 character)\n"
1142 if length($ifname) >= 16;
1144 my $vhostparam = '';
1145 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model
} eq 'virtio';
1147 my $vmname = $conf->{name
} || "vm$vmid";
1149 if ($net->{bridge
}) {
1150 return "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge$vhostparam";
1152 return "type=user,id=$netid,hostname=$vmname";
1156 sub drive_is_cdrom
{
1159 return $drive && $drive->{media
} && ($drive->{media
} eq 'cdrom');
1166 return undef if !$value;
1170 if ($value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/) {
1171 $res->{pciid
} = $value;
1179 # netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1185 foreach my $kvp (split(/,/, $data)) {
1187 if ($kvp =~ m/^(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
1189 my $mac = uc($3) || PVE
::Tools
::random_ether_addr
();
1190 $res->{model
} = $model;
1191 $res->{macaddr
} = $mac;
1192 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1193 $res->{bridge
} = $1;
1194 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1196 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1204 return undef if !$res->{model
};
1212 my $res = "$net->{model}";
1213 $res .= "=$net->{macaddr}" if $net->{macaddr
};
1214 $res .= ",bridge=$net->{bridge}" if $net->{bridge
};
1215 $res .= ",rate=$net->{rate}" if $net->{rate
};
1216 $res .= ",tag=$net->{tag}" if $net->{tag
};
1221 sub add_random_macs
{
1222 my ($settings) = @_;
1224 foreach my $opt (keys %$settings) {
1225 next if $opt !~ m/^net(\d+)$/;
1226 my $net = parse_net
($settings->{$opt});
1228 $settings->{$opt} = print_net
($net);
1232 sub add_unused_volume
{
1233 my ($config, $volid) = @_;
1236 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1237 my $test = "unused$ind";
1238 if (my $vid = $config->{$test}) {
1239 return if $vid eq $volid; # do not add duplicates
1245 die "To many unused volume - please delete them first.\n" if !$key;
1247 $config->{$key} = $volid;
1252 # fixme: remove all thos $noerr parameters?
1254 PVE
::JSONSchema
::register_format
('pve-qm-bootdisk', \
&verify_bootdisk
);
1255 sub verify_bootdisk
{
1256 my ($value, $noerr) = @_;
1258 return $value if valid_drivename
($value);
1260 return undef if $noerr;
1262 die "invalid boot disk '$value'\n";
1265 PVE
::JSONSchema
::register_format
('pve-qm-net', \
&verify_net
);
1267 my ($value, $noerr) = @_;
1269 return $value if parse_net
($value);
1271 return undef if $noerr;
1273 die "unable to parse network options\n";
1276 PVE
::JSONSchema
::register_format
('pve-qm-drive', \
&verify_drive
);
1278 my ($value, $noerr) = @_;
1280 return $value if parse_drive
(undef, $value);
1282 return undef if $noerr;
1284 die "unable to parse drive options\n";
1287 PVE
::JSONSchema
::register_format
('pve-qm-hostpci', \
&verify_hostpci
);
1288 sub verify_hostpci
{
1289 my ($value, $noerr) = @_;
1291 return $value if parse_hostpci
($value);
1293 return undef if $noerr;
1295 die "unable to parse pci id\n";
1298 PVE
::JSONSchema
::register_format
('pve-qm-watchdog', \
&verify_watchdog
);
1299 sub verify_watchdog
{
1300 my ($value, $noerr) = @_;
1302 return $value if parse_watchdog
($value);
1304 return undef if $noerr;
1306 die "unable to parse watchdog options\n";
1309 sub parse_watchdog
{
1312 return undef if !$value;
1316 foreach my $p (split(/,/, $value)) {
1317 next if $p =~ m/^\s*$/;
1319 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1321 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1322 $res->{action
} = $2;
1331 PVE
::JSONSchema
::register_format
('pve-qm-startup', \
&verify_startup
);
1332 sub verify_startup
{
1333 my ($value, $noerr) = @_;
1335 return $value if parse_startup
($value);
1337 return undef if $noerr;
1339 die "unable to parse startup options\n";
1345 return undef if !$value;
1349 foreach my $p (split(/,/, $value)) {
1350 next if $p =~ m/^\s*$/;
1352 if ($p =~ m/^(order=)?(\d+)$/) {
1354 } elsif ($p =~ m/^up=(\d+)$/) {
1356 } elsif ($p =~ m/^down=(\d+)$/) {
1366 sub parse_usb_device
{
1369 return undef if !$value;
1371 my @dl = split(/,/, $value);
1375 foreach my $v (@dl) {
1376 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1378 $res->{vendorid
} = $2;
1379 $res->{productid
} = $4;
1380 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1382 $res->{hostbus
} = $1;
1383 $res->{hostport
} = $2;
1388 return undef if !$found;
1393 PVE
::JSONSchema
::register_format
('pve-qm-usb-device', \
&verify_usb_device
);
1394 sub verify_usb_device
{
1395 my ($value, $noerr) = @_;
1397 return $value if parse_usb_device
($value);
1399 return undef if $noerr;
1401 die "unable to parse usb device\n";
1404 # add JSON properties for create and set function
1405 sub json_config_properties
{
1408 foreach my $opt (keys %$confdesc) {
1409 next if $opt eq 'parent' || $opt eq 'snaptime' || $opt eq 'vmstate';
1410 $prop->{$opt} = $confdesc->{$opt};
1417 my ($key, $value) = @_;
1419 die "unknown setting '$key'\n" if !$confdesc->{$key};
1421 my $type = $confdesc->{$key}->{type
};
1423 if (!defined($value)) {
1424 die "got undefined value\n";
1427 if ($value =~ m/[\n\r]/) {
1428 die "property contains a line feed\n";
1431 if ($type eq 'boolean') {
1432 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1433 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1434 die "type check ('boolean') failed - got '$value'\n";
1435 } elsif ($type eq 'integer') {
1436 return int($1) if $value =~ m/^(\d+)$/;
1437 die "type check ('integer') failed - got '$value'\n";
1438 } elsif ($type eq 'string') {
1439 if (my $fmt = $confdesc->{$key}->{format
}) {
1440 if ($fmt eq 'pve-qm-drive') {
1441 # special case - we need to pass $key to parse_drive()
1442 my $drive = parse_drive
($key, $value);
1443 return $value if $drive;
1444 die "unable to parse drive options\n";
1446 PVE
::JSONSchema
::check_format
($fmt, $value);
1449 $value =~ s/^\"(.*)\"$/$1/;
1452 die "internal error"
1456 sub lock_config_full
{
1457 my ($vmid, $timeout, $code, @param) = @_;
1459 my $filename = config_file_lock
($vmid);
1461 my $res = lock_file
($filename, $timeout, $code, @param);
1469 my ($vmid, $code, @param) = @_;
1471 return lock_config_full
($vmid, 10, $code, @param);
1474 sub cfs_config_path
{
1475 my ($vmid, $node) = @_;
1477 $node = $nodename if !$node;
1478 return "nodes/$node/qemu-server/$vmid.conf";
1481 sub check_iommu_support
{
1482 #fixme : need to check IOMMU support
1483 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1491 my ($vmid, $node) = @_;
1493 my $cfspath = cfs_config_path
($vmid, $node);
1494 return "/etc/pve/$cfspath";
1497 sub config_file_lock
{
1500 return "$lock_dir/lock-$vmid.conf";
1506 my $conf = config_file
($vmid);
1507 utime undef, undef, $conf;
1511 my ($storecfg, $vmid, $keep_empty_config) = @_;
1513 my $conffile = config_file
($vmid);
1515 my $conf = load_config
($vmid);
1519 # only remove disks owned by this VM
1520 foreach_drive
($conf, sub {
1521 my ($ds, $drive) = @_;
1523 return if drive_is_cdrom
($drive);
1525 my $volid = $drive->{file
};
1526 return if !$volid || $volid =~ m
|^/|;
1528 my ($path, $owner) = PVE
::Storage
::path
($storecfg, $volid);
1529 return if !$path || !$owner || ($owner != $vmid);
1531 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1534 if ($keep_empty_config) {
1535 PVE
::Tools
::file_set_contents
($conffile, "memory: 128\n");
1540 # also remove unused disk
1542 my $dl = PVE
::Storage
::vdisk_list
($storecfg, undef, $vmid);
1545 PVE
::Storage
::foreach_volid
($dl, sub {
1546 my ($volid, $sid, $volname, $d) = @_;
1547 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1557 my ($vmid, $node) = @_;
1559 my $cfspath = cfs_config_path
($vmid, $node);
1561 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath);
1563 die "no such VM ('$vmid')\n" if !defined($conf);
1568 sub parse_vm_config
{
1569 my ($filename, $raw) = @_;
1571 return undef if !defined($raw);
1574 digest
=> Digest
::SHA
::sha1_hex
($raw),
1578 $filename =~ m
|/qemu-server/(\d
+)\
.conf
$|
1579 || die "got strange filename '$filename'";
1586 my @lines = split(/\n/, $raw);
1587 foreach my $line (@lines) {
1588 next if $line =~ m/^\s*$/;
1590 if ($line =~ m/^\[([a-z][a-z0-9_\-]+)\]\s*$/i) {
1592 $conf->{description
} = $descr if $descr;
1594 $conf = $res->{snapshots
}->{$snapname} = {};
1598 if ($line =~ m/^\#(.*)\s*$/) {
1599 $descr .= PVE
::Tools
::decode_text
($1) . "\n";
1603 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
1604 $descr .= PVE
::Tools
::decode_text
($2);
1605 } elsif ($line =~ m/snapstate:\s*(prepare|delete)\s*$/) {
1606 $conf->{snapstate
} = $1;
1607 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1610 $conf->{$key} = $value;
1611 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1614 eval { $value = check_type
($key, $value); };
1616 warn "vm $vmid - unable to parse value of '$key' - $@";
1618 my $fmt = $confdesc->{$key}->{format
};
1619 if ($fmt && $fmt eq 'pve-qm-drive') {
1620 my $v = parse_drive
($key, $value);
1621 if (my $volid = filename_to_volume_id
($vmid, $v->{file
}, $v->{media
})) {
1622 $v->{file
} = $volid;
1623 $value = print_drive
($vmid, $v);
1625 warn "vm $vmid - unable to parse value of '$key'\n";
1630 if ($key eq 'cdrom') {
1631 $conf->{ide2
} = $value;
1633 $conf->{$key} = $value;
1639 $conf->{description
} = $descr if $descr;
1641 delete $res->{snapstate
}; # just to be sure
1646 sub write_vm_config
{
1647 my ($filename, $conf) = @_;
1649 delete $conf->{snapstate
}; # just to be sure
1651 if ($conf->{cdrom
}) {
1652 die "option ide2 conflicts with cdrom\n" if $conf->{ide2
};
1653 $conf->{ide2
} = $conf->{cdrom
};
1654 delete $conf->{cdrom
};
1657 # we do not use 'smp' any longer
1658 if ($conf->{sockets
}) {
1659 delete $conf->{smp
};
1660 } elsif ($conf->{smp
}) {
1661 $conf->{sockets
} = $conf->{smp
};
1662 delete $conf->{cores
};
1663 delete $conf->{smp
};
1666 my $used_volids = {};
1668 my $cleanup_config = sub {
1671 foreach my $key (keys %$cref) {
1672 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots' ||
1673 $key eq 'snapstate';
1674 my $value = $cref->{$key};
1675 eval { $value = check_type
($key, $value); };
1676 die "unable to parse value of '$key' - $@" if $@;
1678 $cref->{$key} = $value;
1680 if (valid_drivename
($key)) {
1681 my $drive = PVE
::QemuServer
::parse_drive
($key, $value);
1682 $used_volids->{$drive->{file
}} = 1 if $drive && $drive->{file
};
1687 &$cleanup_config($conf);
1688 foreach my $snapname (keys %{$conf->{snapshots
}}) {
1689 &$cleanup_config($conf->{snapshots
}->{$snapname});
1692 # remove 'unusedX' settings if we re-add a volume
1693 foreach my $key (keys %$conf) {
1694 my $value = $conf->{$key};
1695 if ($key =~ m/^unused/ && $used_volids->{$value}) {
1696 delete $conf->{$key};
1700 my $generate_raw_config = sub {
1705 # add description as comment to top of file
1706 my $descr = $conf->{description
} || '';
1707 foreach my $cl (split(/\n/, $descr)) {
1708 $raw .= '#' . PVE
::Tools
::encode_text
($cl) . "\n";
1711 foreach my $key (sort keys %$conf) {
1712 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots';
1713 $raw .= "$key: $conf->{$key}\n";
1718 my $raw = &$generate_raw_config($conf);
1719 foreach my $snapname (sort keys %{$conf->{snapshots
}}) {
1720 $raw .= "\n[$snapname]\n";
1721 $raw .= &$generate_raw_config($conf->{snapshots
}->{$snapname});
1727 sub update_config_nolock
{
1728 my ($vmid, $conf, $skiplock) = @_;
1730 check_lock
($conf) if !$skiplock;
1732 my $cfspath = cfs_config_path
($vmid);
1734 PVE
::Cluster
::cfs_write_file
($cfspath, $conf);
1738 my ($vmid, $conf, $skiplock) = @_;
1740 lock_config
($vmid, &update_config_nolock
, $conf, $skiplock);
1747 # we use static defaults from our JSON schema configuration
1748 foreach my $key (keys %$confdesc) {
1749 if (defined(my $default = $confdesc->{$key}->{default})) {
1750 $res->{$key} = $default;
1754 my $conf = PVE
::Cluster
::cfs_read_file
('datacenter.cfg');
1755 $res->{keyboard
} = $conf->{keyboard
} if $conf->{keyboard
};
1761 my $vmlist = PVE
::Cluster
::get_vmlist
();
1763 return $res if !$vmlist || !$vmlist->{ids
};
1764 my $ids = $vmlist->{ids
};
1766 foreach my $vmid (keys %$ids) {
1767 my $d = $ids->{$vmid};
1768 next if !$d->{node
} || $d->{node
} ne $nodename;
1769 next if !$d->{type
} || $d->{type
} ne 'qemu';
1770 $res->{$vmid}->{exists} = 1;
1775 # test if VM uses local resources (to prevent migration)
1776 sub check_local_resources
{
1777 my ($conf, $noerr) = @_;
1781 $loc_res = 1 if $conf->{hostusb
}; # old syntax
1782 $loc_res = 1 if $conf->{hostpci
}; # old syntax
1784 foreach my $k (keys %$conf) {
1785 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
1788 die "VM uses local resources\n" if $loc_res && !$noerr;
1793 # check is used storages are available on all nodes (use by migrate)
1794 sub check_storage_availability
{
1795 my ($storecfg, $conf, $node) = @_;
1797 foreach_drive
($conf, sub {
1798 my ($ds, $drive) = @_;
1800 my $volid = $drive->{file
};
1803 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
1806 # check if storage is available on both nodes
1807 my $scfg = PVE
::Storage
::storage_check_node
($storecfg, $sid);
1808 PVE
::Storage
::storage_check_node
($storecfg, $sid, $node);
1815 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1819 my ($pidfile, $pid) = @_;
1821 my $fh = IO
::File-
>new("/proc/$pid/cmdline", "r");
1825 return undef if !$line;
1826 my @param = split(/\0/, $line);
1828 my $cmd = $param[0];
1829 return if !$cmd || ($cmd !~ m
|kvm
$|);
1831 for (my $i = 0; $i < scalar (@param); $i++) {
1834 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1835 my $p = $param[$i+1];
1836 return 1 if $p && ($p eq $pidfile);
1845 my ($vmid, $nocheck, $node) = @_;
1847 my $filename = config_file
($vmid, $node);
1849 die "unable to find configuration file for VM $vmid - no such machine\n"
1850 if !$nocheck && ! -f
$filename;
1852 my $pidfile = pidfile_name
($vmid);
1854 if (my $fd = IO
::File-
>new("<$pidfile")) {
1859 my $mtime = $st->mtime;
1860 if ($mtime > time()) {
1861 warn "file '$filename' modified in future\n";
1864 if ($line =~ m/^(\d+)$/) {
1866 if (check_cmdline
($pidfile, $pid)) {
1867 if (my $pinfo = PVE
::ProcFSTools
::check_process_running
($pid)) {
1879 my $vzlist = config_list
();
1881 my $fd = IO
::Dir-
>new($var_run_tmpdir) || return $vzlist;
1883 while (defined(my $de = $fd->read)) {
1884 next if $de !~ m/^(\d+)\.pid$/;
1886 next if !defined($vzlist->{$vmid});
1887 if (my $pid = check_running
($vmid)) {
1888 $vzlist->{$vmid}->{pid
} = $pid;
1896 my ($storecfg, $conf) = @_;
1898 my $bootdisk = $conf->{bootdisk
};
1899 return undef if !$bootdisk;
1900 return undef if !valid_drivename
($bootdisk);
1902 return undef if !$conf->{$bootdisk};
1904 my $drive = parse_drive
($bootdisk, $conf->{$bootdisk});
1905 return undef if !defined($drive);
1907 return undef if drive_is_cdrom
($drive);
1909 my $volid = $drive->{file
};
1910 return undef if !$volid;
1912 return $drive->{size
};
1915 my $last_proc_pid_stat;
1917 # get VM status information
1918 # This must be fast and should not block ($full == false)
1919 # We only query KVM using QMP if $full == true (this can be slow)
1921 my ($opt_vmid, $full) = @_;
1925 my $storecfg = PVE
::Storage
::config
();
1927 my $list = vzlist
();
1928 my ($uptime) = PVE
::ProcFSTools
::read_proc_uptime
(1);
1930 my $cpucount = $cpuinfo->{cpus
} || 1;
1932 foreach my $vmid (keys %$list) {
1933 next if $opt_vmid && ($vmid ne $opt_vmid);
1935 my $cfspath = cfs_config_path
($vmid);
1936 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath) || {};
1939 $d->{pid
} = $list->{$vmid}->{pid
};
1941 # fixme: better status?
1942 $d->{status
} = $list->{$vmid}->{pid
} ?
'running' : 'stopped';
1944 my $size = disksize
($storecfg, $conf);
1945 if (defined($size)) {
1946 $d->{disk
} = 0; # no info available
1947 $d->{maxdisk
} = $size;
1953 $d->{cpus
} = ($conf->{sockets
} || 1) * ($conf->{cores
} || 1);
1954 $d->{cpus
} = $cpucount if $d->{cpus
} > $cpucount;
1956 $d->{name
} = $conf->{name
} || "VM $vmid";
1957 $d->{maxmem
} = $conf->{memory
} ?
$conf->{memory
}*(1024*1024) : 0;
1967 $d->{diskwrite
} = 0;
1972 my $netdev = PVE
::ProcFSTools
::read_proc_net_dev
();
1973 foreach my $dev (keys %$netdev) {
1974 next if $dev !~ m/^tap([1-9]\d*)i/;
1976 my $d = $res->{$vmid};
1979 $d->{netout
} += $netdev->{$dev}->{receive
};
1980 $d->{netin
} += $netdev->{$dev}->{transmit
};
1983 my $ctime = gettimeofday
;
1985 foreach my $vmid (keys %$list) {
1987 my $d = $res->{$vmid};
1988 my $pid = $d->{pid
};
1991 my $pstat = PVE
::ProcFSTools
::read_proc_pid_stat
($pid);
1992 next if !$pstat; # not running
1994 my $used = $pstat->{utime} + $pstat->{stime
};
1996 $d->{uptime
} = int(($uptime - $pstat->{starttime
})/$cpuinfo->{user_hz
});
1998 if ($pstat->{vsize
}) {
1999 $d->{mem
} = int(($pstat->{rss
}/$pstat->{vsize
})*$d->{maxmem
});
2002 my $old = $last_proc_pid_stat->{$pid};
2004 $last_proc_pid_stat->{$pid} = {
2012 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz
};
2014 if ($dtime > 1000) {
2015 my $dutime = $used - $old->{used
};
2017 $d->{cpu
} = (($dutime/$dtime)* $cpucount) / $d->{cpus
};
2018 $last_proc_pid_stat->{$pid} = {
2024 $d->{cpu
} = $old->{cpu
};
2028 return $res if !$full;
2030 my $qmpclient = PVE
::QMPClient-
>new();
2032 my $blockstatscb = sub {
2033 my ($vmid, $resp) = @_;
2034 my $data = $resp->{'return'} || [];
2035 my $totalrdbytes = 0;
2036 my $totalwrbytes = 0;
2037 for my $blockstat (@$data) {
2038 $totalrdbytes = $totalrdbytes + $blockstat->{stats
}->{rd_bytes
};
2039 $totalwrbytes = $totalwrbytes + $blockstat->{stats
}->{wr_bytes
};
2041 $res->{$vmid}->{diskread
} = $totalrdbytes;
2042 $res->{$vmid}->{diskwrite
} = $totalwrbytes;
2045 my $statuscb = sub {
2046 my ($vmid, $resp) = @_;
2047 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
2049 my $status = 'unknown';
2050 if (!defined($status = $resp->{'return'}->{status
})) {
2051 warn "unable to get VM status\n";
2055 $res->{$vmid}->{qmpstatus
} = $resp->{'return'}->{status
};
2058 foreach my $vmid (keys %$list) {
2059 next if $opt_vmid && ($vmid ne $opt_vmid);
2060 next if !$res->{$vmid}->{pid
}; # not running
2061 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2064 $qmpclient->queue_execute();
2066 foreach my $vmid (keys %$list) {
2067 next if $opt_vmid && ($vmid ne $opt_vmid);
2068 $res->{$vmid}->{qmpstatus
} = $res->{$vmid}->{status
} if !$res->{$vmid}->{qmpstatus
};
2075 my ($conf, $func) = @_;
2077 foreach my $ds (keys %$conf) {
2078 next if !valid_drivename
($ds);
2080 my $drive = parse_drive
($ds, $conf->{$ds});
2083 &$func($ds, $drive);
2088 my ($conf, $func) = @_;
2092 my $test_volid = sub {
2093 my ($volid, $is_cdrom) = @_;
2097 $volhash->{$volid} = $is_cdrom || 0;
2100 PVE
::QemuServer
::foreach_drive
($conf, sub {
2101 my ($ds, $drive) = @_;
2102 &$test_volid($drive->{file
}, drive_is_cdrom
($drive));
2105 foreach my $snapname (keys %{$conf->{snapshots
}}) {
2106 my $snap = $conf->{snapshots
}->{$snapname};
2107 &$test_volid($snap->{vmstate
}, 0);
2108 PVE
::QemuServer
::foreach_drive
($snap, sub {
2109 my ($ds, $drive) = @_;
2110 &$test_volid($drive->{file
}, drive_is_cdrom
($drive));
2114 foreach my $volid (keys %$volhash) {
2115 &$func($volid, $volhash->{$volid});
2119 sub config_to_command
{
2120 my ($storecfg, $vmid, $conf, $defaults) = @_;
2123 my $globalFlags = [];
2124 my $machineFlags = [];
2129 my $kvmver = kvm_user_version
();
2130 my $vernum = 0; # unknown
2131 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2132 $vernum = $1*1000000+$2*1000;
2133 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
2134 $vernum = $1*1000000+$2*1000+$3;
2137 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
2139 my $have_ovz = -f
'/proc/vz/vestat';
2141 push @$cmd, '/usr/bin/kvm';
2143 push @$cmd, '-id', $vmid;
2147 my $qmpsocket = qmp_socket
($vmid);
2148 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2149 push @$cmd, '-mon', "chardev=qmp,mode=control";
2151 my $socket = vnc_socket
($vmid);
2152 push @$cmd, '-vnc', "unix:$socket,x509,password";
2154 push @$cmd, '-pidfile' , pidfile_name
($vmid);
2156 push @$cmd, '-daemonize';
2159 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2160 next if !$conf->{"usb$i"};
2163 # include usb device config
2164 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
2166 # enable absolute mouse coordinates (needed by vnc)
2167 my $tablet = defined($conf->{tablet
}) ?
$conf->{tablet
} : $defaults->{tablet
};
2170 push @$devices, '-device', 'usb-tablet,bus=ehci.0,port=6';
2172 push @$devices, '-usbdevice', 'tablet';
2177 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2178 my $d = parse_hostpci
($conf->{"hostpci$i"});
2180 $pciaddr = print_pci_addr
("hostpci$i", $bridges);
2181 push @$devices, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
2185 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2186 my $d = parse_usb_device
($conf->{"usb$i"});
2188 if ($d->{vendorid
} && $d->{productid
}) {
2189 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
2190 } elsif (defined($d->{hostbus
}) && defined($d->{hostport
})) {
2191 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
2196 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
2197 if (my $path = $conf->{"serial$i"}) {
2198 die "no such serial device\n" if ! -c
$path;
2199 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2200 push @$devices, '-device', "isa-serial,chardev=serial$i";
2205 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
2206 if (my $path = $conf->{"parallel$i"}) {
2207 die "no such parallel device\n" if ! -c
$path;
2208 push @$devices, '-chardev', "parport,id=parallel$i,path=$path";
2209 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
2213 my $vmname = $conf->{name
} || "vm$vmid";
2215 push @$cmd, '-name', $vmname;
2218 $sockets = $conf->{smp
} if $conf->{smp
}; # old style - no longer iused
2219 $sockets = $conf->{sockets
} if $conf->{sockets
};
2221 my $cores = $conf->{cores
} || 1;
2223 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2225 push @$cmd, '-cpu', $conf->{cpu
} if $conf->{cpu
};
2227 push @$cmd, '-nodefaults';
2229 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
2231 my $bootindex_hash = {};
2233 foreach my $o (split(//, $bootorder)) {
2234 $bootindex_hash->{$o} = $i*100;
2238 push @$cmd, '-boot', "menu=on";
2240 push @$cmd, '-no-acpi' if defined($conf->{acpi
}) && $conf->{acpi
} == 0;
2242 push @$cmd, '-no-reboot' if defined($conf->{reboot
}) && $conf->{reboot
} == 0;
2244 my $vga = $conf->{vga
};
2246 if ($conf->{ostype
} && ($conf->{ostype
} eq 'win8' || $conf->{ostype
} eq 'win7' || $conf->{ostype
} eq 'w2k8')) {
2253 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2256 my $tdf = defined($conf->{tdf
}) ?
$conf->{tdf
} : $defaults->{tdf
};
2258 my $nokvm = defined($conf->{kvm
}) && $conf->{kvm
} == 0 ?
1 : 0;
2259 my $useLocaltime = $conf->{localtime};
2261 if (my $ost = $conf->{ostype
}) {
2262 # other, wxp, w2k, w2k3, w2k8, wvista, win7, win8, l24, l26
2264 if ($ost =~ m/^w/) { # windows
2265 $useLocaltime = 1 if !defined($conf->{localtime});
2267 # use time drift fix when acpi is enabled
2268 if (!(defined($conf->{acpi
}) && $conf->{acpi
} == 0)) {
2269 $tdf = 1 if !defined($conf->{tdf
});
2273 if ($ost eq 'win7' || $ost eq 'win8' || $ost eq 'w2k8' ||
2275 push @$globalFlags, 'kvm-pit.lost_tick_policy=discard';
2276 push @$cmd, '-no-hpet';
2280 push @$rtcFlags, 'driftfix=slew' if $tdf;
2283 push @$machineFlags, 'accel=tcg';
2285 die "No accelerator found!\n" if !$cpuinfo->{hvm
};
2288 if ($conf->{startdate
}) {
2289 push @$rtcFlags, "base=$conf->{startdate}";
2290 } elsif ($useLocaltime) {
2291 push @$rtcFlags, 'base=localtime';
2294 push @$cmd, '-S' if $conf->{freeze
};
2296 # set keyboard layout
2297 my $kb = $conf->{keyboard
} || $defaults->{keyboard
};
2298 push @$cmd, '-k', $kb if $kb;
2301 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2302 #push @$cmd, '-soundhw', 'es1370';
2303 #push @$cmd, '-soundhw', $soundhw if $soundhw;
2305 if($conf->{agent
}) {
2306 my $qgasocket = qga_socket
($vmid);
2307 my $pciaddr = print_pci_addr
("qga0", $bridges);
2308 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
2309 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
2310 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
2313 $pciaddr = print_pci_addr
("balloon0", $bridges);
2314 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr" if $conf->{balloon
};
2316 if ($conf->{watchdog
}) {
2317 my $wdopts = parse_watchdog
($conf->{watchdog
});
2318 $pciaddr = print_pci_addr
("watchdog", $bridges);
2319 my $watchdog = $wdopts->{model
} || 'i6300esb';
2320 push @$devices, '-device', "$watchdog$pciaddr";
2321 push @$devices, '-watchdog-action', $wdopts->{action
} if $wdopts->{action
};
2325 my $scsicontroller = {};
2326 my $ahcicontroller = {};
2327 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : $defaults->{scsihw
};
2329 foreach_drive
($conf, sub {
2330 my ($ds, $drive) = @_;
2332 if (PVE
::Storage
::parse_volume_id
($drive->{file
}, 1)) {
2333 push @$vollist, $drive->{file
};
2336 $use_virtio = 1 if $ds =~ m/^virtio/;
2338 if (drive_is_cdrom
($drive)) {
2339 if ($bootindex_hash->{d
}) {
2340 $drive->{bootindex
} = $bootindex_hash->{d
};
2341 $bootindex_hash->{d
} += 1;
2344 if ($bootindex_hash->{c
}) {
2345 $drive->{bootindex
} = $bootindex_hash->{c
} if $conf->{bootdisk
} && ($conf->{bootdisk
} eq $ds);
2346 $bootindex_hash->{c
} += 1;
2350 if ($drive->{interface
} eq 'scsi') {
2352 my $maxdev = ($scsihw ne 'lsi') ?
256 : 7;
2353 my $controller = int($drive->{index} / $maxdev);
2354 $pciaddr = print_pci_addr
("scsihw$controller", $bridges);
2355 push @$devices, '-device', "$scsihw,id=scsihw$controller$pciaddr" if !$scsicontroller->{$controller};
2356 $scsicontroller->{$controller}=1;
2359 if ($drive->{interface
} eq 'sata') {
2360 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
2361 $pciaddr = print_pci_addr
("ahci$controller", $bridges);
2362 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
2363 $ahcicontroller->{$controller}=1;
2366 push @$devices, '-drive',print_drive_full
($storecfg, $vmid, $drive);
2367 push @$devices, '-device',print_drivedevice_full
($storecfg, $conf, $vmid, $drive, $bridges);
2370 push @$cmd, '-m', $conf->{memory
} || $defaults->{memory
};
2372 for (my $i = 0; $i < $MAX_NETS; $i++) {
2373 next if !$conf->{"net$i"};
2374 my $d = parse_net
($conf->{"net$i"});
2377 $use_virtio = 1 if $d->{model
} eq 'virtio';
2379 if ($bootindex_hash->{n
}) {
2380 $d->{bootindex
} = $bootindex_hash->{n
};
2381 $bootindex_hash->{n
} += 1;
2384 my $netdevfull = print_netdev_full
($vmid,$conf,$d,"net$i");
2385 push @$devices, '-netdev', $netdevfull;
2387 my $netdevicefull = print_netdevice_full
($vmid,$conf,$d,"net$i",$bridges);
2388 push @$devices, '-device', $netdevicefull;
2392 while (my ($k, $v) = each %$bridges) {
2393 $pciaddr = print_pci_addr
("pci.$k");
2394 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
2398 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2399 # when the VM uses virtio devices.
2400 if (!$use_virtio && $have_ovz) {
2402 my $cpuunits = defined($conf->{cpuunits
}) ?
2403 $conf->{cpuunits
} : $defaults->{cpuunits
};
2405 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2407 # fixme: cpulimit is currently ignored
2408 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2412 if ($conf->{args
}) {
2413 my $aa = PVE
::Tools
::split_args
($conf->{args
});
2417 push @$cmd, @$devices;
2418 push @$cmd, '-rtc', join(',', @$rtcFlags)
2419 if scalar(@$rtcFlags);
2420 push @$cmd, '-machine', join(',', @$machineFlags)
2421 if scalar(@$machineFlags);
2422 push @$cmd, '-global', join(',', @$globalFlags)
2423 if scalar(@$globalFlags);
2425 return wantarray ?
($cmd, $vollist) : $cmd;
2430 return "${var_run_tmpdir}/$vmid.vnc";
2435 return "${var_run_tmpdir}/$vmid.qmp";
2440 return "${var_run_tmpdir}/$vmid.qga";
2445 return "${var_run_tmpdir}/$vmid.pid";
2448 sub next_migrate_port
{
2450 for (my $p = 60000; $p < 60010; $p++) {
2452 my $sock = IO
::Socket
::INET-
>new(Listen
=> 5,
2453 LocalAddr
=> 'localhost',
2464 die "unable to find free migration port";
2467 sub vm_devices_list
{
2470 my $res = vm_mon_cmd
($vmid, 'query-pci');
2473 foreach my $pcibus (@$res) {
2474 foreach my $device (@{$pcibus->{devices
}}) {
2475 next if !$device->{'qdev_id'};
2476 $devices->{$device->{'qdev_id'}} = $device;
2484 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
2486 return 1 if !check_running
($vmid) || !$conf->{hotplug
};
2488 my $devices_list = vm_devices_list
($vmid);
2489 return 1 if defined($devices_list->{$deviceid});
2491 qemu_bridgeadd
($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
2493 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2494 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2495 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
2496 qemu_deviceadd
($vmid, $devicefull);
2497 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2498 qemu_drivedel
($vmid, $deviceid);
2503 if ($deviceid =~ m/^(scsihw)(\d+)$/) {
2504 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : "lsi";
2505 my $pciaddr = print_pci_addr
($deviceid);
2506 my $devicefull = "$scsihw,id=$deviceid$pciaddr";
2507 qemu_deviceadd
($vmid, $devicefull);
2508 return undef if(!qemu_deviceaddverify
($vmid, $deviceid));
2511 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2512 return 1 if ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi'); #virtio-scsi not yet support hotplug
2513 return undef if !qemu_findorcreatescsihw
($storecfg,$conf, $vmid, $device);
2514 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2515 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
2516 if(!qemu_deviceadd
($vmid, $devicefull)) {
2517 qemu_drivedel
($vmid, $deviceid);
2522 if ($deviceid =~ m/^(net)(\d+)$/) {
2523 return undef if !qemu_netdevadd
($vmid, $conf, $device, $deviceid);
2524 my $netdevicefull = print_netdevice_full
($vmid, $conf, $device, $deviceid);
2525 qemu_deviceadd
($vmid, $netdevicefull);
2526 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2527 qemu_netdevdel
($vmid, $deviceid);
2532 if ($deviceid =~ m/^(pci\.)(\d+)$/) {
2534 my $pciaddr = print_pci_addr
($deviceid);
2535 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
2536 qemu_deviceadd
($vmid, $devicefull);
2537 return undef if !qemu_deviceaddverify
($vmid, $deviceid);
2543 sub vm_deviceunplug
{
2544 my ($vmid, $conf, $deviceid) = @_;
2546 return 1 if !check_running
($vmid) || !$conf->{hotplug
};
2548 my $devices_list = vm_devices_list
($vmid);
2549 return 1 if !defined($devices_list->{$deviceid});
2551 die "can't unplug bootdisk" if $conf->{bootdisk
} && $conf->{bootdisk
} eq $deviceid;
2553 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2554 return undef if !qemu_drivedel
($vmid, $deviceid);
2555 qemu_devicedel
($vmid, $deviceid);
2556 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2559 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2560 return undef if !qemu_devicedel
($vmid, $deviceid);
2563 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2564 return undef if !qemu_devicedel
($vmid, $deviceid);
2565 return undef if !qemu_drivedel
($vmid, $deviceid);
2568 if ($deviceid =~ m/^(net)(\d+)$/) {
2569 return undef if !qemu_netdevdel
($vmid, $deviceid);
2570 qemu_devicedel
($vmid, $deviceid);
2571 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2577 sub qemu_deviceadd
{
2578 my ($vmid, $devicefull) = @_;
2580 my $ret = vm_human_monitor_command
($vmid, "device_add $devicefull");
2582 # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
2583 return 1 if $ret eq "";
2584 syslog
("err", "error on hotplug device : $ret");
2589 sub qemu_devicedel
{
2590 my($vmid, $deviceid) = @_;
2592 my $ret = vm_human_monitor_command
($vmid, "device_del $deviceid");
2594 return 1 if $ret eq "";
2595 syslog
("err", "detaching device $deviceid failed : $ret");
2600 my($storecfg, $vmid, $device) = @_;
2602 my $drive = print_drive_full
($storecfg, $vmid, $device);
2603 my $ret = vm_human_monitor_command
($vmid, "drive_add auto $drive");
2604 # If the command succeeds qemu prints: "OK"
2605 if ($ret !~ m/OK/s) {
2606 syslog
("err", "adding drive failed: $ret");
2613 my($vmid, $deviceid) = @_;
2615 my $ret = vm_human_monitor_command
($vmid, "drive_del drive-$deviceid");
2617 if ($ret =~ m/Device \'.*?\' not found/s) {
2618 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
2620 elsif ($ret ne "") {
2621 syslog
("err", "deleting drive $deviceid failed : $ret");
2627 sub qemu_deviceaddverify
{
2628 my ($vmid,$deviceid) = @_;
2630 for (my $i = 0; $i <= 5; $i++) {
2631 my $devices_list = vm_devices_list
($vmid);
2632 return 1 if defined($devices_list->{$deviceid});
2635 syslog
("err", "error on hotplug device $deviceid");
2640 sub qemu_devicedelverify
{
2641 my ($vmid,$deviceid) = @_;
2643 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2644 for (my $i = 0; $i <= 5; $i++) {
2645 my $devices_list = vm_devices_list
($vmid);
2646 return 1 if !defined($devices_list->{$deviceid});
2649 syslog
("err", "error on hot-unplugging device $deviceid");
2653 sub qemu_findorcreatescsihw
{
2654 my ($storecfg, $conf, $vmid, $device) = @_;
2656 my $maxdev = ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi') ?
256 : 7;
2657 my $controller = int($device->{index} / $maxdev);
2658 my $scsihwid="scsihw$controller";
2659 my $devices_list = vm_devices_list
($vmid);
2661 if(!defined($devices_list->{$scsihwid})) {
2662 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $scsihwid);
2667 sub qemu_bridgeadd
{
2668 my ($storecfg, $conf, $vmid, $device) = @_;
2671 my $bridgeid = undef;
2672 print_pci_addr
($device, $bridges);
2674 while (my ($k, $v) = each %$bridges) {
2677 return if $bridgeid < 1;
2678 my $bridge = "pci.$bridgeid";
2679 my $devices_list = vm_devices_list
($vmid);
2681 if(!defined($devices_list->{$bridge})) {
2682 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $bridge);
2687 sub qemu_netdevadd
{
2688 my ($vmid, $conf, $device, $deviceid) = @_;
2690 my $netdev = print_netdev_full
($vmid, $conf, $device, $deviceid);
2691 my $ret = vm_human_monitor_command
($vmid, "netdev_add $netdev");
2694 #if the command succeeds, no output is sent. So any non-empty string shows an error
2695 return 1 if $ret eq "";
2696 syslog
("err", "adding netdev failed: $ret");
2700 sub qemu_netdevdel
{
2701 my ($vmid, $deviceid) = @_;
2703 my $ret = vm_human_monitor_command
($vmid, "netdev_del $deviceid");
2705 #if the command succeeds, no output is sent. So any non-empty string shows an error
2706 return 1 if $ret eq "";
2707 syslog
("err", "deleting netdev failed: $ret");
2711 sub qemu_block_set_io_throttle
{
2712 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2714 return if !check_running
($vmid) ;
2717 $bps_rd = 0 if !$bps_rd;
2718 $bps_wr = 0 if !$bps_wr;
2719 $iops = 0 if !$iops;
2720 $iops_rd = 0 if !$iops_rd;
2721 $iops_wr = 0 if !$iops_wr;
2723 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));
2727 # old code, only used to shutdown old VM after update
2729 my ($fh, $timeout) = @_;
2731 my $sel = new IO
::Select
;
2738 while (scalar (@ready = $sel->can_read($timeout))) {
2740 if ($count = $fh->sysread($buf, 8192)) {
2741 if ($buf =~ /^(.*)\(qemu\) $/s) {
2748 if (!defined($count)) {
2755 die "monitor read timeout\n" if !scalar(@ready);
2760 # old code, only used to shutdown old VM after update
2761 sub vm_monitor_command
{
2762 my ($vmid, $cmdstr, $nocheck) = @_;
2767 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
2769 my $sname = "${var_run_tmpdir}/$vmid.mon";
2771 my $sock = IO
::Socket
::UNIX-
>new( Peer
=> $sname ) ||
2772 die "unable to connect to VM $vmid socket - $!\n";
2776 # hack: migrate sometime blocks the monitor (when migrate_downtime
2778 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2779 $timeout = 60*60; # 1 hour
2783 my $data = __read_avail
($sock, $timeout);
2785 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2786 die "got unexpected qemu monitor banner\n";
2789 my $sel = new IO
::Select
;
2792 if (!scalar(my @ready = $sel->can_write($timeout))) {
2793 die "monitor write error - timeout";
2796 my $fullcmd = "$cmdstr\r";
2798 # syslog('info', "VM $vmid monitor command: $cmdstr");
2801 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
2802 die "monitor write error - $!";
2805 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2809 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2810 $timeout = 60*60; # 1 hour
2811 } elsif ($cmdstr =~ m/^(eject|change)/) {
2812 $timeout = 60; # note: cdrom mount command is slow
2814 if ($res = __read_avail
($sock, $timeout)) {
2816 my @lines = split("\r?\n", $res);
2818 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
2820 $res = join("\n", @lines);
2828 syslog
("err", "VM $vmid monitor command failed - $err");
2835 sub qemu_block_resize
{
2836 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
2838 my $running = PVE
::QemuServer
::check_running
($vmid);
2840 return if !PVE
::Storage
::volume_resize
($storecfg, $volid, $size, $running);
2842 return if !$running;
2844 vm_mon_cmd
($vmid, "block_resize", device
=> $deviceid, size
=> int($size));
2848 sub qemu_volume_snapshot
{
2849 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
2851 my $running = PVE
::QemuServer
::check_running
($vmid);
2853 return if !PVE
::Storage
::volume_snapshot
($storecfg, $volid, $snap, $running);
2855 return if !$running;
2857 vm_mon_cmd
($vmid, "snapshot-drive", device
=> $deviceid, name
=> $snap);
2861 sub qemu_volume_snapshot_delete
{
2862 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
2864 my $running = PVE
::QemuServer
::check_running
($vmid);
2866 return if !PVE
::Storage
::volume_snapshot_delete
($storecfg, $volid, $snap, $running);
2868 return if !$running;
2870 vm_mon_cmd
($vmid, "delete-drive-snapshot", device
=> $deviceid, name
=> $snap);
2876 #need to impplement call to qemu-ga
2879 sub qga_unfreezefs
{
2882 #need to impplement call to qemu-ga
2886 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom) = @_;
2888 lock_config
($vmid, sub {
2889 my $conf = load_config
($vmid, $migratedfrom);
2891 check_lock
($conf) if !$skiplock;
2893 die "VM $vmid already running\n" if check_running
($vmid, undef, $migratedfrom);
2895 my $defaults = load_defaults
();
2897 # set environment variable useful inside network script
2898 $ENV{PVE_MIGRATED_FROM
} = $migratedfrom if $migratedfrom;
2900 my ($cmd, $vollist) = config_to_command
($storecfg, $vmid, $conf, $defaults);
2902 my $migrate_port = 0;
2905 if ($statefile eq 'tcp') {
2906 $migrate_port = next_migrate_port
();
2907 my $migrate_uri = "tcp:localhost:${migrate_port}";
2908 push @$cmd, '-incoming', $migrate_uri;
2911 push @$cmd, '-loadstate', $statefile;
2916 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2917 my $d = parse_hostpci
($conf->{"hostpci$i"});
2919 my $info = pci_device_info
("0000:$d->{pciid}");
2920 die "IOMMU not present\n" if !check_iommu_support
();
2921 die "no pci device info for device '$d->{pciid}'\n" if !$info;
2922 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub
($info);
2923 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset
($info);
2926 PVE
::Storage
::activate_volumes
($storecfg, $vollist);
2928 eval { run_command
($cmd, timeout
=> $statefile ?
undef : 30,
2931 die "start failed: $err" if $err;
2933 print "migration listens on port $migrate_port\n" if $migrate_port;
2935 if ($statefile && $statefile ne 'tcp') {
2936 eval { vm_mon_cmd
($vmid, "cont"); };
2940 # always set migrate speed (overwrite kvm default of 32m)
2941 # we set a very hight default of 8192m which is basically unlimited
2942 my $migrate_speed = $defaults->{migrate_speed
} || 8192;
2943 $migrate_speed = $conf->{migrate_speed
} || $migrate_speed;
2944 $migrate_speed = $migrate_speed * 1048576;
2946 vm_mon_cmd
($vmid, "migrate_set_speed", value
=> $migrate_speed);
2949 my $migrate_downtime = $defaults->{migrate_downtime
};
2950 $migrate_downtime = $conf->{migrate_downtime
} if defined($conf->{migrate_downtime
});
2951 if (defined($migrate_downtime)) {
2952 eval { vm_mon_cmd
($vmid, "migrate_set_downtime", value
=> $migrate_downtime); };
2956 my $capabilities = {};
2957 $capabilities->{capability
} = "xbzrle";
2958 $capabilities->{state} = JSON
::true
;
2959 eval { PVE
::QemuServer
::vm_mon_cmd_nocheck
($vmid, "migrate-set-capabilities", capabilities
=> [$capabilities]); };
2962 vm_balloonset
($vmid, $conf->{balloon
}) if $conf->{balloon
};
2968 my ($vmid, $execute, %params) = @_;
2970 my $cmd = { execute
=> $execute, arguments
=> \
%params };
2971 vm_qmp_command
($vmid, $cmd);
2974 sub vm_mon_cmd_nocheck
{
2975 my ($vmid, $execute, %params) = @_;
2977 my $cmd = { execute
=> $execute, arguments
=> \
%params };
2978 vm_qmp_command
($vmid, $cmd, 1);
2981 sub vm_qmp_command
{
2982 my ($vmid, $cmd, $nocheck) = @_;
2987 if ($cmd->{arguments
} && $cmd->{arguments
}->{timeout
}) {
2988 $timeout = $cmd->{arguments
}->{timeout
};
2989 delete $cmd->{arguments
}->{timeout
};
2993 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
2994 my $sname = PVE
::QemuServer
::qmp_socket
($vmid);
2996 my $qmpclient = PVE
::QMPClient-
>new();
2998 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
2999 } elsif (-e
"${var_run_tmpdir}/$vmid.mon") {
3000 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
3001 if scalar(%{$cmd->{arguments
}});
3002 vm_monitor_command
($vmid, $cmd->{execute
}, $nocheck);
3004 die "unable to open monitor socket\n";
3008 syslog
("err", "VM $vmid qmp command failed - $err");
3015 sub vm_human_monitor_command
{
3016 my ($vmid, $cmdline) = @_;
3021 execute
=> 'human-monitor-command',
3022 arguments
=> { 'command-line' => $cmdline},
3025 return vm_qmp_command
($vmid, $cmd);
3028 sub vm_commandline
{
3029 my ($storecfg, $vmid) = @_;
3031 my $conf = load_config
($vmid);
3033 my $defaults = load_defaults
();
3035 my $cmd = config_to_command
($storecfg, $vmid, $conf, $defaults);
3037 return join(' ', @$cmd);
3041 my ($vmid, $skiplock) = @_;
3043 lock_config
($vmid, sub {
3045 my $conf = load_config
($vmid);
3047 check_lock
($conf) if !$skiplock;
3049 vm_mon_cmd
($vmid, "system_reset");
3053 sub get_vm_volumes
{
3057 foreach_volid
($conf, sub {
3058 my ($volid, $is_cdrom) = @_;
3060 return if $volid =~ m
|^/|;
3062 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
3065 push @$vollist, $volid;
3071 sub vm_stop_cleanup
{
3072 my ($storecfg, $vmid, $conf, $keepActive) = @_;
3075 fairsched_rmnod
($vmid); # try to destroy group
3078 my $vollist = get_vm_volumes
($conf);
3079 PVE
::Storage
::deactivate_volumes
($storecfg, $vollist);
3082 foreach my $ext (qw(mon qmp pid vnc qga)) {
3083 unlink "/var/run/qemu-server/${vmid}.$ext";
3086 warn $@ if $@; # avoid errors - just warn
3089 # Note: use $nockeck to skip tests if VM configuration file exists.
3090 # We need that when migration VMs to other nodes (files already moved)
3091 # Note: we set $keepActive in vzdump stop mode - volumes need to stay active
3093 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
3095 $force = 1 if !defined($force) && !$shutdown;
3098 my $pid = check_running
($vmid, $nocheck, $migratedfrom);
3099 kill 15, $pid if $pid;
3100 my $conf = load_config
($vmid, $migratedfrom);
3101 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive);
3105 lock_config
($vmid, sub {
3107 my $pid = check_running
($vmid, $nocheck);
3112 $conf = load_config
($vmid);
3113 check_lock
($conf) if !$skiplock;
3114 if (!defined($timeout) && $shutdown && $conf->{startup
}) {
3115 my $opts = parse_startup
($conf->{startup
});
3116 $timeout = $opts->{down
} if $opts->{down
};
3120 $timeout = 60 if !defined($timeout);
3124 $nocheck ? vm_mon_cmd_nocheck
($vmid, "system_powerdown") : vm_mon_cmd
($vmid, "system_powerdown");
3127 $nocheck ? vm_mon_cmd_nocheck
($vmid, "quit") : vm_mon_cmd
($vmid, "quit");
3134 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
3139 if ($count >= $timeout) {
3141 warn "VM still running - terminating now with SIGTERM\n";
3144 die "VM quit/powerdown failed - got timeout\n";
3147 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
3152 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
3155 die "VM quit/powerdown failed\n";
3163 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
3168 if ($count >= $timeout) {
3169 warn "VM still running - terminating now with SIGKILL\n";
3174 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
3179 my ($vmid, $skiplock) = @_;
3181 lock_config
($vmid, sub {
3183 my $conf = load_config
($vmid);
3185 check_lock
($conf) if !$skiplock;
3187 vm_mon_cmd
($vmid, "stop");
3192 my ($vmid, $skiplock) = @_;
3194 lock_config
($vmid, sub {
3196 my $conf = load_config
($vmid);
3198 check_lock
($conf) if !$skiplock;
3200 vm_mon_cmd
($vmid, "cont");
3205 my ($vmid, $skiplock, $key) = @_;
3207 lock_config
($vmid, sub {
3209 my $conf = load_config
($vmid);
3211 # there is no qmp command, so we use the human monitor command
3212 vm_human_monitor_command
($vmid, "sendkey $key");
3217 my ($storecfg, $vmid, $skiplock) = @_;
3219 lock_config
($vmid, sub {
3221 my $conf = load_config
($vmid);
3223 check_lock
($conf) if !$skiplock;
3225 if (!check_running
($vmid)) {
3226 fairsched_rmnod
($vmid); # try to destroy group
3227 destroy_vm
($storecfg, $vmid);
3229 die "VM $vmid is running - destroy failed\n";
3237 my ($filename, $buf) = @_;
3239 my $fh = IO
::File-
>new($filename, "w");
3240 return undef if !$fh;
3242 my $res = print $fh $buf;
3249 sub pci_device_info
{
3254 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
3255 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
3257 my $irq = file_read_firstline
("$pcisysfs/devices/$name/irq");
3258 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3260 my $vendor = file_read_firstline
("$pcisysfs/devices/$name/vendor");
3261 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3263 my $product = file_read_firstline
("$pcisysfs/devices/$name/device");
3264 return undef if !defined($product) || $product !~ s/^0x//;
3269 product
=> $product,
3275 has_fl_reset
=> -f
"$pcisysfs/devices/$name/reset" || 0,
3284 my $name = $dev->{name
};
3286 my $fn = "$pcisysfs/devices/$name/reset";
3288 return file_write
($fn, "1");
3291 sub pci_dev_bind_to_stub
{
3294 my $name = $dev->{name
};
3296 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3297 return 1 if -d
$testdir;
3299 my $data = "$dev->{vendor} $dev->{product}";
3300 return undef if !file_write
("$pcisysfs/drivers/pci-stub/new_id", $data);
3302 my $fn = "$pcisysfs/devices/$name/driver/unbind";
3303 if (!file_write
($fn, $name)) {
3304 return undef if -f
$fn;
3307 $fn = "$pcisysfs/drivers/pci-stub/bind";
3308 if (! -d
$testdir) {
3309 return undef if !file_write
($fn, $name);
3315 sub print_pci_addr
{
3316 my ($id, $bridges) = @_;
3320 #addr1 : ide,parallel,serial (motherboard)
3321 #addr2 : first videocard
3322 balloon0
=> { bus
=> 0, addr
=> 3 },
3323 watchdog
=> { bus
=> 0, addr
=> 4 },
3324 scsihw0
=> { bus
=> 0, addr
=> 5 },
3325 scsihw1
=> { bus
=> 0, addr
=> 6 },
3326 ahci0
=> { bus
=> 0, addr
=> 7 },
3327 qga0
=> { bus
=> 0, addr
=> 8 },
3328 virtio0
=> { bus
=> 0, addr
=> 10 },
3329 virtio1
=> { bus
=> 0, addr
=> 11 },
3330 virtio2
=> { bus
=> 0, addr
=> 12 },
3331 virtio3
=> { bus
=> 0, addr
=> 13 },
3332 virtio4
=> { bus
=> 0, addr
=> 14 },
3333 virtio5
=> { bus
=> 0, addr
=> 15 },
3334 hostpci0
=> { bus
=> 0, addr
=> 16 },
3335 hostpci1
=> { bus
=> 0, addr
=> 17 },
3336 net0
=> { bus
=> 0, addr
=> 18 },
3337 net1
=> { bus
=> 0, addr
=> 19 },
3338 net2
=> { bus
=> 0, addr
=> 20 },
3339 net3
=> { bus
=> 0, addr
=> 21 },
3340 net4
=> { bus
=> 0, addr
=> 22 },
3341 net5
=> { bus
=> 0, addr
=> 23 },
3342 #addr29 : usb-host (pve-usb.cfg)
3343 'pci.1' => { bus
=> 0, addr
=> 30 },
3344 'pci.2' => { bus
=> 0, addr
=> 31 },
3345 'net6' => { bus
=> 1, addr
=> 1 },
3346 'net7' => { bus
=> 1, addr
=> 2 },
3347 'net8' => { bus
=> 1, addr
=> 3 },
3348 'net9' => { bus
=> 1, addr
=> 4 },
3349 'net10' => { bus
=> 1, addr
=> 5 },
3350 'net11' => { bus
=> 1, addr
=> 6 },
3351 'net12' => { bus
=> 1, addr
=> 7 },
3352 'net13' => { bus
=> 1, addr
=> 8 },
3353 'net14' => { bus
=> 1, addr
=> 9 },
3354 'net15' => { bus
=> 1, addr
=> 10 },
3355 'net16' => { bus
=> 1, addr
=> 11 },
3356 'net17' => { bus
=> 1, addr
=> 12 },
3357 'net18' => { bus
=> 1, addr
=> 13 },
3358 'net19' => { bus
=> 1, addr
=> 14 },
3359 'net20' => { bus
=> 1, addr
=> 15 },
3360 'net21' => { bus
=> 1, addr
=> 16 },
3361 'net22' => { bus
=> 1, addr
=> 17 },
3362 'net23' => { bus
=> 1, addr
=> 18 },
3363 'net24' => { bus
=> 1, addr
=> 19 },
3364 'net25' => { bus
=> 1, addr
=> 20 },
3365 'net26' => { bus
=> 1, addr
=> 21 },
3366 'net27' => { bus
=> 1, addr
=> 22 },
3367 'net28' => { bus
=> 1, addr
=> 23 },
3368 'net29' => { bus
=> 1, addr
=> 24 },
3369 'net30' => { bus
=> 1, addr
=> 25 },
3370 'net31' => { bus
=> 1, addr
=> 26 },
3371 'virtio6' => { bus
=> 2, addr
=> 1 },
3372 'virtio7' => { bus
=> 2, addr
=> 2 },
3373 'virtio8' => { bus
=> 2, addr
=> 3 },
3374 'virtio9' => { bus
=> 2, addr
=> 4 },
3375 'virtio10' => { bus
=> 2, addr
=> 5 },
3376 'virtio11' => { bus
=> 2, addr
=> 6 },
3377 'virtio12' => { bus
=> 2, addr
=> 7 },
3378 'virtio13' => { bus
=> 2, addr
=> 8 },
3379 'virtio14' => { bus
=> 2, addr
=> 9 },
3380 'virtio15' => { bus
=> 2, addr
=> 10 },
3383 if (defined($devices->{$id}->{bus
}) && defined($devices->{$id}->{addr
})) {
3384 my $addr = sprintf("0x%x", $devices->{$id}->{addr
});
3385 my $bus = $devices->{$id}->{bus
};
3386 $res = ",bus=pci.$bus,addr=$addr";
3387 $bridges->{$bus} = 1 if $bridges;
3394 my ($vmid, $value) = @_;
3396 vm_mon_cmd
($vmid, "balloon", value
=> $value);
3399 # vzdump restore implementaion
3401 sub archive_read_firstfile
{
3402 my $archive = shift;
3404 die "ERROR: file '$archive' does not exist\n" if ! -f
$archive;
3406 # try to detect archive type first
3407 my $pid = open (TMP
, "tar tf '$archive'|") ||
3408 die "unable to open file '$archive'\n";
3409 my $firstfile = <TMP
>;
3413 die "ERROR: archive contaions no data\n" if !$firstfile;
3419 sub restore_cleanup
{
3420 my $statfile = shift;
3422 print STDERR
"starting cleanup\n";
3424 if (my $fd = IO
::File-
>new($statfile, "r")) {
3425 while (defined(my $line = <$fd>)) {
3426 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3429 if ($volid =~ m
|^/|) {
3430 unlink $volid || die 'unlink failed\n';
3432 my $cfg = cfs_read_file
('storage.cfg');
3433 PVE
::Storage
::vdisk_free
($cfg, $volid);
3435 print STDERR
"temporary volume '$volid' sucessfuly removed\n";
3437 print STDERR
"unable to cleanup '$volid' - $@" if $@;
3439 print STDERR
"unable to parse line in statfile - $line";
3446 sub restore_archive
{
3447 my ($archive, $vmid, $user, $opts) = @_;
3449 if ($archive ne '-') {
3450 my $firstfile = archive_read_firstfile
($archive);
3451 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
3452 if $firstfile ne 'qemu-server.conf';
3455 my $tocmd = "/usr/lib/qemu-server/qmextract";
3457 $tocmd .= " --storage " . PVE
::Tools
::shellquote
($opts->{storage
}) if $opts->{storage
};
3458 $tocmd .= " --pool " . PVE
::Tools
::shellquote
($opts->{pool
}) if $opts->{pool
};
3459 $tocmd .= ' --prealloc' if $opts->{prealloc
};
3460 $tocmd .= ' --info' if $opts->{info
};
3462 # tar option "xf" does not autodetect compression when read from STDIN,
3463 # so we pipe to zcat
3464 my $cmd = "zcat -f|tar xf " . PVE
::Tools
::shellquote
($archive) . " " .
3465 PVE
::Tools
::shellquote
("--to-command=$tocmd");
3467 my $tmpdir = "/var/tmp/vzdumptmp$$";
3470 local $ENV{VZDUMP_TMPDIR
} = $tmpdir;
3471 local $ENV{VZDUMP_VMID
} = $vmid;
3472 local $ENV{VZDUMP_USER
} = $user;
3474 my $conffile = PVE
::QemuServer
::config_file
($vmid);
3475 my $tmpfn = "$conffile.$$.tmp";
3477 # disable interrupts (always do cleanups)
3478 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
3479 print STDERR
"got interrupt - ignored\n";
3484 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
3485 die "interrupted by signal\n";
3488 if ($archive eq '-') {
3489 print "extracting archive from STDIN\n";
3490 run_command
($cmd, input
=> "<&STDIN");
3492 print "extracting archive '$archive'\n";
3496 return if $opts->{info
};
3500 my $statfile = "$tmpdir/qmrestore.stat";
3501 if (my $fd = IO
::File-
>new($statfile, "r")) {
3502 while (defined (my $line = <$fd>)) {
3503 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3504 $map->{$1} = $2 if $1;
3506 print STDERR
"unable to parse line in statfile - $line\n";
3512 my $confsrc = "$tmpdir/qemu-server.conf";
3514 my $srcfd = new IO
::File
($confsrc, "r") ||
3515 die "unable to open file '$confsrc'\n";
3517 my $outfd = new IO
::File
($tmpfn, "w") ||
3518 die "unable to write config for VM $vmid\n";
3522 while (defined (my $line = <$srcfd>)) {
3523 next if $line =~ m/^\#vzdump\#/;
3524 next if $line =~ m/^lock:/;
3525 next if $line =~ m/^unused\d+:/;
3527 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3528 # try to convert old 1.X settings
3529 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3530 foreach my $devconfig (PVE
::Tools
::split_list
($ethcfg)) {
3531 my ($model, $macaddr) = split(/\=/, $devconfig);
3532 $macaddr = PVE
::Tools
::random_ether_addr
() if !$macaddr || $opts->{unique
};
3535 bridge
=> "vmbr$ind",
3536 macaddr
=> $macaddr,
3538 my $netstr = print_net
($net);
3539 print $outfd "net${netcount}: $netstr\n";
3542 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && ($opts->{unique
})) {
3543 my ($id, $netstr) = ($1, $2);
3544 my $net = parse_net
($netstr);
3545 $net->{macaddr
} = PVE
::Tools
::random_ether_addr
() if $net->{macaddr
};
3546 $netstr = print_net
($net);
3547 print $outfd "$id: $netstr\n";
3548 } elsif ($line =~ m/^((ide|scsi|virtio|sata)\d+):\s*(\S+)\s*$/) {
3551 if ($line =~ m/backup=no/) {
3552 print $outfd "#$line";
3553 } elsif ($virtdev && $map->{$virtdev}) {
3554 my $di = PVE
::QemuServer
::parse_drive
($virtdev, $value);
3555 $di->{file
} = $map->{$virtdev};
3556 $value = PVE
::QemuServer
::print_drive
($vmid, $di);
3557 print $outfd "$virtdev: $value\n";
3575 restore_cleanup
("$tmpdir/qmrestore.stat") if !$opts->{info
};
3582 rename $tmpfn, $conffile ||
3583 die "unable to commit configuration file '$conffile'\n";
3587 # Internal snapshots
3589 # NOTE: Snapshot create/delete involves several non-atomic
3590 # action, and can take a long time.
3591 # So we try to avoid locking the file and use 'lock' variable
3592 # inside the config file instead.
3594 my $snapshot_copy_config = sub {
3595 my ($source, $dest) = @_;
3597 foreach my $k (keys %$source) {
3598 next if $k eq 'snapshots';
3599 next if $k eq 'snapstate';
3600 next if $k eq 'snaptime';
3601 next if $k eq 'vmstate';
3602 next if $k eq 'lock';
3603 next if $k eq 'digest';
3604 next if $k eq 'description';
3605 next if $k =~ m/^unused\d+$/;
3607 $dest->{$k} = $source->{$k};
3611 my $snapshot_apply_config = sub {
3612 my ($conf, $snap) = @_;
3614 # copy snapshot list
3616 snapshots
=> $conf->{snapshots
},
3619 # keep description and list of unused disks
3620 foreach my $k (keys %$conf) {
3621 next if !($k =~ m/^unused\d+$/ || $k eq 'description');
3622 $newconf->{$k} = $conf->{$k};
3625 &$snapshot_copy_config($snap, $newconf);
3630 sub foreach_writable_storage
{
3631 my ($conf, $func) = @_;
3635 foreach my $ds (keys %$conf) {
3636 next if !valid_drivename
($ds);
3638 my $drive = parse_drive
($ds, $conf->{$ds});
3640 next if drive_is_cdrom
($drive);
3642 my $volid = $drive->{file
};
3644 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
3645 $sidhash->{$sid} = $sid if $sid;
3648 foreach my $sid (sort keys %$sidhash) {
3653 my $alloc_vmstate_volid = sub {
3654 my ($storecfg, $vmid, $conf, $snapname) = @_;
3656 # Note: we try to be smart when selecting a $target storage
3660 # search shared storage first
3661 foreach_writable_storage
($conf, sub {
3663 my $scfg = PVE
::Storage
::storage_config
($storecfg, $sid);
3664 return if !$scfg->{shared
};
3666 $target = $sid if !$target || $scfg->{path
}; # prefer file based storage
3670 # now search local storage
3671 foreach_writable_storage
($conf, sub {
3673 my $scfg = PVE
::Storage
::storage_config
($storecfg, $sid);
3674 return if $scfg->{shared
};
3676 $target = $sid if !$target || $scfg->{path
}; # prefer file based storage;
3680 $target = 'local' if !$target;
3682 my $driver_state_size = 500; # assume 32MB is enough to safe all driver state;
3683 # we abort live save after $conf->{memory}, so we need at max twice that space
3684 my $size = $conf->{memory
}*2 + $driver_state_size;
3686 my $name = "vm-$vmid-state-$snapname";
3687 my $scfg = PVE
::Storage
::storage_config
($storecfg, $target);
3688 $name .= ".raw" if $scfg->{path
}; # add filename extension for file base storage
3689 my $volid = PVE
::Storage
::vdisk_alloc
($storecfg, $target, $vmid, 'raw', $name, $size*1024);
3694 my $snapshot_prepare = sub {
3695 my ($vmid, $snapname, $save_vmstate, $comment) = @_;
3699 my $updatefn = sub {
3701 my $conf = load_config
($vmid);
3705 $conf->{lock} = 'snapshot';
3707 die "snapshot name '$snapname' already used\n"
3708 if defined($conf->{snapshots
}->{$snapname});
3710 my $storecfg = PVE
::Storage
::config
();
3712 foreach_drive
($conf, sub {
3713 my ($ds, $drive) = @_;
3715 return if drive_is_cdrom
($drive);
3716 my $volid = $drive->{file
};
3718 my ($storeid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
3720 my $scfg = PVE
::Storage
::storage_config
($storecfg, $storeid);
3721 die "can't snapshot volume '$volid'\n"
3722 if !(($scfg->{path
} && $volname =~ m/\.qcow2$/) ||
3723 ($scfg->{type
} eq 'nexenta') ||
3724 ($scfg->{type
} eq 'rbd') ||
3725 ($scfg->{type
} eq 'sheepdog'));
3726 } elsif ($volid =~ m
|^(/.+)$| && -e
$volid) {
3727 die "snapshot device '$volid' is not possible\n";
3729 die "can't snapshot volume '$volid'\n";
3734 $snap = $conf->{snapshots
}->{$snapname} = {};
3736 if ($save_vmstate && check_running
($vmid)) {
3737 $snap->{vmstate
} = &$alloc_vmstate_volid($storecfg, $vmid, $conf, $snapname);
3740 &$snapshot_copy_config($conf, $snap);
3742 $snap->{snapstate
} = "prepare";
3743 $snap->{snaptime
} = time();
3744 $snap->{description
} = $comment if $comment;
3746 update_config_nolock
($vmid, $conf, 1);
3749 lock_config
($vmid, $updatefn);
3754 my $snapshot_commit = sub {
3755 my ($vmid, $snapname) = @_;
3757 my $updatefn = sub {
3759 my $conf = load_config
($vmid);
3761 die "missing snapshot lock\n"
3762 if !($conf->{lock} && $conf->{lock} eq 'snapshot');
3764 my $snap = $conf->{snapshots
}->{$snapname};
3766 die "snapshot '$snapname' does not exist\n" if !defined($snap);
3768 die "wrong snapshot state\n"
3769 if !($snap->{snapstate
} && $snap->{snapstate
} eq "prepare");
3771 delete $snap->{snapstate
};
3772 delete $conf->{lock};
3774 my $newconf = &$snapshot_apply_config($conf, $snap);
3776 $newconf->{parent
} = $snapname;
3778 update_config_nolock
($vmid, $newconf, 1);
3781 lock_config
($vmid, $updatefn);
3784 sub snapshot_rollback
{
3785 my ($vmid, $snapname) = @_;
3791 my $storecfg = PVE
::Storage
::config
();
3793 my $updatefn = sub {
3795 my $conf = load_config
($vmid);
3797 $snap = $conf->{snapshots
}->{$snapname};
3799 die "snapshot '$snapname' does not exist\n" if !defined($snap);
3801 die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
3802 if $snap->{snapstate
};
3806 vm_stop
($storecfg, $vmid, undef, undef, 5, undef, undef);
3809 die "unable to rollback vm $vmid: vm is running\n"
3810 if check_running
($vmid);
3813 $conf->{lock} = 'rollback';
3815 die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
3816 delete $conf->{lock};
3820 # copy snapshot config to current config
3821 $conf = &$snapshot_apply_config($conf, $snap);
3822 $conf->{parent
} = $snapname;
3825 update_config_nolock
($vmid, $conf, 1);
3827 if (!$prepare && $snap->{vmstate
}) {
3828 my $statefile = PVE
::Storage
::path
($storecfg, $snap->{vmstate
});
3829 # fixme: this only forws for files currently
3830 vm_start
($storecfg, $vmid, $statefile);
3835 lock_config
($vmid, $updatefn);
3837 foreach_drive
($snap, sub {
3838 my ($ds, $drive) = @_;
3840 return if drive_is_cdrom
($drive);
3842 my $volid = $drive->{file
};
3843 my $device = "drive-$ds";
3845 PVE
::Storage
::volume_snapshot_rollback
($storecfg, $volid, $snapname);
3849 lock_config
($vmid, $updatefn);
3852 my $savevm_wait = sub {
3856 my $stat = PVE
::QemuServer
::vm_mon_cmd_nocheck
($vmid, "query-savevm");
3857 if (!$stat->{status
}) {
3858 die "savevm not active\n";
3859 } elsif ($stat->{status
} eq 'active') {
3862 } elsif ($stat->{status
} eq 'completed') {
3865 die "query-savevm returned status '$stat->{status}'\n";
3870 sub snapshot_create
{
3871 my ($vmid, $snapname, $save_vmstate, $freezefs, $comment) = @_;
3873 my $snap = &$snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
3875 $freezefs = $save_vmstate = 0 if !$snap->{vmstate
}; # vm is not running
3879 my $running = check_running
($vmid);
3882 # create internal snapshots of all drives
3884 my $storecfg = PVE
::Storage
::config
();
3887 if ($snap->{vmstate
}) {
3888 my $path = PVE
::Storage
::path
($storecfg, $snap->{vmstate
});
3889 vm_mon_cmd
($vmid, "savevm-start", statefile
=> $path);
3890 &$savevm_wait($vmid);
3892 vm_mon_cmd
($vmid, "savevm-start");
3896 qga_freezefs
($vmid) if $running && $freezefs;
3898 foreach_drive
($snap, sub {
3899 my ($ds, $drive) = @_;
3901 return if drive_is_cdrom
($drive);
3903 my $volid = $drive->{file
};
3904 my $device = "drive-$ds";
3906 qemu_volume_snapshot
($vmid, $device, $storecfg, $volid, $snapname);
3907 $drivehash->{$ds} = 1;
3912 eval { gqa_unfreezefs
($vmid) if $running && $freezefs; };
3915 eval { vm_mon_cmd
($vmid, "savevm-end") if $running; };
3919 warn "snapshot create failed: starting cleanup\n";
3920 eval { snapshot_delete
($vmid, $snapname, 0, $drivehash); };
3925 &$snapshot_commit($vmid, $snapname);
3928 # Note: $drivehash is only set when called from snapshot_create.
3929 sub snapshot_delete
{
3930 my ($vmid, $snapname, $force, $drivehash) = @_;
3937 my $unlink_parent = sub {
3938 my ($confref, $new_parent) = @_;
3940 if ($confref->{parent
} && $confref->{parent
} eq $snapname) {
3942 $confref->{parent
} = $new_parent;
3944 delete $confref->{parent
};
3949 my $updatefn = sub {
3950 my ($remove_drive) = @_;
3952 my $conf = load_config
($vmid);
3954 check_lock
($conf) if !$drivehash;
3956 $snap = $conf->{snapshots
}->{$snapname};
3958 die "snapshot '$snapname' does not exist\n" if !defined($snap);
3960 # remove parent refs
3961 &$unlink_parent($conf, $snap->{parent
});
3962 foreach my $sn (keys %{$conf->{snapshots
}}) {
3963 next if $sn eq $snapname;
3964 &$unlink_parent($conf->{snapshots
}->{$sn}, $snap->{parent
});
3967 if ($remove_drive) {
3968 if ($remove_drive eq 'vmstate') {
3969 delete $snap->{$remove_drive};
3971 my $drive = parse_drive
($remove_drive, $snap->{$remove_drive});
3972 my $volid = $drive->{file
};
3973 delete $snap->{$remove_drive};
3974 add_unused_volume
($conf, $volid);
3979 $snap->{snapstate
} = 'delete';
3981 delete $conf->{snapshots
}->{$snapname};
3982 delete $conf->{lock} if $drivehash;
3983 foreach my $volid (@$unused) {
3984 add_unused_volume
($conf, $volid);
3988 update_config_nolock
($vmid, $conf, 1);
3991 lock_config
($vmid, $updatefn);
3993 # now remove vmstate file
3995 my $storecfg = PVE
::Storage
::config
();
3997 if ($snap->{vmstate
}) {
3998 eval { PVE
::Storage
::vdisk_free
($storecfg, $snap->{vmstate
}); };
4000 die $err if !$force;
4003 # save changes (remove vmstate from snapshot)
4004 lock_config
($vmid, $updatefn, 'vmstate') if !$force;
4007 # now remove all internal snapshots
4008 foreach_drive
($snap, sub {
4009 my ($ds, $drive) = @_;
4011 return if drive_is_cdrom
($drive);
4013 my $volid = $drive->{file
};
4014 my $device = "drive-$ds";
4016 if (!$drivehash || $drivehash->{$ds}) {
4017 eval { qemu_volume_snapshot_delete
($vmid, $device, $storecfg, $volid, $snapname); };
4019 die $err if !$force;
4024 # save changes (remove drive fron snapshot)
4025 lock_config
($vmid, $updatefn, $ds) if !$force;
4026 push @$unused, $volid;
4029 # now cleanup config
4031 lock_config
($vmid, $updatefn);