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
::Cluster
qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
29 use Time
::HiRes
qw(gettimeofday);
31 my $cpuinfo = PVE
::ProcFSTools
::read_cpuinfo
();
33 # Note about locking: we use flock on the config file protect
34 # against concurent actions.
35 # Aditionaly, we have a 'lock' setting in the config file. This
36 # can be set to 'migrate', 'backup', 'snapshot' or 'rollback'. Most actions are not
37 # allowed when such lock is set. But you can ignore this kind of
38 # lock with the --skiplock flag.
40 cfs_register_file
('/qemu-server/',
44 PVE
::JSONSchema
::register_standard_option
('skiplock', {
45 description
=> "Ignore locks - only root is allowed to use this option.",
50 PVE
::JSONSchema
::register_standard_option
('pve-qm-stateuri', {
51 description
=> "Some command save/restore state from this location.",
57 PVE
::JSONSchema
::register_standard_option
('pve-snapshot-name', {
58 description
=> "The name of the snapshot.",
59 type
=> 'string', format
=> 'pve-configid',
63 #no warnings 'redefine';
65 unless(defined(&_VZSYSCALLS_H_
)) {
66 eval 'sub _VZSYSCALLS_H_ () {1;}' unless defined(&_VZSYSCALLS_H_
);
67 require 'sys/syscall.ph';
68 if(defined(&__x86_64__
)) {
69 eval 'sub __NR_fairsched_vcpus () {499;}' unless defined(&__NR_fairsched_vcpus
);
70 eval 'sub __NR_fairsched_mknod () {504;}' unless defined(&__NR_fairsched_mknod
);
71 eval 'sub __NR_fairsched_rmnod () {505;}' unless defined(&__NR_fairsched_rmnod
);
72 eval 'sub __NR_fairsched_chwt () {506;}' unless defined(&__NR_fairsched_chwt
);
73 eval 'sub __NR_fairsched_mvpr () {507;}' unless defined(&__NR_fairsched_mvpr
);
74 eval 'sub __NR_fairsched_rate () {508;}' unless defined(&__NR_fairsched_rate
);
75 eval 'sub __NR_setluid () {501;}' unless defined(&__NR_setluid
);
76 eval 'sub __NR_setublimit () {502;}' unless defined(&__NR_setublimit
);
78 elsif(defined( &__i386__
) ) {
79 eval 'sub __NR_fairsched_mknod () {500;}' unless defined(&__NR_fairsched_mknod
);
80 eval 'sub __NR_fairsched_rmnod () {501;}' unless defined(&__NR_fairsched_rmnod
);
81 eval 'sub __NR_fairsched_chwt () {502;}' unless defined(&__NR_fairsched_chwt
);
82 eval 'sub __NR_fairsched_mvpr () {503;}' unless defined(&__NR_fairsched_mvpr
);
83 eval 'sub __NR_fairsched_rate () {504;}' unless defined(&__NR_fairsched_rate
);
84 eval 'sub __NR_fairsched_vcpus () {505;}' unless defined(&__NR_fairsched_vcpus
);
85 eval 'sub __NR_setluid () {511;}' unless defined(&__NR_setluid
);
86 eval 'sub __NR_setublimit () {512;}' unless defined(&__NR_setublimit
);
88 die("no fairsched syscall for this arch");
90 require 'asm/ioctl.ph';
91 eval 'sub KVM_GET_API_VERSION () { &_IO(0xAE, 0x);}' unless defined(&KVM_GET_API_VERSION
);
95 my ($parent, $weight, $desired) = @_;
97 return syscall(&__NR_fairsched_mknod
, int($parent), int($weight), int($desired));
100 sub fairsched_rmnod
{
103 return syscall(&__NR_fairsched_rmnod
, int($id));
107 my ($pid, $newid) = @_;
109 return syscall(&__NR_fairsched_mvpr
, int($pid), int($newid));
112 sub fairsched_vcpus
{
113 my ($id, $vcpus) = @_;
115 return syscall(&__NR_fairsched_vcpus
, int($id), int($vcpus));
119 my ($id, $op, $rate) = @_;
121 return syscall(&__NR_fairsched_rate
, int($id), int($op), int($rate));
124 use constant FAIRSCHED_SET_RATE
=> 0;
125 use constant FAIRSCHED_DROP_RATE
=> 1;
126 use constant FAIRSCHED_GET_RATE
=> 2;
128 sub fairsched_cpulimit
{
129 my ($id, $limit) = @_;
131 my $cpulim1024 = int($limit * 1024 / 100);
132 my $op = $cpulim1024 ? FAIRSCHED_SET_RATE
: FAIRSCHED_DROP_RATE
;
134 return fairsched_rate
($id, $op, $cpulim1024);
137 my $nodename = PVE
::INotify
::nodename
();
139 mkdir "/etc/pve/nodes/$nodename";
140 my $confdir = "/etc/pve/nodes/$nodename/qemu-server";
143 my $var_run_tmpdir = "/var/run/qemu-server";
144 mkdir $var_run_tmpdir;
146 my $lock_dir = "/var/lock/qemu-server";
149 my $pcisysfs = "/sys/bus/pci";
155 description
=> "Specifies whether a VM will be started during system bootup.",
161 description
=> "Automatic restart after crash (currently ignored).",
167 description
=> "Activate hotplug for disk and network device",
173 description
=> "Allow reboot. If set to '0' the VM exit on reboot.",
179 description
=> "Lock/unlock the VM.",
180 enum
=> [qw(migrate backup snapshot rollback)],
185 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.",
192 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.",
200 description
=> "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.",
207 description
=> "Amount of target RAM for the VM in MB.",
213 description
=> "Keybord layout for vnc server. Default is read from the datacenter configuration file.",
214 enum
=> PVE
::Tools
::kvmkeymaplist
(),
219 type
=> 'string', format
=> 'dns-name',
220 description
=> "Set a name for the VM. Only used on the configuration web interface.",
225 description
=> "scsi controller model",
226 enum
=> [qw(lsi virtio-scsi-pci megasas)],
232 description
=> "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.",
237 enum
=> [qw(other wxp w2k w2k3 w2k8 wvista win7 l24 l26)],
238 description
=> <<EODESC,
239 Used to enable special optimization/features for specific
242 other => unspecified OS
243 wxp => Microsoft Windows XP
244 w2k => Microsoft Windows 2000
245 w2k3 => Microsoft Windows 2003
246 w2k8 => Microsoft Windows 2008
247 wvista => Microsoft Windows Vista
248 win7 => Microsoft Windows 7
249 l24 => Linux 2.4 Kernel
250 l26 => Linux 2.6/3.X Kernel
252 other|l24|l26 ... no special behaviour
253 wxp|w2k|w2k3|w2k8|wvista|win7 ... use --localtime switch
259 description
=> "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n).",
260 pattern
=> '[acdn]{1,4}',
265 type
=> 'string', format
=> 'pve-qm-bootdisk',
266 description
=> "Enable booting from specified disk.",
267 pattern
=> '(ide|sata|scsi|virtio)\d+',
272 description
=> "The number of CPUs. Please use option -sockets instead.",
279 description
=> "The number of CPU sockets.",
286 description
=> "The number of cores per socket.",
293 description
=> "Enable/disable ACPI.",
299 description
=> "Enable/disable Qemu GuestAgent.",
305 description
=> "Enable/disable KVM hardware virtualization.",
311 description
=> "Enable/disable time drift fix. This is ignored for kvm versions newer that 1.0 (not needed anymore).",
317 description
=> "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
322 description
=> "Freeze CPU at startup (use 'c' monitor command to start execution).",
327 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 win7/w2k8, and 'cirrur' for other OS types",
328 enum
=> [qw(std cirrus vmware)],
332 type
=> 'string', format
=> 'pve-qm-watchdog',
333 typetext
=> '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
334 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)",
339 typetext
=> "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
340 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'.",
341 pattern
=> '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
346 type
=> 'string', format
=> 'pve-qm-startup',
347 typetext
=> '[[order=]\d+] [,up=\d+] [,down=\d+] ',
348 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.",
353 description
=> <<EODESCR,
354 Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
356 args: -no-reboot -no-hpet
363 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.",
368 description
=> "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
372 migrate_downtime
=> {
375 description
=> "Set maximum tolerated downtime (in seconds) for migrations.",
381 type
=> 'string', format
=> 'pve-qm-drive',
382 typetext
=> 'volume',
383 description
=> "This is an alias for option -ide2",
387 description
=> "Emulated CPU type.",
389 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 # what about other qemu settings ?
396 #machine => 'string',
409 ##soundhw => 'string',
411 while (my ($k, $v) = each %$confdesc) {
412 PVE
::JSONSchema
::register_standard_option
("pve-qm-$k", $v);
415 my $MAX_IDE_DISKS = 4;
416 my $MAX_SCSI_DISKS = 14;
417 my $MAX_VIRTIO_DISKS = 16;
418 my $MAX_SATA_DISKS = 6;
419 my $MAX_USB_DEVICES = 5;
421 my $MAX_UNUSED_DISKS = 8;
422 my $MAX_HOSTPCI_DEVICES = 2;
423 my $MAX_SERIAL_PORTS = 4;
424 my $MAX_PARALLEL_PORTS = 3;
426 my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
427 'ne2k_isa', 'i82551', 'i82557b', 'i82559er'];
428 my $nic_model_list_txt = join(' ', sort @$nic_model_list);
433 type
=> 'string', format
=> 'pve-qm-net',
434 typetext
=> "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,rate=<mbps>][,tag=<vlanid>]",
435 description
=> <<EODESCR,
436 Specify network devices.
438 MODEL is one of: $nic_model_list_txt
440 XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
441 automatically generated if not specified.
443 The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
445 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'.
447 If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
453 The DHCP server assign addresses to the guest starting from 10.0.2.15.
457 PVE
::JSONSchema
::register_standard_option
("pve-qm-net", $netdesc);
459 for (my $i = 0; $i < $MAX_NETS; $i++) {
460 $confdesc->{"net$i"} = $netdesc;
467 type
=> 'string', format
=> 'pve-qm-drive',
468 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]',
469 description
=> "Use volume as IDE hard disk or CD-ROM (n is 0 to " .($MAX_IDE_DISKS -1) . ").",
471 PVE
::JSONSchema
::register_standard_option
("pve-qm-ide", $idedesc);
475 type
=> 'string', format
=> 'pve-qm-drive',
476 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]',
477 description
=> "Use volume as SCSI hard disk or CD-ROM (n is 0 to " . ($MAX_SCSI_DISKS - 1) . ").",
479 PVE
::JSONSchema
::register_standard_option
("pve-qm-scsi", $scsidesc);
483 type
=> 'string', format
=> 'pve-qm-drive',
484 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]',
485 description
=> "Use volume as SATA hard disk or CD-ROM (n is 0 to " . ($MAX_SATA_DISKS - 1). ").",
487 PVE
::JSONSchema
::register_standard_option
("pve-qm-sata", $satadesc);
491 type
=> 'string', format
=> 'pve-qm-drive',
492 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]',
493 description
=> "Use volume as VIRTIO hard disk (n is 0 to " . ($MAX_VIRTIO_DISKS - 1) . ").",
495 PVE
::JSONSchema
::register_standard_option
("pve-qm-virtio", $virtiodesc);
499 type
=> 'string', format
=> 'pve-qm-usb-device',
500 typetext
=> 'host=HOSTUSBDEVICE',
501 description
=> <<EODESCR,
502 Configure an USB device (n is 0 to 4). This can be used to
503 pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
505 'bus-port(.port)*' (decimal numbers) or
506 'vendor_id:product_id' (hexadeciaml numbers)
508 You can use the 'lsusb -t' command to list existing usb devices.
510 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
514 PVE
::JSONSchema
::register_standard_option
("pve-qm-usb", $usbdesc);
518 type
=> 'string', format
=> 'pve-qm-hostpci',
519 typetext
=> "HOSTPCIDEVICE",
520 description
=> <<EODESCR,
521 Map host pci devices. HOSTPCIDEVICE syntax is:
523 'bus:dev.func' (hexadecimal numbers)
525 You can us the 'lspci' command to list existing pci 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.
529 Experimental: user reported problems with this option.
532 PVE
::JSONSchema
::register_standard_option
("pve-qm-hostpci", $hostpcidesc);
537 pattern
=> '/dev/ttyS\d+',
538 description
=> <<EODESCR,
539 Map host serial devices (n is 0 to 3).
541 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
543 Experimental: user reported problems with this option.
550 pattern
=> '/dev/parport\d+',
551 description
=> <<EODESCR,
552 Map host parallel devices (n is 0 to 2).
554 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
556 Experimental: user reported problems with this option.
560 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
561 $confdesc->{"parallel$i"} = $paralleldesc;
564 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
565 $confdesc->{"serial$i"} = $serialdesc;
568 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
569 $confdesc->{"hostpci$i"} = $hostpcidesc;
572 for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
573 $drivename_hash->{"ide$i"} = 1;
574 $confdesc->{"ide$i"} = $idedesc;
577 for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
578 $drivename_hash->{"sata$i"} = 1;
579 $confdesc->{"sata$i"} = $satadesc;
582 for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
583 $drivename_hash->{"scsi$i"} = 1;
584 $confdesc->{"scsi$i"} = $scsidesc ;
587 for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
588 $drivename_hash->{"virtio$i"} = 1;
589 $confdesc->{"virtio$i"} = $virtiodesc;
592 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
593 $confdesc->{"usb$i"} = $usbdesc;
598 type
=> 'string', format
=> 'pve-volume-id',
599 description
=> "Reference to unused volumes.",
602 for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
603 $confdesc->{"unused$i"} = $unuseddesc;
606 my $kvm_api_version = 0;
610 return $kvm_api_version if $kvm_api_version;
612 my $fh = IO
::File-
>new("</dev/kvm") ||
615 if (my $v = $fh->ioctl(KVM_GET_API_VERSION
(), 0)) {
616 $kvm_api_version = $v;
621 return $kvm_api_version;
624 my $kvm_user_version;
626 sub kvm_user_version
{
628 return $kvm_user_version if $kvm_user_version;
630 $kvm_user_version = 'unknown';
632 my $tmp = `kvm -help 2>/dev/null`;
634 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?) /) {
635 $kvm_user_version = $2;
638 return $kvm_user_version;
642 my $kernel_has_vhost_net = -c
'/dev/vhost-net';
645 # order is important - used to autoselect boot disk
646 return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
647 (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
648 (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
649 (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
652 sub valid_drivename
{
655 return defined($drivename_hash->{$dev});
660 return defined($confdesc->{$key});
664 return $nic_model_list;
667 sub os_list_description
{
672 w2k
=> 'Windows 2000',
673 w2k3
=>, 'Windows 2003',
674 w2k8
=> 'Windows 2008',
675 wvista
=> 'Windows Vista',
686 return $cdrom_path if $cdrom_path;
688 return $cdrom_path = "/dev/cdrom" if -l
"/dev/cdrom";
689 return $cdrom_path = "/dev/cdrom1" if -l
"/dev/cdrom1";
690 return $cdrom_path = "/dev/cdrom2" if -l
"/dev/cdrom2";
694 my ($storecfg, $vmid, $cdrom) = @_;
696 if ($cdrom eq 'cdrom') {
697 return get_cdrom_path
();
698 } elsif ($cdrom eq 'none') {
700 } elsif ($cdrom =~ m
|^/|) {
703 return PVE
::Storage
::path
($storecfg, $cdrom);
707 # try to convert old style file names to volume IDs
708 sub filename_to_volume_id
{
709 my ($vmid, $file, $media) = @_;
711 if (!($file eq 'none' || $file eq 'cdrom' ||
712 $file =~ m
|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
714 return undef if $file =~ m
|/|;
716 if ($media && $media eq 'cdrom') {
717 $file = "local:iso/$file";
719 $file = "local:$vmid/$file";
726 sub verify_media_type
{
727 my ($opt, $vtype, $media) = @_;
732 if ($media eq 'disk') {
734 } elsif ($media eq 'cdrom') {
737 die "internal error";
740 return if ($vtype eq $etype);
742 raise_param_exc
({ $opt => "unexpected media type ($vtype != $etype)" });
745 sub cleanup_drive_path
{
746 my ($opt, $storecfg, $drive) = @_;
748 # try to convert filesystem paths to volume IDs
750 if (($drive->{file
} !~ m/^(cdrom|none)$/) &&
751 ($drive->{file
} !~ m
|^/dev/.+|) &&
752 ($drive->{file
} !~ m/^([^:]+):(.+)$/) &&
753 ($drive->{file
} !~ m/^\d+$/)) {
754 my ($vtype, $volid) = PVE
::Storage
::path_to_volume_id
($storecfg, $drive->{file
});
755 raise_param_exc
({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
756 $drive->{media
} = 'cdrom' if !$drive->{media
} && $vtype eq 'iso';
757 verify_media_type
($opt, $vtype, $drive->{media
});
758 $drive->{file
} = $volid;
761 $drive->{media
} = 'cdrom' if !$drive->{media
} && $drive->{file
} =~ m/^(cdrom|none)$/;
764 sub create_conf_nolock
{
765 my ($vmid, $settings) = @_;
767 my $filename = config_file
($vmid);
769 die "configuration file '$filename' already exists\n" if -f
$filename;
771 my $defaults = load_defaults
();
773 $settings->{name
} = "vm$vmid" if !$settings->{name
};
774 $settings->{memory
} = $defaults->{memory
} if !$settings->{memory
};
777 foreach my $opt (keys %$settings) {
778 next if !$confdesc->{$opt};
780 my $value = $settings->{$opt};
783 $data .= "$opt: $value\n";
786 PVE
::Tools
::file_set_contents
($filename, $data);
789 my $parse_size = sub {
792 return undef if $value !~ m/^(\d+(\.\d+)?)([KMG])?$/;
793 my ($size, $unit) = ($1, $3);
796 $size = $size * 1024;
797 } elsif ($unit eq 'M') {
798 $size = $size * 1024 * 1024;
799 } elsif ($unit eq 'G') {
800 $size = $size * 1024 * 1024 * 1024;
806 my $format_size = sub {
811 my $kb = int($size/1024);
812 return $size if $kb*1024 != $size;
814 my $mb = int($kb/1024);
815 return "${kb}K" if $mb*1024 != $kb;
817 my $gb = int($mb/1024);
818 return "${mb}M" if $gb*1024 != $mb;
823 # ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
824 # [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
825 # [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
826 # [,aio=native|threads]
829 my ($key, $data) = @_;
833 # $key may be undefined - used to verify JSON parameters
834 if (!defined($key)) {
835 $res->{interface
} = 'unknown'; # should not harm when used to verify parameters
837 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
838 $res->{interface
} = $1;
844 foreach my $p (split (/,/, $data)) {
845 next if $p =~ m/^\s*$/;
847 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)=(.+)$/) {
848 my ($k, $v) = ($1, $2);
850 $k = 'file' if $k eq 'volume';
852 return undef if defined $res->{$k};
854 if ($k eq 'bps' || $k eq 'bps_rd' || $k eq 'bps_wr') {
855 return undef if !$v || $v !~ m/^\d+/;
857 $v = sprintf("%.3f", $v / (1024*1024));
861 if (!$res->{file
} && $p !~ m/=/) {
869 return undef if !$res->{file
};
871 return undef if $res->{cache
} &&
872 $res->{cache
} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
873 return undef if $res->{snapshot
} && $res->{snapshot
} !~ m/^(on|off)$/;
874 return undef if $res->{cyls
} && $res->{cyls
} !~ m/^\d+$/;
875 return undef if $res->{heads
} && $res->{heads
} !~ m/^\d+$/;
876 return undef if $res->{secs
} && $res->{secs
} !~ m/^\d+$/;
877 return undef if $res->{media
} && $res->{media
} !~ m/^(disk|cdrom)$/;
878 return undef if $res->{trans
} && $res->{trans
} !~ m/^(none|lba|auto)$/;
879 return undef if $res->{format
} && $res->{format
} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
880 return undef if $res->{rerror
} && $res->{rerror
} !~ m/^(ignore|report|stop)$/;
881 return undef if $res->{werror
} && $res->{werror
} !~ m/^(enospc|ignore|report|stop)$/;
882 return undef if $res->{backup
} && $res->{backup
} !~ m/^(yes|no)$/;
883 return undef if $res->{aio
} && $res->{aio
} !~ m/^(native|threads)$/;
886 return undef if $res->{mbps_rd
} && $res->{mbps
};
887 return undef if $res->{mbps_wr
} && $res->{mbps
};
889 return undef if $res->{mbps
} && $res->{mbps
} !~ m/^\d+(\.\d+)?$/;
890 return undef if $res->{mbps_rd
} && $res->{mbps_rd
} !~ m/^\d+(\.\d+)?$/;
891 return undef if $res->{mbps_wr
} && $res->{mbps_wr
} !~ m/^\d+(\.\d+)?$/;
893 return undef if $res->{iops_rd
} && $res->{iops
};
894 return undef if $res->{iops_wr
} && $res->{iops
};
895 return undef if $res->{iops
} && $res->{iops
} !~ m/^\d+$/;
896 return undef if $res->{iops_rd
} && $res->{iops_rd
} !~ m/^\d+$/;
897 return undef if $res->{iops_wr
} && $res->{iops_wr
} !~ m/^\d+$/;
901 return undef if !defined($res->{size
} = &$parse_size($res->{size
}));
904 if ($res->{media
} && ($res->{media
} eq 'cdrom')) {
905 return undef if $res->{snapshot
} || $res->{trans
} || $res->{format
};
906 return undef if $res->{heads
} || $res->{secs
} || $res->{cyls
};
907 return undef if $res->{interface
} eq 'virtio';
910 # rerror does not work with scsi drives
911 if ($res->{rerror
}) {
912 return undef if $res->{interface
} eq 'scsi';
918 my @qemu_drive_options = qw(heads secs cyls trans media format cache snapshot rerror werror aio iops iops_rd iops_wr);
921 my ($vmid, $drive) = @_;
924 foreach my $o (@qemu_drive_options, 'mbps', 'mbps_rd', 'mbps_wr', 'backup') {
925 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
928 if ($drive->{size
}) {
929 $opts .= ",size=" . &$format_size($drive->{size
});
932 return "$drive->{file}$opts";
936 my($fh, $noerr) = @_;
939 my $SG_GET_VERSION_NUM = 0x2282;
941 my $versionbuf = "\x00" x
8;
942 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
944 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
947 my $version = unpack("I", $versionbuf);
948 if ($version < 30000) {
949 die "scsi generic interface too old\n" if !$noerr;
953 my $buf = "\x00" x
36;
954 my $sensebuf = "\x00" x
8;
955 my $cmd = pack("C x3 C x11", 0x12, 36);
957 # see /usr/include/scsi/sg.h
958 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";
960 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
961 length($sensebuf), 0, length($buf), $buf,
962 $cmd, $sensebuf, 6000);
964 $ret = ioctl($fh, $SG_IO, $packet);
966 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
970 my @res = unpack($sg_io_hdr_t, $packet);
971 if ($res[17] || $res[18]) {
972 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
977 ($res->{device
}, $res->{removable
}, $res->{venodor
},
978 $res->{product
}, $res->{revision
}) = unpack("C C x6 A8 A16 A4", $buf);
986 my $fh = IO
::File-
>new("+<$path") || return undef;
987 my $res = scsi_inquiry
($fh, 1);
993 sub print_drivedevice_full
{
994 my ($storecfg, $conf, $vmid, $drive, $bridges) = @_;
999 if ($drive->{interface
} eq 'virtio') {
1000 my $pciaddr = print_pci_addr
("$drive->{interface}$drive->{index}", $bridges);
1001 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
1002 } elsif ($drive->{interface
} eq 'scsi') {
1003 $maxdev = ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi') ?
256 : 7;
1004 my $controller = int($drive->{index} / $maxdev);
1005 my $unit = $drive->{index} % $maxdev;
1006 my $devicetype = 'hd';
1008 if (drive_is_cdrom
($drive)) {
1011 if ($drive->{file
} =~ m
|^/|) {
1012 $path = $drive->{file
};
1014 $path = PVE
::Storage
::path
($storecfg, $drive->{file
});
1017 if($path =~ m/^iscsi\:\/\
//){
1018 $devicetype = 'generic';
1021 $devicetype = 'block' if path_is_scsi
($path);
1025 if (!$conf->{scsihw
} || $conf->{scsihw
} eq 'lsi'){
1026 $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';
1028 $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}";
1031 } elsif ($drive->{interface
} eq 'ide'){
1033 my $controller = int($drive->{index} / $maxdev);
1034 my $unit = $drive->{index} % $maxdev;
1035 my $devicetype = ($drive->{media
} && $drive->{media
} eq 'cdrom') ?
"cd" : "hd";
1037 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1038 } elsif ($drive->{interface
} eq 'sata'){
1039 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
1040 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1041 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1042 } elsif ($drive->{interface
} eq 'usb') {
1044 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1046 die "unsupported interface type";
1049 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex
};
1054 sub print_drive_full
{
1055 my ($storecfg, $vmid, $drive) = @_;
1058 foreach my $o (@qemu_drive_options) {
1059 next if $o eq 'bootindex';
1060 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
1063 foreach my $o (qw(bps bps_rd bps_wr)) {
1064 my $v = $drive->{"m$o"};
1065 $opts .= ",$o=" . int($v*1024*1024) if $v;
1068 # use linux-aio by default (qemu default is threads)
1069 $opts .= ",aio=native" if !$drive->{aio
};
1072 my $volid = $drive->{file
};
1073 if (drive_is_cdrom
($drive)) {
1074 $path = get_iso_path
($storecfg, $vmid, $volid);
1076 if ($volid =~ m
|^/|) {
1079 $path = PVE
::Storage
::path
($storecfg, $volid);
1081 if (!$drive->{cache
} && ($path =~ m
|^/dev/| || $path =~ m
|\
.raw
$|)) {
1082 $opts .= ",cache=none";
1086 my $pathinfo = $path ?
"file=$path," : '';
1088 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1091 sub print_netdevice_full
{
1092 my ($vmid, $conf, $net, $netid, $bridges) = @_;
1094 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
1096 my $device = $net->{model
};
1097 if ($net->{model
} eq 'virtio') {
1098 $device = 'virtio-net-pci';
1101 # qemu > 0.15 always try to boot from network - we disable that by
1102 # not loading the pxe rom file
1103 my $extra = ($bootorder !~ m/n/) ?
"romfile=," : '';
1104 my $pciaddr = print_pci_addr
("$netid", $bridges);
1105 my $tmpstr = "$device,${extra}mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
1106 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex
} ;
1110 sub print_netdev_full
{
1111 my ($vmid, $conf, $net, $netid) = @_;
1114 if ($netid =~ m/^net(\d+)$/) {
1118 die "got strange net id '$i'\n" if $i >= ${MAX_NETS
};
1120 my $ifname = "tap${vmid}i$i";
1122 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1123 die "interface name '$ifname' is too long (max 15 character)\n"
1124 if length($ifname) >= 16;
1126 my $vhostparam = '';
1127 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model
} eq 'virtio';
1129 my $vmname = $conf->{name
} || "vm$vmid";
1131 if ($net->{bridge
}) {
1132 return "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge$vhostparam";
1134 return "type=user,id=$netid,hostname=$vmname";
1138 sub drive_is_cdrom
{
1141 return $drive && $drive->{media
} && ($drive->{media
} eq 'cdrom');
1148 return undef if !$value;
1152 if ($value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/) {
1153 $res->{pciid
} = $value;
1161 # netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1167 foreach my $kvp (split(/,/, $data)) {
1169 if ($kvp =~ m/^(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
1171 my $mac = uc($3) || PVE
::Tools
::random_ether_addr
();
1172 $res->{model
} = $model;
1173 $res->{macaddr
} = $mac;
1174 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1175 $res->{bridge
} = $1;
1176 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1178 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1186 return undef if !$res->{model
};
1194 my $res = "$net->{model}";
1195 $res .= "=$net->{macaddr}" if $net->{macaddr
};
1196 $res .= ",bridge=$net->{bridge}" if $net->{bridge
};
1197 $res .= ",rate=$net->{rate}" if $net->{rate
};
1198 $res .= ",tag=$net->{tag}" if $net->{tag
};
1203 sub add_random_macs
{
1204 my ($settings) = @_;
1206 foreach my $opt (keys %$settings) {
1207 next if $opt !~ m/^net(\d+)$/;
1208 my $net = parse_net
($settings->{$opt});
1210 $settings->{$opt} = print_net
($net);
1214 sub add_unused_volume
{
1215 my ($config, $volid) = @_;
1218 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1219 my $test = "unused$ind";
1220 if (my $vid = $config->{$test}) {
1221 return if $vid eq $volid; # do not add duplicates
1227 die "To many unused volume - please delete them first.\n" if !$key;
1229 $config->{$key} = $volid;
1234 # fixme: remove all thos $noerr parameters?
1236 PVE
::JSONSchema
::register_format
('pve-qm-bootdisk', \
&verify_bootdisk
);
1237 sub verify_bootdisk
{
1238 my ($value, $noerr) = @_;
1240 return $value if valid_drivename
($value);
1242 return undef if $noerr;
1244 die "invalid boot disk '$value'\n";
1247 PVE
::JSONSchema
::register_format
('pve-qm-net', \
&verify_net
);
1249 my ($value, $noerr) = @_;
1251 return $value if parse_net
($value);
1253 return undef if $noerr;
1255 die "unable to parse network options\n";
1258 PVE
::JSONSchema
::register_format
('pve-qm-drive', \
&verify_drive
);
1260 my ($value, $noerr) = @_;
1262 return $value if parse_drive
(undef, $value);
1264 return undef if $noerr;
1266 die "unable to parse drive options\n";
1269 PVE
::JSONSchema
::register_format
('pve-qm-hostpci', \
&verify_hostpci
);
1270 sub verify_hostpci
{
1271 my ($value, $noerr) = @_;
1273 return $value if parse_hostpci
($value);
1275 return undef if $noerr;
1277 die "unable to parse pci id\n";
1280 PVE
::JSONSchema
::register_format
('pve-qm-watchdog', \
&verify_watchdog
);
1281 sub verify_watchdog
{
1282 my ($value, $noerr) = @_;
1284 return $value if parse_watchdog
($value);
1286 return undef if $noerr;
1288 die "unable to parse watchdog options\n";
1291 sub parse_watchdog
{
1294 return undef if !$value;
1298 foreach my $p (split(/,/, $value)) {
1299 next if $p =~ m/^\s*$/;
1301 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1303 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1304 $res->{action
} = $2;
1313 PVE
::JSONSchema
::register_format
('pve-qm-startup', \
&verify_startup
);
1314 sub verify_startup
{
1315 my ($value, $noerr) = @_;
1317 return $value if parse_startup
($value);
1319 return undef if $noerr;
1321 die "unable to parse startup options\n";
1327 return undef if !$value;
1331 foreach my $p (split(/,/, $value)) {
1332 next if $p =~ m/^\s*$/;
1334 if ($p =~ m/^(order=)?(\d+)$/) {
1336 } elsif ($p =~ m/^up=(\d+)$/) {
1338 } elsif ($p =~ m/^down=(\d+)$/) {
1348 sub parse_usb_device
{
1351 return undef if !$value;
1353 my @dl = split(/,/, $value);
1357 foreach my $v (@dl) {
1358 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1360 $res->{vendorid
} = $2;
1361 $res->{productid
} = $4;
1362 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1364 $res->{hostbus
} = $1;
1365 $res->{hostport
} = $2;
1370 return undef if !$found;
1375 PVE
::JSONSchema
::register_format
('pve-qm-usb-device', \
&verify_usb_device
);
1376 sub verify_usb_device
{
1377 my ($value, $noerr) = @_;
1379 return $value if parse_usb_device
($value);
1381 return undef if $noerr;
1383 die "unable to parse usb device\n";
1386 # add JSON properties for create and set function
1387 sub json_config_properties
{
1390 foreach my $opt (keys %$confdesc) {
1391 $prop->{$opt} = $confdesc->{$opt};
1398 my ($key, $value) = @_;
1400 die "unknown setting '$key'\n" if !$confdesc->{$key};
1402 my $type = $confdesc->{$key}->{type
};
1404 if (!defined($value)) {
1405 die "got undefined value\n";
1408 if ($value =~ m/[\n\r]/) {
1409 die "property contains a line feed\n";
1412 if ($type eq 'boolean') {
1413 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1414 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1415 die "type check ('boolean') failed - got '$value'\n";
1416 } elsif ($type eq 'integer') {
1417 return int($1) if $value =~ m/^(\d+)$/;
1418 die "type check ('integer') failed - got '$value'\n";
1419 } elsif ($type eq 'string') {
1420 if (my $fmt = $confdesc->{$key}->{format
}) {
1421 if ($fmt eq 'pve-qm-drive') {
1422 # special case - we need to pass $key to parse_drive()
1423 my $drive = parse_drive
($key, $value);
1424 return $value if $drive;
1425 die "unable to parse drive options\n";
1427 PVE
::JSONSchema
::check_format
($fmt, $value);
1430 $value =~ s/^\"(.*)\"$/$1/;
1433 die "internal error"
1437 sub lock_config_full
{
1438 my ($vmid, $timeout, $code, @param) = @_;
1440 my $filename = config_file_lock
($vmid);
1442 my $res = lock_file
($filename, $timeout, $code, @param);
1450 my ($vmid, $code, @param) = @_;
1452 return lock_config_full
($vmid, 10, $code, @param);
1455 sub cfs_config_path
{
1456 my ($vmid, $node) = @_;
1458 $node = $nodename if !$node;
1459 return "nodes/$node/qemu-server/$vmid.conf";
1462 sub check_iommu_support
{
1463 #fixme : need to check IOMMU support
1464 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1472 my ($vmid, $node) = @_;
1474 my $cfspath = cfs_config_path
($vmid, $node);
1475 return "/etc/pve/$cfspath";
1478 sub config_file_lock
{
1481 return "$lock_dir/lock-$vmid.conf";
1487 my $conf = config_file
($vmid);
1488 utime undef, undef, $conf;
1492 my ($storecfg, $vmid, $keep_empty_config) = @_;
1494 my $conffile = config_file
($vmid);
1496 my $conf = load_config
($vmid);
1500 # only remove disks owned by this VM
1501 foreach_drive
($conf, sub {
1502 my ($ds, $drive) = @_;
1504 return if drive_is_cdrom
($drive);
1506 my $volid = $drive->{file
};
1507 return if !$volid || $volid =~ m
|^/|;
1509 my ($path, $owner) = PVE
::Storage
::path
($storecfg, $volid);
1510 return if !$path || !$owner || ($owner != $vmid);
1512 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1515 if ($keep_empty_config) {
1516 PVE
::Tools
::file_set_contents
($conffile, "memory: 128\n");
1521 # also remove unused disk
1523 my $dl = PVE
::Storage
::vdisk_list
($storecfg, undef, $vmid);
1526 PVE
::Storage
::foreach_volid
($dl, sub {
1527 my ($volid, $sid, $volname, $d) = @_;
1528 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1538 my ($vmid, $node) = @_;
1540 my $cfspath = cfs_config_path
($vmid, $node);
1542 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath);
1544 die "no such VM ('$vmid')\n" if !defined($conf);
1549 sub parse_vm_config
{
1550 my ($filename, $raw) = @_;
1552 return undef if !defined($raw);
1555 digest
=> Digest
::SHA
::sha1_hex
($raw),
1559 $filename =~ m
|/qemu-server/(\d
+)\
.conf
$|
1560 || die "got strange filename '$filename'";
1567 my @lines = split(/\n/, $raw);
1568 foreach my $line (@lines) {
1569 next if $line =~ m/^\s*$/;
1571 if ($line =~ m/^\[([a-z][a-z0-9_\-]+)\]\s*$/i) {
1573 $conf->{description
} = $descr if $descr;
1575 $conf = $res->{snapshots
}->{$snapname} = {};
1579 if ($line =~ m/^\#(.*)\s*$/) {
1580 $descr .= PVE
::Tools
::decode_text
($1) . "\n";
1584 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
1585 $descr .= PVE
::Tools
::decode_text
($2);
1586 } elsif ($line =~ m/parent:\s*([a-z][a-z0-9_\-]+)\s*$/) {
1587 $conf->{parent
} = $1;
1588 } elsif ($line =~ m/snapstate:\s*(prepare|delete)\s*$/) {
1589 $conf->{snapstate
} = $1;
1590 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1593 $conf->{$key} = $value;
1594 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1597 eval { $value = check_type
($key, $value); };
1599 warn "vm $vmid - unable to parse value of '$key' - $@";
1601 my $fmt = $confdesc->{$key}->{format
};
1602 if ($fmt && $fmt eq 'pve-qm-drive') {
1603 my $v = parse_drive
($key, $value);
1604 if (my $volid = filename_to_volume_id
($vmid, $v->{file
}, $v->{media
})) {
1605 $v->{file
} = $volid;
1606 $value = print_drive
($vmid, $v);
1608 warn "vm $vmid - unable to parse value of '$key'\n";
1613 if ($key eq 'cdrom') {
1614 $conf->{ide2
} = $value;
1616 $conf->{$key} = $value;
1622 $conf->{description
} = $descr if $descr;
1624 delete $res->{snapstate
}; # just to be sure
1629 sub write_vm_config
{
1630 my ($filename, $conf) = @_;
1632 delete $conf->{snapstate
}; # just to be sure
1634 if ($conf->{cdrom
}) {
1635 die "option ide2 conflicts with cdrom\n" if $conf->{ide2
};
1636 $conf->{ide2
} = $conf->{cdrom
};
1637 delete $conf->{cdrom
};
1640 # we do not use 'smp' any longer
1641 if ($conf->{sockets
}) {
1642 delete $conf->{smp
};
1643 } elsif ($conf->{smp
}) {
1644 $conf->{sockets
} = $conf->{smp
};
1645 delete $conf->{cores
};
1646 delete $conf->{smp
};
1649 # fixme: unused drives and snapshots??!!
1651 my $new_volids = {};
1652 foreach my $key (keys %$conf) {
1653 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots';
1654 my $value = $conf->{$key};
1655 eval { $value = check_type
($key, $value); };
1656 die "unable to parse value of '$key' - $@" if $@;
1658 $conf->{$key} = $value;
1660 if (valid_drivename
($key)) {
1661 my $drive = PVE
::QemuServer
::parse_drive
($key, $value);
1662 $new_volids->{$drive->{file
}} = 1 if $drive && $drive->{file
};
1666 # remove 'unusedX' settings if we re-add a volume
1667 foreach my $key (keys %$conf) {
1668 my $value = $conf->{$key};
1669 if ($key =~ m/^unused/ && $new_volids->{$value}) {
1670 delete $conf->{$key};
1674 my $generate_raw_config = sub {
1679 # add description as comment to top of file
1680 my $descr = $conf->{description
} || '';
1681 foreach my $cl (split(/\n/, $descr)) {
1682 $raw .= '#' . PVE
::Tools
::encode_text
($cl) . "\n";
1685 foreach my $key (sort keys %$conf) {
1686 next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots';
1687 $raw .= "$key: $conf->{$key}\n";
1692 my $raw = &$generate_raw_config($conf);
1693 foreach my $snapname (sort keys %{$conf->{snapshots
}}) {
1694 $raw .= "\n[$snapname]\n";
1695 $raw .= &$generate_raw_config($conf->{snapshots
}->{$snapname});
1701 sub update_config_nolock
{
1702 my ($vmid, $conf, $skiplock) = @_;
1704 check_lock
($conf) if !$skiplock;
1706 my $cfspath = cfs_config_path
($vmid);
1708 PVE
::Cluster
::cfs_write_file
($cfspath, $conf);
1712 my ($vmid, $conf, $skiplock) = @_;
1714 lock_config
($vmid, &update_config_nolock
, $conf, $skiplock);
1721 # we use static defaults from our JSON schema configuration
1722 foreach my $key (keys %$confdesc) {
1723 if (defined(my $default = $confdesc->{$key}->{default})) {
1724 $res->{$key} = $default;
1728 my $conf = PVE
::Cluster
::cfs_read_file
('datacenter.cfg');
1729 $res->{keyboard
} = $conf->{keyboard
} if $conf->{keyboard
};
1735 my $vmlist = PVE
::Cluster
::get_vmlist
();
1737 return $res if !$vmlist || !$vmlist->{ids
};
1738 my $ids = $vmlist->{ids
};
1740 foreach my $vmid (keys %$ids) {
1741 my $d = $ids->{$vmid};
1742 next if !$d->{node
} || $d->{node
} ne $nodename;
1743 next if !$d->{type
} || $d->{type
} ne 'qemu';
1744 $res->{$vmid}->{exists} = 1;
1749 # test if VM uses local resources (to prevent migration)
1750 sub check_local_resources
{
1751 my ($conf, $noerr) = @_;
1755 $loc_res = 1 if $conf->{hostusb
}; # old syntax
1756 $loc_res = 1 if $conf->{hostpci
}; # old syntax
1758 foreach my $k (keys %$conf) {
1759 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
1762 die "VM uses local resources\n" if $loc_res && !$noerr;
1767 # check is used storages are available on all nodes (use by migrate)
1768 sub check_storage_availability
{
1769 my ($storecfg, $conf, $node) = @_;
1771 foreach_drive
($conf, sub {
1772 my ($ds, $drive) = @_;
1774 my $volid = $drive->{file
};
1777 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
1780 # check if storage is available on both nodes
1781 my $scfg = PVE
::Storage
::storage_check_node
($storecfg, $sid);
1782 PVE
::Storage
::storage_check_node
($storecfg, $sid, $node);
1789 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1793 my ($pidfile, $pid) = @_;
1795 my $fh = IO
::File-
>new("/proc/$pid/cmdline", "r");
1799 return undef if !$line;
1800 my @param = split(/\0/, $line);
1802 my $cmd = $param[0];
1803 return if !$cmd || ($cmd !~ m
|kvm
$|);
1805 for (my $i = 0; $i < scalar (@param); $i++) {
1808 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1809 my $p = $param[$i+1];
1810 return 1 if $p && ($p eq $pidfile);
1819 my ($vmid, $nocheck, $node) = @_;
1821 my $filename = config_file
($vmid, $node);
1823 die "unable to find configuration file for VM $vmid - no such machine\n"
1824 if !$nocheck && ! -f
$filename;
1826 my $pidfile = pidfile_name
($vmid);
1828 if (my $fd = IO
::File-
>new("<$pidfile")) {
1833 my $mtime = $st->mtime;
1834 if ($mtime > time()) {
1835 warn "file '$filename' modified in future\n";
1838 if ($line =~ m/^(\d+)$/) {
1840 if (check_cmdline
($pidfile, $pid)) {
1841 if (my $pinfo = PVE
::ProcFSTools
::check_process_running
($pid)) {
1853 my $vzlist = config_list
();
1855 my $fd = IO
::Dir-
>new($var_run_tmpdir) || return $vzlist;
1857 while (defined(my $de = $fd->read)) {
1858 next if $de !~ m/^(\d+)\.pid$/;
1860 next if !defined($vzlist->{$vmid});
1861 if (my $pid = check_running
($vmid)) {
1862 $vzlist->{$vmid}->{pid
} = $pid;
1870 my ($storecfg, $conf) = @_;
1872 my $bootdisk = $conf->{bootdisk
};
1873 return undef if !$bootdisk;
1874 return undef if !valid_drivename
($bootdisk);
1876 return undef if !$conf->{$bootdisk};
1878 my $drive = parse_drive
($bootdisk, $conf->{$bootdisk});
1879 return undef if !defined($drive);
1881 return undef if drive_is_cdrom
($drive);
1883 my $volid = $drive->{file
};
1884 return undef if !$volid;
1886 return $drive->{size
};
1889 my $last_proc_pid_stat;
1891 # get VM status information
1892 # This must be fast and should not block ($full == false)
1893 # We only query KVM using QMP if $full == true (this can be slow)
1895 my ($opt_vmid, $full) = @_;
1899 my $storecfg = PVE
::Storage
::config
();
1901 my $list = vzlist
();
1902 my ($uptime) = PVE
::ProcFSTools
::read_proc_uptime
(1);
1904 my $cpucount = $cpuinfo->{cpus
} || 1;
1906 foreach my $vmid (keys %$list) {
1907 next if $opt_vmid && ($vmid ne $opt_vmid);
1909 my $cfspath = cfs_config_path
($vmid);
1910 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath) || {};
1913 $d->{pid
} = $list->{$vmid}->{pid
};
1915 # fixme: better status?
1916 $d->{status
} = $list->{$vmid}->{pid
} ?
'running' : 'stopped';
1918 my $size = disksize
($storecfg, $conf);
1919 if (defined($size)) {
1920 $d->{disk
} = 0; # no info available
1921 $d->{maxdisk
} = $size;
1927 $d->{cpus
} = ($conf->{sockets
} || 1) * ($conf->{cores
} || 1);
1928 $d->{cpus
} = $cpucount if $d->{cpus
} > $cpucount;
1930 $d->{name
} = $conf->{name
} || "VM $vmid";
1931 $d->{maxmem
} = $conf->{memory
} ?
$conf->{memory
}*(1024*1024) : 0;
1941 $d->{diskwrite
} = 0;
1946 my $netdev = PVE
::ProcFSTools
::read_proc_net_dev
();
1947 foreach my $dev (keys %$netdev) {
1948 next if $dev !~ m/^tap([1-9]\d*)i/;
1950 my $d = $res->{$vmid};
1953 $d->{netout
} += $netdev->{$dev}->{receive
};
1954 $d->{netin
} += $netdev->{$dev}->{transmit
};
1957 my $ctime = gettimeofday
;
1959 foreach my $vmid (keys %$list) {
1961 my $d = $res->{$vmid};
1962 my $pid = $d->{pid
};
1965 my $pstat = PVE
::ProcFSTools
::read_proc_pid_stat
($pid);
1966 next if !$pstat; # not running
1968 my $used = $pstat->{utime} + $pstat->{stime
};
1970 $d->{uptime
} = int(($uptime - $pstat->{starttime
})/$cpuinfo->{user_hz
});
1972 if ($pstat->{vsize
}) {
1973 $d->{mem
} = int(($pstat->{rss
}/$pstat->{vsize
})*$d->{maxmem
});
1976 my $old = $last_proc_pid_stat->{$pid};
1978 $last_proc_pid_stat->{$pid} = {
1986 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz
};
1988 if ($dtime > 1000) {
1989 my $dutime = $used - $old->{used
};
1991 $d->{cpu
} = (($dutime/$dtime)* $cpucount) / $d->{cpus
};
1992 $last_proc_pid_stat->{$pid} = {
1998 $d->{cpu
} = $old->{cpu
};
2002 return $res if !$full;
2004 my $qmpclient = PVE
::QMPClient-
>new();
2006 my $blockstatscb = sub {
2007 my ($vmid, $resp) = @_;
2008 my $data = $resp->{'return'} || [];
2009 my $totalrdbytes = 0;
2010 my $totalwrbytes = 0;
2011 for my $blockstat (@$data) {
2012 $totalrdbytes = $totalrdbytes + $blockstat->{stats
}->{rd_bytes
};
2013 $totalwrbytes = $totalwrbytes + $blockstat->{stats
}->{wr_bytes
};
2015 $res->{$vmid}->{diskread
} = $totalrdbytes;
2016 $res->{$vmid}->{diskwrite
} = $totalwrbytes;
2019 my $statuscb = sub {
2020 my ($vmid, $resp) = @_;
2021 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
2023 my $status = 'unknown';
2024 if (!defined($status = $resp->{'return'}->{status
})) {
2025 warn "unable to get VM status\n";
2029 $res->{$vmid}->{qmpstatus
} = $resp->{'return'}->{status
};
2032 foreach my $vmid (keys %$list) {
2033 next if $opt_vmid && ($vmid ne $opt_vmid);
2034 next if !$res->{$vmid}->{pid
}; # not running
2035 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2038 $qmpclient->queue_execute();
2040 foreach my $vmid (keys %$list) {
2041 next if $opt_vmid && ($vmid ne $opt_vmid);
2042 $res->{$vmid}->{qmpstatus
} = $res->{$vmid}->{status
} if !$res->{$vmid}->{qmpstatus
};
2049 my ($conf, $func) = @_;
2051 foreach my $ds (keys %$conf) {
2052 next if !valid_drivename
($ds);
2054 my $drive = parse_drive
($ds, $conf->{$ds});
2057 &$func($ds, $drive);
2061 sub config_to_command
{
2062 my ($storecfg, $vmid, $conf, $defaults, $migrate_uri) = @_;
2068 my $kvmver = kvm_user_version
();
2069 my $vernum = 0; # unknown
2070 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2071 $vernum = $1*1000000+$2*1000;
2072 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
2073 $vernum = $1*1000000+$2*1000+$3;
2076 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
2078 my $have_ovz = -f
'/proc/vz/vestat';
2080 push @$cmd, '/usr/bin/kvm';
2082 push @$cmd, '-id', $vmid;
2086 my $qmpsocket = qmp_socket
($vmid);
2087 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2088 push @$cmd, '-mon', "chardev=qmp,mode=control";
2090 my $socket = vnc_socket
($vmid);
2091 push @$cmd, '-vnc', "unix:$socket,x509,password";
2093 push @$cmd, '-pidfile' , pidfile_name
($vmid);
2095 push @$cmd, '-daemonize';
2097 push @$cmd, '-incoming', $migrate_uri if $migrate_uri;
2099 push @$cmd, '-S' if $migrate_uri;
2102 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2103 next if !$conf->{"usb$i"};
2106 # include usb device config
2107 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
2109 # enable absolute mouse coordinates (needed by vnc)
2110 my $tablet = defined($conf->{tablet
}) ?
$conf->{tablet
} : $defaults->{tablet
};
2113 push @$devices, '-device', 'usb-tablet,bus=ehci.0,port=6';
2115 push @$devices, '-usbdevice', 'tablet';
2120 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2121 my $d = parse_hostpci
($conf->{"hostpci$i"});
2123 $pciaddr = print_pci_addr
("hostpci$i", $bridges);
2124 push @$devices, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
2128 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2129 my $d = parse_usb_device
($conf->{"usb$i"});
2131 if ($d->{vendorid
} && $d->{productid
}) {
2132 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
2133 } elsif (defined($d->{hostbus
}) && defined($d->{hostport
})) {
2134 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
2139 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
2140 if (my $path = $conf->{"serial$i"}) {
2141 die "no such serial device\n" if ! -c
$path;
2142 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2143 push @$devices, '-device', "isa-serial,chardev=serial$i";
2148 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
2149 if (my $path = $conf->{"parallel$i"}) {
2150 die "no such parallel device\n" if ! -c
$path;
2151 push @$devices, '-chardev', "parport,id=parallel$i,path=$path";
2152 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
2156 my $vmname = $conf->{name
} || "vm$vmid";
2158 push @$cmd, '-name', $vmname;
2161 $sockets = $conf->{smp
} if $conf->{smp
}; # old style - no longer iused
2162 $sockets = $conf->{sockets
} if $conf->{sockets
};
2164 my $cores = $conf->{cores
} || 1;
2166 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2168 push @$cmd, '-cpu', $conf->{cpu
} if $conf->{cpu
};
2170 push @$cmd, '-nodefaults';
2172 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
2174 my $bootindex_hash = {};
2176 foreach my $o (split(//, $bootorder)) {
2177 $bootindex_hash->{$o} = $i*100;
2181 push @$cmd, '-boot', "menu=on";
2183 push @$cmd, '-no-acpi' if defined($conf->{acpi
}) && $conf->{acpi
} == 0;
2185 push @$cmd, '-no-reboot' if defined($conf->{reboot
}) && $conf->{reboot
} == 0;
2187 my $vga = $conf->{vga
};
2189 if ($conf->{ostype
} && ($conf->{ostype
} eq 'win7' || $conf->{ostype
} eq 'w2k8')) {
2196 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2199 my $tdf = defined($conf->{tdf
}) ?
$conf->{tdf
} : $defaults->{tdf
};
2200 # ignore - no longer supported by newer kvm
2201 # push @$cmd, '-tdf' if $tdf;
2203 my $nokvm = defined($conf->{kvm
}) && $conf->{kvm
} == 0 ?
1 : 0;
2205 if (my $ost = $conf->{ostype
}) {
2206 # other, wxp, w2k, w2k3, w2k8, wvista, win7, l24, l26
2208 if ($ost =~ m/^w/) { # windows
2209 push @$cmd, '-localtime' if !defined($conf->{localtime});
2211 # use rtc-td-hack when acpi is enabled
2212 if (!(defined($conf->{acpi
}) && $conf->{acpi
} == 0)) {
2213 push @$cmd, '-rtc-td-hack';
2217 if ($ost eq 'win7' || $ost eq 'w2k8' || $ost eq 'wvista') {
2218 push @$cmd, '-no-kvm-pit-reinjection';
2219 push @$cmd, '-no-hpet';
2229 push @$cmd, '-no-kvm';
2231 die "No accelerator found!\n" if !$cpuinfo->{hvm
};
2234 push @$cmd, '-localtime' if $conf->{localtime};
2236 push @$cmd, '-startdate', $conf->{startdate
} if $conf->{startdate
};
2238 push @$cmd, '-S' if $conf->{freeze
};
2240 # set keyboard layout
2241 my $kb = $conf->{keyboard
} || $defaults->{keyboard
};
2242 push @$cmd, '-k', $kb if $kb;
2245 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2246 #push @$cmd, '-soundhw', 'es1370';
2247 #push @$cmd, '-soundhw', $soundhw if $soundhw;
2249 if($conf->{agent
}) {
2250 my $qgasocket = qga_socket
($vmid);
2251 my $pciaddr = print_pci_addr
("qga0", $bridges);
2252 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
2253 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
2254 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
2257 $pciaddr = print_pci_addr
("balloon0", $bridges);
2258 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr" if $conf->{balloon
};
2260 if ($conf->{watchdog
}) {
2261 my $wdopts = parse_watchdog
($conf->{watchdog
});
2262 $pciaddr = print_pci_addr
("watchdog", $bridges);
2263 my $watchdog = $wdopts->{model
} || 'i6300esb';
2264 push @$devices, '-device', "$watchdog$pciaddr";
2265 push @$devices, '-watchdog-action', $wdopts->{action
} if $wdopts->{action
};
2269 my $scsicontroller = {};
2270 my $ahcicontroller = {};
2271 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : $defaults->{scsihw
};
2273 foreach_drive
($conf, sub {
2274 my ($ds, $drive) = @_;
2276 if (PVE
::Storage
::parse_volume_id
($drive->{file
}, 1)) {
2277 push @$vollist, $drive->{file
};
2280 $use_virtio = 1 if $ds =~ m/^virtio/;
2282 if (drive_is_cdrom
($drive)) {
2283 if ($bootindex_hash->{d
}) {
2284 $drive->{bootindex
} = $bootindex_hash->{d
};
2285 $bootindex_hash->{d
} += 1;
2288 if ($bootindex_hash->{c
}) {
2289 $drive->{bootindex
} = $bootindex_hash->{c
} if $conf->{bootdisk
} && ($conf->{bootdisk
} eq $ds);
2290 $bootindex_hash->{c
} += 1;
2294 if ($drive->{interface
} eq 'scsi') {
2296 my $maxdev = ($scsihw ne 'lsi') ?
256 : 7;
2297 my $controller = int($drive->{index} / $maxdev);
2298 $pciaddr = print_pci_addr
("scsihw$controller", $bridges);
2299 push @$devices, '-device', "$scsihw,id=scsihw$controller$pciaddr" if !$scsicontroller->{$controller};
2300 $scsicontroller->{$controller}=1;
2303 if ($drive->{interface
} eq 'sata') {
2304 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
2305 $pciaddr = print_pci_addr
("ahci$controller", $bridges);
2306 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
2307 $ahcicontroller->{$controller}=1;
2310 push @$devices, '-drive',print_drive_full
($storecfg, $vmid, $drive);
2311 push @$devices, '-device',print_drivedevice_full
($storecfg, $conf, $vmid, $drive, $bridges);
2314 push @$cmd, '-m', $conf->{memory
} || $defaults->{memory
};
2316 for (my $i = 0; $i < $MAX_NETS; $i++) {
2317 next if !$conf->{"net$i"};
2318 my $d = parse_net
($conf->{"net$i"});
2321 $use_virtio = 1 if $d->{model
} eq 'virtio';
2323 if ($bootindex_hash->{n
}) {
2324 $d->{bootindex
} = $bootindex_hash->{n
};
2325 $bootindex_hash->{n
} += 1;
2328 my $netdevfull = print_netdev_full
($vmid,$conf,$d,"net$i");
2329 push @$devices, '-netdev', $netdevfull;
2331 my $netdevicefull = print_netdevice_full
($vmid,$conf,$d,"net$i",$bridges);
2332 push @$devices, '-device', $netdevicefull;
2336 while (my ($k, $v) = each %$bridges) {
2337 $pciaddr = print_pci_addr
("pci.$k");
2338 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
2342 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2343 # when the VM uses virtio devices.
2344 if (!$use_virtio && $have_ovz) {
2346 my $cpuunits = defined($conf->{cpuunits
}) ?
2347 $conf->{cpuunits
} : $defaults->{cpuunits
};
2349 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2351 # fixme: cpulimit is currently ignored
2352 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2356 if ($conf->{args
}) {
2357 my $aa = PVE
::Tools
::split_args
($conf->{args
});
2361 push @$cmd, @$devices;
2362 return wantarray ?
($cmd, $vollist) : $cmd;
2367 return "${var_run_tmpdir}/$vmid.vnc";
2372 return "${var_run_tmpdir}/$vmid.qmp";
2377 return "${var_run_tmpdir}/$vmid.qga";
2382 return "${var_run_tmpdir}/$vmid.pid";
2385 sub next_migrate_port
{
2387 for (my $p = 60000; $p < 60010; $p++) {
2389 my $sock = IO
::Socket
::INET-
>new(Listen
=> 5,
2390 LocalAddr
=> 'localhost',
2401 die "unable to find free migration port";
2404 sub vm_devices_list
{
2407 my $res = vm_mon_cmd
($vmid, 'query-pci');
2410 foreach my $pcibus (@$res) {
2411 foreach my $device (@{$pcibus->{devices
}}) {
2412 next if !$device->{'qdev_id'};
2413 $devices->{$device->{'qdev_id'}} = $device;
2421 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
2423 return 1 if !check_running
($vmid) || !$conf->{hotplug
};
2425 my $devices_list = vm_devices_list
($vmid);
2426 return 1 if defined($devices_list->{$deviceid});
2428 qemu_bridgeadd
($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
2430 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2431 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2432 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
2433 qemu_deviceadd
($vmid, $devicefull);
2434 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2435 qemu_drivedel
($vmid, $deviceid);
2440 if ($deviceid =~ m/^(scsihw)(\d+)$/) {
2441 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : "lsi";
2442 my $pciaddr = print_pci_addr
($deviceid);
2443 my $devicefull = "$scsihw,id=$deviceid$pciaddr";
2444 qemu_deviceadd
($vmid, $devicefull);
2445 return undef if(!qemu_deviceaddverify
($vmid, $deviceid));
2448 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2449 return 1 if ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi'); #virtio-scsi not yet support hotplug
2450 return undef if !qemu_findorcreatescsihw
($storecfg,$conf, $vmid, $device);
2451 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2452 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
2453 if(!qemu_deviceadd
($vmid, $devicefull)) {
2454 qemu_drivedel
($vmid, $deviceid);
2459 if ($deviceid =~ m/^(net)(\d+)$/) {
2460 return undef if !qemu_netdevadd
($vmid, $conf, $device, $deviceid);
2461 my $netdevicefull = print_netdevice_full
($vmid, $conf, $device, $deviceid);
2462 qemu_deviceadd
($vmid, $netdevicefull);
2463 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2464 qemu_netdevdel
($vmid, $deviceid);
2469 if ($deviceid =~ m/^(pci\.)(\d+)$/) {
2471 my $pciaddr = print_pci_addr
($deviceid);
2472 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
2473 qemu_deviceadd
($vmid, $devicefull);
2474 return undef if !qemu_deviceaddverify
($vmid, $deviceid);
2480 sub vm_deviceunplug
{
2481 my ($vmid, $conf, $deviceid) = @_;
2483 return 1 if !check_running
($vmid) || !$conf->{hotplug
};
2485 my $devices_list = vm_devices_list
($vmid);
2486 return 1 if !defined($devices_list->{$deviceid});
2488 die "can't unplug bootdisk" if $conf->{bootdisk
} && $conf->{bootdisk
} eq $deviceid;
2490 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2491 return undef if !qemu_drivedel
($vmid, $deviceid);
2492 qemu_devicedel
($vmid, $deviceid);
2493 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2496 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2497 return undef if !qemu_devicedel
($vmid, $deviceid);
2500 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2501 return undef if !qemu_devicedel
($vmid, $deviceid);
2502 return undef if !qemu_drivedel
($vmid, $deviceid);
2505 if ($deviceid =~ m/^(net)(\d+)$/) {
2506 return undef if !qemu_netdevdel
($vmid, $deviceid);
2507 qemu_devicedel
($vmid, $deviceid);
2508 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2514 sub qemu_deviceadd
{
2515 my ($vmid, $devicefull) = @_;
2517 my $ret = vm_human_monitor_command
($vmid, "device_add $devicefull");
2519 # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
2520 return 1 if $ret eq "";
2521 syslog
("err", "error on hotplug device : $ret");
2526 sub qemu_devicedel
{
2527 my($vmid, $deviceid) = @_;
2529 my $ret = vm_human_monitor_command
($vmid, "device_del $deviceid");
2531 return 1 if $ret eq "";
2532 syslog
("err", "detaching device $deviceid failed : $ret");
2537 my($storecfg, $vmid, $device) = @_;
2539 my $drive = print_drive_full
($storecfg, $vmid, $device);
2540 my $ret = vm_human_monitor_command
($vmid, "drive_add auto $drive");
2541 # If the command succeeds qemu prints: "OK"
2542 if ($ret !~ m/OK/s) {
2543 syslog
("err", "adding drive failed: $ret");
2550 my($vmid, $deviceid) = @_;
2552 my $ret = vm_human_monitor_command
($vmid, "drive_del drive-$deviceid");
2554 if ($ret =~ m/Device \'.*?\' not found/s) {
2555 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
2557 elsif ($ret ne "") {
2558 syslog
("err", "deleting drive $deviceid failed : $ret");
2564 sub qemu_deviceaddverify
{
2565 my ($vmid,$deviceid) = @_;
2567 for (my $i = 0; $i <= 5; $i++) {
2568 my $devices_list = vm_devices_list
($vmid);
2569 return 1 if defined($devices_list->{$deviceid});
2572 syslog
("err", "error on hotplug device $deviceid");
2577 sub qemu_devicedelverify
{
2578 my ($vmid,$deviceid) = @_;
2580 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2581 for (my $i = 0; $i <= 5; $i++) {
2582 my $devices_list = vm_devices_list
($vmid);
2583 return 1 if !defined($devices_list->{$deviceid});
2586 syslog
("err", "error on hot-unplugging device $deviceid");
2590 sub qemu_findorcreatescsihw
{
2591 my ($storecfg, $conf, $vmid, $device) = @_;
2593 my $maxdev = ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi') ?
256 : 7;
2594 my $controller = int($device->{index} / $maxdev);
2595 my $scsihwid="scsihw$controller";
2596 my $devices_list = vm_devices_list
($vmid);
2598 if(!defined($devices_list->{$scsihwid})) {
2599 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $scsihwid);
2604 sub qemu_bridgeadd
{
2605 my ($storecfg, $conf, $vmid, $device) = @_;
2608 my $bridgeid = undef;
2609 print_pci_addr
($device, $bridges);
2611 while (my ($k, $v) = each %$bridges) {
2614 return if $bridgeid < 1;
2615 my $bridge = "pci.$bridgeid";
2616 my $devices_list = vm_devices_list
($vmid);
2618 if(!defined($devices_list->{$bridge})) {
2619 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $bridge);
2624 sub qemu_netdevadd
{
2625 my ($vmid, $conf, $device, $deviceid) = @_;
2627 my $netdev = print_netdev_full
($vmid, $conf, $device, $deviceid);
2628 my $ret = vm_human_monitor_command
($vmid, "netdev_add $netdev");
2631 #if the command succeeds, no output is sent. So any non-empty string shows an error
2632 return 1 if $ret eq "";
2633 syslog
("err", "adding netdev failed: $ret");
2637 sub qemu_netdevdel
{
2638 my ($vmid, $deviceid) = @_;
2640 my $ret = vm_human_monitor_command
($vmid, "netdev_del $deviceid");
2642 #if the command succeeds, no output is sent. So any non-empty string shows an error
2643 return 1 if $ret eq "";
2644 syslog
("err", "deleting netdev failed: $ret");
2648 sub qemu_block_set_io_throttle
{
2649 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2651 return if !check_running
($vmid) ;
2654 $bps_rd = 0 if !$bps_rd;
2655 $bps_wr = 0 if !$bps_wr;
2656 $iops = 0 if !$iops;
2657 $iops_rd = 0 if !$iops_rd;
2658 $iops_wr = 0 if !$iops_wr;
2660 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));
2664 # old code, only used to shutdown old VM after update
2666 my ($fh, $timeout) = @_;
2668 my $sel = new IO
::Select
;
2675 while (scalar (@ready = $sel->can_read($timeout))) {
2677 if ($count = $fh->sysread($buf, 8192)) {
2678 if ($buf =~ /^(.*)\(qemu\) $/s) {
2685 if (!defined($count)) {
2692 die "monitor read timeout\n" if !scalar(@ready);
2697 # old code, only used to shutdown old VM after update
2698 sub vm_monitor_command
{
2699 my ($vmid, $cmdstr, $nocheck) = @_;
2704 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
2706 my $sname = "${var_run_tmpdir}/$vmid.mon";
2708 my $sock = IO
::Socket
::UNIX-
>new( Peer
=> $sname ) ||
2709 die "unable to connect to VM $vmid socket - $!\n";
2713 # hack: migrate sometime blocks the monitor (when migrate_downtime
2715 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2716 $timeout = 60*60; # 1 hour
2720 my $data = __read_avail
($sock, $timeout);
2722 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2723 die "got unexpected qemu monitor banner\n";
2726 my $sel = new IO
::Select
;
2729 if (!scalar(my @ready = $sel->can_write($timeout))) {
2730 die "monitor write error - timeout";
2733 my $fullcmd = "$cmdstr\r";
2735 # syslog('info', "VM $vmid monitor command: $cmdstr");
2738 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
2739 die "monitor write error - $!";
2742 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2746 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2747 $timeout = 60*60; # 1 hour
2748 } elsif ($cmdstr =~ m/^(eject|change)/) {
2749 $timeout = 60; # note: cdrom mount command is slow
2751 if ($res = __read_avail
($sock, $timeout)) {
2753 my @lines = split("\r?\n", $res);
2755 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
2757 $res = join("\n", @lines);
2765 syslog
("err", "VM $vmid monitor command failed - $err");
2772 sub qemu_block_resize
{
2773 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
2775 my $running = PVE
::QemuServer
::check_running
($vmid);
2777 return if !PVE
::Storage
::volume_resize
($storecfg, $volid, $size, $running);
2779 return if !$running;
2781 vm_mon_cmd
($vmid, "block_resize", device
=> $deviceid, size
=> int($size));
2785 sub qemu_volume_snapshot
{
2786 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
2788 my $running = PVE
::QemuServer
::check_running
($vmid);
2790 return if !PVE
::Storage
::volume_snapshot
($storecfg, $volid, $snap, $running);
2792 return if !$running;
2794 vm_mon_cmd
($vmid, "snapshot-drive", device
=> $deviceid, name
=> $snap);
2798 sub qemu_volume_snapshot_delete
{
2799 my ($vmid, $deviceid, $storecfg, $volid, $snap) = @_;
2801 #need to implement statefile location
2802 my $statefile="/tmp/$vmid-$snap";
2804 unlink $statefile if -e
$statefile;
2806 my $running = PVE
::QemuServer
::check_running
($vmid);
2808 return if !PVE
::Storage
::volume_snapshot_delete
($storecfg, $volid, $snap, $running);
2810 return if !$running;
2812 #need to split delvm monitor command like savevm
2816 sub qemu_snapshot_start
{
2817 my ($vmid, $snap) = @_;
2819 #need to implement statefile location
2820 my $statefile="/tmp/$vmid-$snap";
2822 vm_mon_cmd
($vmid, "snapshot-start", statefile
=> $statefile);
2826 sub qemu_snapshot_end
{
2829 vm_mon_cmd
($vmid, "snapshot-end");
2836 #need to impplement call to qemu-ga
2839 sub qga_unfreezefs
{
2842 #need to impplement call to qemu-ga
2846 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom) = @_;
2848 lock_config
($vmid, sub {
2849 my $conf = load_config
($vmid, $migratedfrom);
2851 check_lock
($conf) if !$skiplock;
2853 die "VM $vmid already running\n" if check_running
($vmid, undef, $migratedfrom);
2856 my $migrate_port = 0;
2859 if ($statefile eq 'tcp') {
2860 $migrate_port = next_migrate_port
();
2861 $migrate_uri = "tcp:localhost:${migrate_port}";
2863 if (-f
$statefile) {
2864 $migrate_uri = "exec:cat $statefile";
2866 warn "state file '$statefile' does not exist - doing normal startup\n";
2871 my $defaults = load_defaults
();
2873 # set environment variable useful inside network script
2874 $ENV{PVE_MIGRATED_FROM
} = $migratedfrom if $migratedfrom;
2876 my ($cmd, $vollist) = config_to_command
($storecfg, $vmid, $conf, $defaults, $migrate_uri);
2878 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2879 my $d = parse_hostpci
($conf->{"hostpci$i"});
2881 my $info = pci_device_info
("0000:$d->{pciid}");
2882 die "IOMMU not present\n" if !check_iommu_support
();
2883 die "no pci device info for device '$d->{pciid}'\n" if !$info;
2884 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub
($info);
2885 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset
($info);
2888 PVE
::Storage
::activate_volumes
($storecfg, $vollist);
2890 eval { run_command
($cmd, timeout
=> $migrate_uri ?
undef : 30); };
2892 die "start failed: $err" if $err;
2896 if ($statefile eq 'tcp') {
2897 print "migration listens on port $migrate_port\n";
2900 # fixme: send resume - is that necessary ?
2901 eval { vm_mon_cmd
($vmid, "cont"); };
2905 # always set migrate speed (overwrite kvm default of 32m)
2906 # we set a very hight default of 8192m which is basically unlimited
2907 my $migrate_speed = $defaults->{migrate_speed
} || 8192;
2908 $migrate_speed = $conf->{migrate_speed
} || $migrate_speed;
2909 $migrate_speed = $migrate_speed * 1048576;
2911 vm_mon_cmd
($vmid, "migrate_set_speed", value
=> $migrate_speed);
2914 my $migrate_downtime = $defaults->{migrate_downtime
};
2915 $migrate_downtime = $conf->{migrate_downtime
} if defined($conf->{migrate_downtime
});
2916 if (defined($migrate_downtime)) {
2917 eval { vm_mon_cmd
($vmid, "migrate_set_downtime", value
=> $migrate_downtime); };
2921 my $capabilities = {};
2922 $capabilities->{capability
} = "xbzrle";
2923 $capabilities->{state} = JSON
::true
;
2924 eval { PVE
::QemuServer
::vm_mon_cmd_nocheck
($vmid, "migrate-set-capabilities", capabilities
=> [$capabilities]); };
2927 vm_balloonset
($vmid, $conf->{balloon
}) if $conf->{balloon
};
2933 my ($vmid, $execute, %params) = @_;
2935 my $cmd = { execute
=> $execute, arguments
=> \
%params };
2936 vm_qmp_command
($vmid, $cmd);
2939 sub vm_mon_cmd_nocheck
{
2940 my ($vmid, $execute, %params) = @_;
2942 my $cmd = { execute
=> $execute, arguments
=> \
%params };
2943 vm_qmp_command
($vmid, $cmd, 1);
2946 sub vm_qmp_command
{
2947 my ($vmid, $cmd, $nocheck) = @_;
2952 if ($cmd->{arguments
} && $cmd->{arguments
}->{timeout
}) {
2953 $timeout = $cmd->{arguments
}->{timeout
};
2954 delete $cmd->{arguments
}->{timeout
};
2958 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
2959 my $sname = PVE
::QemuServer
::qmp_socket
($vmid);
2961 my $qmpclient = PVE
::QMPClient-
>new();
2963 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
2964 } elsif (-e
"${var_run_tmpdir}/$vmid.mon") {
2965 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
2966 if scalar(%{$cmd->{arguments
}});
2967 vm_monitor_command
($vmid, $cmd->{execute
}, $nocheck);
2969 die "unable to open monitor socket\n";
2973 syslog
("err", "VM $vmid qmp command failed - $err");
2980 sub vm_human_monitor_command
{
2981 my ($vmid, $cmdline) = @_;
2986 execute
=> 'human-monitor-command',
2987 arguments
=> { 'command-line' => $cmdline},
2990 return vm_qmp_command
($vmid, $cmd);
2993 sub vm_commandline
{
2994 my ($storecfg, $vmid) = @_;
2996 my $conf = load_config
($vmid);
2998 my $defaults = load_defaults
();
3000 my $cmd = config_to_command
($storecfg, $vmid, $conf, $defaults);
3002 return join(' ', @$cmd);
3006 my ($vmid, $skiplock) = @_;
3008 lock_config
($vmid, sub {
3010 my $conf = load_config
($vmid);
3012 check_lock
($conf) if !$skiplock;
3014 vm_mon_cmd
($vmid, "system_reset");
3018 sub get_vm_volumes
{
3022 foreach_drive
($conf, sub {
3023 my ($ds, $drive) = @_;
3025 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($drive->{file
}, 1);
3028 my $volid = $drive->{file
};
3029 return if !$volid || $volid =~ m
|^/|;
3031 push @$vollist, $volid;
3037 sub vm_stop_cleanup
{
3038 my ($storecfg, $vmid, $conf, $keepActive) = @_;
3041 fairsched_rmnod
($vmid); # try to destroy group
3044 my $vollist = get_vm_volumes
($conf);
3045 PVE
::Storage
::deactivate_volumes
($storecfg, $vollist);
3048 foreach my $ext (qw(mon qmp pid vnc qga)) {
3049 unlink "/var/run/qemu-server/${vmid}.$ext";
3052 warn $@ if $@; # avoid errors - just warn
3055 # Note: use $nockeck to skip tests if VM configuration file exists.
3056 # We need that when migration VMs to other nodes (files already moved)
3057 # Note: we set $keepActive in vzdump stop mode - volumes need to stay active
3059 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
3061 $force = 1 if !defined($force) && !$shutdown;
3064 my $pid = check_running
($vmid, $nocheck, $migratedfrom);
3065 kill 15, $pid if $pid;
3066 my $conf = load_config
($vmid, $migratedfrom);
3067 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive);
3071 lock_config
($vmid, sub {
3073 my $pid = check_running
($vmid, $nocheck);
3078 $conf = load_config
($vmid);
3079 check_lock
($conf) if !$skiplock;
3080 if (!defined($timeout) && $shutdown && $conf->{startup
}) {
3081 my $opts = parse_startup
($conf->{startup
});
3082 $timeout = $opts->{down
} if $opts->{down
};
3086 $timeout = 60 if !defined($timeout);
3090 $nocheck ? vm_mon_cmd_nocheck
($vmid, "system_powerdown") : vm_mon_cmd
($vmid, "system_powerdown");
3093 $nocheck ? vm_mon_cmd_nocheck
($vmid, "quit") : vm_mon_cmd
($vmid, "quit");
3100 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
3105 if ($count >= $timeout) {
3107 warn "VM still running - terminating now with SIGTERM\n";
3110 die "VM quit/powerdown failed - got timeout\n";
3113 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
3118 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
3121 die "VM quit/powerdown failed\n";
3129 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
3134 if ($count >= $timeout) {
3135 warn "VM still running - terminating now with SIGKILL\n";
3140 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
3145 my ($vmid, $skiplock) = @_;
3147 lock_config
($vmid, sub {
3149 my $conf = load_config
($vmid);
3151 check_lock
($conf) if !$skiplock;
3153 vm_mon_cmd
($vmid, "stop");
3158 my ($vmid, $skiplock) = @_;
3160 lock_config
($vmid, sub {
3162 my $conf = load_config
($vmid);
3164 check_lock
($conf) if !$skiplock;
3166 vm_mon_cmd
($vmid, "cont");
3171 my ($vmid, $skiplock, $key) = @_;
3173 lock_config
($vmid, sub {
3175 my $conf = load_config
($vmid);
3177 # there is no qmp command, so we use the human monitor command
3178 vm_human_monitor_command
($vmid, "sendkey $key");
3183 my ($storecfg, $vmid, $skiplock) = @_;
3185 lock_config
($vmid, sub {
3187 my $conf = load_config
($vmid);
3189 check_lock
($conf) if !$skiplock;
3191 if (!check_running
($vmid)) {
3192 fairsched_rmnod
($vmid); # try to destroy group
3193 destroy_vm
($storecfg, $vmid);
3195 die "VM $vmid is running - destroy failed\n";
3203 my ($filename, $buf) = @_;
3205 my $fh = IO
::File-
>new($filename, "w");
3206 return undef if !$fh;
3208 my $res = print $fh $buf;
3215 sub pci_device_info
{
3220 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
3221 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
3223 my $irq = file_read_firstline
("$pcisysfs/devices/$name/irq");
3224 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3226 my $vendor = file_read_firstline
("$pcisysfs/devices/$name/vendor");
3227 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3229 my $product = file_read_firstline
("$pcisysfs/devices/$name/device");
3230 return undef if !defined($product) || $product !~ s/^0x//;
3235 product
=> $product,
3241 has_fl_reset
=> -f
"$pcisysfs/devices/$name/reset" || 0,
3250 my $name = $dev->{name
};
3252 my $fn = "$pcisysfs/devices/$name/reset";
3254 return file_write
($fn, "1");
3257 sub pci_dev_bind_to_stub
{
3260 my $name = $dev->{name
};
3262 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3263 return 1 if -d
$testdir;
3265 my $data = "$dev->{vendor} $dev->{product}";
3266 return undef if !file_write
("$pcisysfs/drivers/pci-stub/new_id", $data);
3268 my $fn = "$pcisysfs/devices/$name/driver/unbind";
3269 if (!file_write
($fn, $name)) {
3270 return undef if -f
$fn;
3273 $fn = "$pcisysfs/drivers/pci-stub/bind";
3274 if (! -d
$testdir) {
3275 return undef if !file_write
($fn, $name);
3281 sub print_pci_addr
{
3282 my ($id, $bridges) = @_;
3286 #addr1 : ide,parallel,serial (motherboard)
3287 #addr2 : first videocard
3288 balloon0
=> { bus
=> 0, addr
=> 3 },
3289 watchdog
=> { bus
=> 0, addr
=> 4 },
3290 scsihw0
=> { bus
=> 0, addr
=> 5 },
3291 scsihw1
=> { bus
=> 0, addr
=> 6 },
3292 ahci0
=> { bus
=> 0, addr
=> 7 },
3293 qga0
=> { bus
=> 0, addr
=> 8 },
3294 virtio0
=> { bus
=> 0, addr
=> 10 },
3295 virtio1
=> { bus
=> 0, addr
=> 11 },
3296 virtio2
=> { bus
=> 0, addr
=> 12 },
3297 virtio3
=> { bus
=> 0, addr
=> 13 },
3298 virtio4
=> { bus
=> 0, addr
=> 14 },
3299 virtio5
=> { bus
=> 0, addr
=> 15 },
3300 hostpci0
=> { bus
=> 0, addr
=> 16 },
3301 hostpci1
=> { bus
=> 0, addr
=> 17 },
3302 net0
=> { bus
=> 0, addr
=> 18 },
3303 net1
=> { bus
=> 0, addr
=> 19 },
3304 net2
=> { bus
=> 0, addr
=> 20 },
3305 net3
=> { bus
=> 0, addr
=> 21 },
3306 net4
=> { bus
=> 0, addr
=> 22 },
3307 net5
=> { bus
=> 0, addr
=> 23 },
3308 #addr29 : usb-host (pve-usb.cfg)
3309 'pci.1' => { bus
=> 0, addr
=> 30 },
3310 'pci.2' => { bus
=> 0, addr
=> 31 },
3311 'net6' => { bus
=> 1, addr
=> 1 },
3312 'net7' => { bus
=> 1, addr
=> 2 },
3313 'net8' => { bus
=> 1, addr
=> 3 },
3314 'net9' => { bus
=> 1, addr
=> 4 },
3315 'net10' => { bus
=> 1, addr
=> 5 },
3316 'net11' => { bus
=> 1, addr
=> 6 },
3317 'net12' => { bus
=> 1, addr
=> 7 },
3318 'net13' => { bus
=> 1, addr
=> 8 },
3319 'net14' => { bus
=> 1, addr
=> 9 },
3320 'net15' => { bus
=> 1, addr
=> 10 },
3321 'net16' => { bus
=> 1, addr
=> 11 },
3322 'net17' => { bus
=> 1, addr
=> 12 },
3323 'net18' => { bus
=> 1, addr
=> 13 },
3324 'net19' => { bus
=> 1, addr
=> 14 },
3325 'net20' => { bus
=> 1, addr
=> 15 },
3326 'net21' => { bus
=> 1, addr
=> 16 },
3327 'net22' => { bus
=> 1, addr
=> 17 },
3328 'net23' => { bus
=> 1, addr
=> 18 },
3329 'net24' => { bus
=> 1, addr
=> 19 },
3330 'net25' => { bus
=> 1, addr
=> 20 },
3331 'net26' => { bus
=> 1, addr
=> 21 },
3332 'net27' => { bus
=> 1, addr
=> 22 },
3333 'net28' => { bus
=> 1, addr
=> 23 },
3334 'net29' => { bus
=> 1, addr
=> 24 },
3335 'net30' => { bus
=> 1, addr
=> 25 },
3336 'net31' => { bus
=> 1, addr
=> 26 },
3337 'virtio6' => { bus
=> 2, addr
=> 1 },
3338 'virtio7' => { bus
=> 2, addr
=> 2 },
3339 'virtio8' => { bus
=> 2, addr
=> 3 },
3340 'virtio9' => { bus
=> 2, addr
=> 4 },
3341 'virtio10' => { bus
=> 2, addr
=> 5 },
3342 'virtio11' => { bus
=> 2, addr
=> 6 },
3343 'virtio12' => { bus
=> 2, addr
=> 7 },
3344 'virtio13' => { bus
=> 2, addr
=> 8 },
3345 'virtio14' => { bus
=> 2, addr
=> 9 },
3346 'virtio15' => { bus
=> 2, addr
=> 10 },
3349 if (defined($devices->{$id}->{bus
}) && defined($devices->{$id}->{addr
})) {
3350 my $addr = sprintf("0x%x", $devices->{$id}->{addr
});
3351 my $bus = $devices->{$id}->{bus
};
3352 $res = ",bus=pci.$bus,addr=$addr";
3353 $bridges->{$bus} = 1 if $bridges;
3360 my ($vmid, $value) = @_;
3362 vm_mon_cmd
($vmid, "balloon", value
=> $value);
3365 # vzdump restore implementaion
3367 sub archive_read_firstfile
{
3368 my $archive = shift;
3370 die "ERROR: file '$archive' does not exist\n" if ! -f
$archive;
3372 # try to detect archive type first
3373 my $pid = open (TMP
, "tar tf '$archive'|") ||
3374 die "unable to open file '$archive'\n";
3375 my $firstfile = <TMP
>;
3379 die "ERROR: archive contaions no data\n" if !$firstfile;
3385 sub restore_cleanup
{
3386 my $statfile = shift;
3388 print STDERR
"starting cleanup\n";
3390 if (my $fd = IO
::File-
>new($statfile, "r")) {
3391 while (defined(my $line = <$fd>)) {
3392 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3395 if ($volid =~ m
|^/|) {
3396 unlink $volid || die 'unlink failed\n';
3398 my $cfg = cfs_read_file
('storage.cfg');
3399 PVE
::Storage
::vdisk_free
($cfg, $volid);
3401 print STDERR
"temporary volume '$volid' sucessfuly removed\n";
3403 print STDERR
"unable to cleanup '$volid' - $@" if $@;
3405 print STDERR
"unable to parse line in statfile - $line";
3412 sub restore_archive
{
3413 my ($archive, $vmid, $user, $opts) = @_;
3415 if ($archive ne '-') {
3416 my $firstfile = archive_read_firstfile
($archive);
3417 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
3418 if $firstfile ne 'qemu-server.conf';
3421 my $tocmd = "/usr/lib/qemu-server/qmextract";
3423 $tocmd .= " --storage " . PVE
::Tools
::shellquote
($opts->{storage
}) if $opts->{storage
};
3424 $tocmd .= " --pool " . PVE
::Tools
::shellquote
($opts->{pool
}) if $opts->{pool
};
3425 $tocmd .= ' --prealloc' if $opts->{prealloc
};
3426 $tocmd .= ' --info' if $opts->{info
};
3428 # tar option "xf" does not autodetect compression when read from STDIN,
3429 # so we pipe to zcat
3430 my $cmd = "zcat -f|tar xf " . PVE
::Tools
::shellquote
($archive) . " " .
3431 PVE
::Tools
::shellquote
("--to-command=$tocmd");
3433 my $tmpdir = "/var/tmp/vzdumptmp$$";
3436 local $ENV{VZDUMP_TMPDIR
} = $tmpdir;
3437 local $ENV{VZDUMP_VMID
} = $vmid;
3438 local $ENV{VZDUMP_USER
} = $user;
3440 my $conffile = PVE
::QemuServer
::config_file
($vmid);
3441 my $tmpfn = "$conffile.$$.tmp";
3443 # disable interrupts (always do cleanups)
3444 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
3445 print STDERR
"got interrupt - ignored\n";
3450 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
3451 die "interrupted by signal\n";
3454 if ($archive eq '-') {
3455 print "extracting archive from STDIN\n";
3456 run_command
($cmd, input
=> "<&STDIN");
3458 print "extracting archive '$archive'\n";
3462 return if $opts->{info
};
3466 my $statfile = "$tmpdir/qmrestore.stat";
3467 if (my $fd = IO
::File-
>new($statfile, "r")) {
3468 while (defined (my $line = <$fd>)) {
3469 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3470 $map->{$1} = $2 if $1;
3472 print STDERR
"unable to parse line in statfile - $line\n";
3478 my $confsrc = "$tmpdir/qemu-server.conf";
3480 my $srcfd = new IO
::File
($confsrc, "r") ||
3481 die "unable to open file '$confsrc'\n";
3483 my $outfd = new IO
::File
($tmpfn, "w") ||
3484 die "unable to write config for VM $vmid\n";
3488 while (defined (my $line = <$srcfd>)) {
3489 next if $line =~ m/^\#vzdump\#/;
3490 next if $line =~ m/^lock:/;
3491 next if $line =~ m/^unused\d+:/;
3493 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3494 # try to convert old 1.X settings
3495 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3496 foreach my $devconfig (PVE
::Tools
::split_list
($ethcfg)) {
3497 my ($model, $macaddr) = split(/\=/, $devconfig);
3498 $macaddr = PVE
::Tools
::random_ether_addr
() if !$macaddr || $opts->{unique
};
3501 bridge
=> "vmbr$ind",
3502 macaddr
=> $macaddr,
3504 my $netstr = print_net
($net);
3505 print $outfd "net${netcount}: $netstr\n";
3508 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && ($opts->{unique
})) {
3509 my ($id, $netstr) = ($1, $2);
3510 my $net = parse_net
($netstr);
3511 $net->{macaddr
} = PVE
::Tools
::random_ether_addr
() if $net->{macaddr
};
3512 $netstr = print_net
($net);
3513 print $outfd "$id: $netstr\n";
3514 } elsif ($line =~ m/^((ide|scsi|virtio)\d+):\s*(\S+)\s*$/) {
3517 if ($line =~ m/backup=no/) {
3518 print $outfd "#$line";
3519 } elsif ($virtdev && $map->{$virtdev}) {
3520 my $di = PVE
::QemuServer
::parse_drive
($virtdev, $value);
3521 $di->{file
} = $map->{$virtdev};
3522 $value = PVE
::QemuServer
::print_drive
($vmid, $di);
3523 print $outfd "$virtdev: $value\n";
3541 restore_cleanup
("$tmpdir/qmrestore.stat") if !$opts->{info
};
3548 rename $tmpfn, $conffile ||
3549 die "unable to commit configuration file '$conffile'\n";
3553 # Internal snapshots
3555 # NOTE: Snapshot create/delete involves several non-atomic
3556 # action, and can take a long time.
3557 # So we try to avoid locking the file and use 'lock' variable
3558 # inside the config file instead.
3560 my $snapshot_prepare = sub {
3561 my ($vmid, $snapname) = @_;
3565 my $updatefn = sub {
3567 my $conf = load_config
($vmid);
3571 $conf->{lock} = 'snapshot';
3573 die "snapshot name '$snapname' already used\n"
3574 if defined($conf->{snapshots
}->{$snapname});
3576 # fixme: need to implement a check to see if all storages
3579 $snap = $conf->{snapshots
}->{$snapname} = {
3580 snapstate
=> "prepare",
3583 foreach my $k (keys %$conf) {
3584 next if $k eq 'snapshots';
3585 next if $k eq 'lock';
3586 next if $k eq 'digest';
3588 $snap->{$k} = $conf->{$k};
3591 update_config_nolock
($vmid, $conf, 1);
3594 lock_config
($vmid, $updatefn);
3599 my $snapshot_commit = sub {
3600 my ($vmid, $snapname) = @_;
3602 my $updatefn = sub {
3604 my $conf = load_config
($vmid);
3606 die "missing snapshot lock\n"
3607 if !($conf->{lock} && $conf->{lock} eq 'snapshot');
3609 my $snap = $conf->{snapshots
}->{$snapname};
3611 die "snapshot '$snapname' does not exist\n" if !defined($snap);
3613 die "wrong snapshot state\n"
3614 if !($snap->{snapstate
} && $snap->{snapstate
} eq "prepare");
3616 delete $snap->{snapstate
};
3618 # copy snapshot config to current config
3620 snapshots
=> $conf->{snapshots
},
3622 foreach my $k (keys %$snap) {
3623 next if $k eq 'snapshots';
3624 next if $k eq 'lock';
3625 next if $k eq 'digest';
3627 $newconf->{$k} = $snap->{$k};
3630 update_config_nolock
($vmid, $newconf, 1);
3633 lock_config
($vmid, $updatefn);
3636 sub snapshot_rollback
{
3637 my ($vmid, $snapname) = @_;
3643 my $updatefn = sub {
3645 my $conf = load_config
($vmid);
3647 check_lock
($conf) if $prepare;
3649 die "unable to rollback vm $vmid: vm is running\n"
3650 if check_running
($vmid);
3653 $conf->{lock} = 'rollback';
3655 die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
3656 delete $conf->{lock};
3659 $snap = $conf->{snapshots
}->{$snapname};
3661 die "snapshot '$snapname' does not exist\n" if !defined($snap);
3663 die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
3664 if $snap->{snapstate
};
3667 # copy snapshot config to current config
3669 snapshots
=> $conf->{snapshots
},
3671 foreach my $k (keys %$snap) {
3672 next if $k eq 'snapshots';
3673 next if $k eq 'lock';
3674 next if $k eq 'digest';
3676 $newconf->{$k} = $snap->{$k};
3677 $newconf->{parent
} = $snapname;
3681 update_config_nolock
($vmid, $conf, 1);
3684 lock_config
($vmid, $updatefn);
3686 my $storecfg = PVE
::Storage
::config
();
3688 foreach_drive
($snap, sub {
3689 my ($ds, $drive) = @_;
3691 return if drive_is_cdrom
($drive);
3693 my $volid = $drive->{file
};
3694 my $device = "drive-$ds";
3696 qemu_volume_snapshot_rollback
($vmid, $device, $storecfg, $volid, $snapname);
3700 lock_config
($vmid, $updatefn);
3703 sub snapshot_create
{
3704 my ($vmid, $snapname, $vmstate, $freezefs) = @_;
3706 my $snap = &$snapshot_prepare($vmid, $snapname);
3709 # create internal snapshots of all drives
3711 qemu_snapshot_start
($vmid, $snapname) if $vmstate;
3713 qga_freezefs
($vmid) if $freezefs;
3715 my $storecfg = PVE
::Storage
::config
();
3717 foreach_drive
($snap, sub {
3718 my ($ds, $drive) = @_;
3720 return if drive_is_cdrom
($drive);
3722 my $volid = $drive->{file
};
3723 my $device = "drive-$ds";
3725 qemu_volume_snapshot
($vmid, $device, $storecfg, $volid, $snapname);
3730 eval { gqa_unfreezefs
($vmid) if $freezefs; };
3733 eval { qemu_snapshot_end
($vmid) if $vmstate; };
3737 warn "snapshot create failed: starting cleanup\n";
3738 eval { snapshot_delete
($vmid, $snapname); };
3743 &$snapshot_commit($vmid, $snapname);
3746 sub snapshot_delete
{
3747 my ($vmid, $snapname, $force) = @_;
3753 my $updatefn = sub {
3755 my $conf = load_config
($vmid);
3757 check_lock
($conf) if !$force;
3759 $snap = $conf->{snapshots
}->{$snapname};
3761 die "snapshot '$snapname' does not exist\n" if !defined($snap);
3763 # remove parent refs
3764 foreach my $sn (keys %{$conf->{snapshots
}}) {
3765 next if $sn eq $snapname;
3766 my $snapref = $conf->{snapshots
}->{$sn};
3767 if ($snapref->{parent
} && $snapref->{parent
} eq $snapname) {
3768 if ($snap->{parent
}) {
3769 $snapref->{parent
} = $snap->{parent
};
3771 delete $snapref->{parent
};
3777 $snap->{snapstate
} = 'delete';
3779 delete $conf->{snapshots
}->{$snapname};
3782 update_config_nolock
($vmid, $conf, 1);
3785 lock_config
($vmid, $updatefn);
3787 # now remove all internal snapshots
3789 my $storecfg = PVE
::Storage
::config
();
3791 PVE
::QemuServer
::foreach_drive
($snap, sub {
3792 my ($ds, $drive) = @_;
3794 return if drive_is_cdrom
($drive);
3795 my $volid = $drive->{file
};
3796 my $device = "drive-$ds";
3798 qemu_volume_snapshot_delete
($vmid, $device, $storecfg, $volid, $snapname);
3801 # now cleanup config
3803 lock_config
($vmid, $updatefn);