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' or 'backup'. 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 #no warnings 'redefine';
59 unless(defined(&_VZSYSCALLS_H_
)) {
60 eval 'sub _VZSYSCALLS_H_ () {1;}' unless defined(&_VZSYSCALLS_H_
);
61 require 'sys/syscall.ph';
62 if(defined(&__x86_64__
)) {
63 eval 'sub __NR_fairsched_vcpus () {499;}' unless defined(&__NR_fairsched_vcpus
);
64 eval 'sub __NR_fairsched_mknod () {504;}' unless defined(&__NR_fairsched_mknod
);
65 eval 'sub __NR_fairsched_rmnod () {505;}' unless defined(&__NR_fairsched_rmnod
);
66 eval 'sub __NR_fairsched_chwt () {506;}' unless defined(&__NR_fairsched_chwt
);
67 eval 'sub __NR_fairsched_mvpr () {507;}' unless defined(&__NR_fairsched_mvpr
);
68 eval 'sub __NR_fairsched_rate () {508;}' unless defined(&__NR_fairsched_rate
);
69 eval 'sub __NR_setluid () {501;}' unless defined(&__NR_setluid
);
70 eval 'sub __NR_setublimit () {502;}' unless defined(&__NR_setublimit
);
72 elsif(defined( &__i386__
) ) {
73 eval 'sub __NR_fairsched_mknod () {500;}' unless defined(&__NR_fairsched_mknod
);
74 eval 'sub __NR_fairsched_rmnod () {501;}' unless defined(&__NR_fairsched_rmnod
);
75 eval 'sub __NR_fairsched_chwt () {502;}' unless defined(&__NR_fairsched_chwt
);
76 eval 'sub __NR_fairsched_mvpr () {503;}' unless defined(&__NR_fairsched_mvpr
);
77 eval 'sub __NR_fairsched_rate () {504;}' unless defined(&__NR_fairsched_rate
);
78 eval 'sub __NR_fairsched_vcpus () {505;}' unless defined(&__NR_fairsched_vcpus
);
79 eval 'sub __NR_setluid () {511;}' unless defined(&__NR_setluid
);
80 eval 'sub __NR_setublimit () {512;}' unless defined(&__NR_setublimit
);
82 die("no fairsched syscall for this arch");
84 require 'asm/ioctl.ph';
85 eval 'sub KVM_GET_API_VERSION () { &_IO(0xAE, 0x);}' unless defined(&KVM_GET_API_VERSION
);
89 my ($parent, $weight, $desired) = @_;
91 return syscall(&__NR_fairsched_mknod
, int($parent), int($weight), int($desired));
97 return syscall(&__NR_fairsched_rmnod
, int($id));
101 my ($pid, $newid) = @_;
103 return syscall(&__NR_fairsched_mvpr
, int($pid), int($newid));
106 sub fairsched_vcpus
{
107 my ($id, $vcpus) = @_;
109 return syscall(&__NR_fairsched_vcpus
, int($id), int($vcpus));
113 my ($id, $op, $rate) = @_;
115 return syscall(&__NR_fairsched_rate
, int($id), int($op), int($rate));
118 use constant FAIRSCHED_SET_RATE
=> 0;
119 use constant FAIRSCHED_DROP_RATE
=> 1;
120 use constant FAIRSCHED_GET_RATE
=> 2;
122 sub fairsched_cpulimit
{
123 my ($id, $limit) = @_;
125 my $cpulim1024 = int($limit * 1024 / 100);
126 my $op = $cpulim1024 ? FAIRSCHED_SET_RATE
: FAIRSCHED_DROP_RATE
;
128 return fairsched_rate
($id, $op, $cpulim1024);
131 my $nodename = PVE
::INotify
::nodename
();
133 mkdir "/etc/pve/nodes/$nodename";
134 my $confdir = "/etc/pve/nodes/$nodename/qemu-server";
137 my $var_run_tmpdir = "/var/run/qemu-server";
138 mkdir $var_run_tmpdir;
140 my $lock_dir = "/var/lock/qemu-server";
143 my $pcisysfs = "/sys/bus/pci";
149 description
=> "Specifies whether a VM will be started during system bootup.",
155 description
=> "Automatic restart after crash (currently ignored).",
161 description
=> "Activate hotplug for disk and network device",
167 description
=> "Allow reboot. If set to '0' the VM exit on reboot.",
173 description
=> "Lock/unlock the VM.",
174 enum
=> [qw(migrate backup)],
179 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.",
186 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.",
194 description
=> "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.",
201 description
=> "Amount of target RAM for the VM in MB.",
207 description
=> "Keybord layout for vnc server. Default is read from the datacenter configuration file.",
208 enum
=> PVE
::Tools
::kvmkeymaplist
(),
213 type
=> 'string', format
=> 'dns-name',
214 description
=> "Set a name for the VM. Only used on the configuration web interface.",
219 description
=> "scsi controller model",
220 enum
=> [qw(lsi virtio-scsi-pci megasas)],
226 description
=> "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.",
231 enum
=> [qw(other wxp w2k w2k3 w2k8 wvista win7 l24 l26)],
232 description
=> <<EODESC,
233 Used to enable special optimization/features for specific
236 other => unspecified OS
237 wxp => Microsoft Windows XP
238 w2k => Microsoft Windows 2000
239 w2k3 => Microsoft Windows 2003
240 w2k8 => Microsoft Windows 2008
241 wvista => Microsoft Windows Vista
242 win7 => Microsoft Windows 7
243 l24 => Linux 2.4 Kernel
244 l26 => Linux 2.6/3.X Kernel
246 other|l24|l26 ... no special behaviour
247 wxp|w2k|w2k3|w2k8|wvista|win7 ... use --localtime switch
253 description
=> "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n).",
254 pattern
=> '[acdn]{1,4}',
259 type
=> 'string', format
=> 'pve-qm-bootdisk',
260 description
=> "Enable booting from specified disk.",
261 pattern
=> '(ide|sata|scsi|virtio)\d+',
266 description
=> "The number of CPUs. Please use option -sockets instead.",
273 description
=> "The number of CPU sockets.",
280 description
=> "The number of cores per socket.",
287 description
=> "Enable/disable ACPI.",
293 description
=> "Enable/disable Qemu GuestAgent.",
299 description
=> "Enable/disable KVM hardware virtualization.",
305 description
=> "Enable/disable time drift fix. This is ignored for kvm versions newer that 1.0 (not needed anymore).",
311 description
=> "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
316 description
=> "Freeze CPU at startup (use 'c' monitor command to start execution).",
321 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",
322 enum
=> [qw(std cirrus vmware)],
326 type
=> 'string', format
=> 'pve-qm-watchdog',
327 typetext
=> '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
328 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)",
333 typetext
=> "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
334 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'.",
335 pattern
=> '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
340 type
=> 'string', format
=> 'pve-qm-startup',
341 typetext
=> '[[order=]\d+] [,up=\d+] [,down=\d+] ',
342 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.",
347 description
=> <<EODESCR,
348 Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
350 args: -no-reboot -no-hpet
357 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.",
362 description
=> "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
366 migrate_downtime
=> {
369 description
=> "Set maximum tolerated downtime (in seconds) for migrations.",
375 type
=> 'string', format
=> 'pve-qm-drive',
376 typetext
=> 'volume',
377 description
=> "This is an alias for option -ide2",
381 description
=> "Emulated CPU type.",
383 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) ],
388 # what about other qemu settings ?
390 #machine => 'string',
403 ##soundhw => 'string',
405 while (my ($k, $v) = each %$confdesc) {
406 PVE
::JSONSchema
::register_standard_option
("pve-qm-$k", $v);
409 my $MAX_IDE_DISKS = 4;
410 my $MAX_SCSI_DISKS = 14;
411 my $MAX_VIRTIO_DISKS = 16;
412 my $MAX_SATA_DISKS = 6;
413 my $MAX_USB_DEVICES = 5;
415 my $MAX_UNUSED_DISKS = 8;
416 my $MAX_HOSTPCI_DEVICES = 2;
417 my $MAX_SERIAL_PORTS = 4;
418 my $MAX_PARALLEL_PORTS = 3;
420 my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
421 'ne2k_isa', 'i82551', 'i82557b', 'i82559er'];
422 my $nic_model_list_txt = join(' ', sort @$nic_model_list);
427 type
=> 'string', format
=> 'pve-qm-net',
428 typetext
=> "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,rate=<mbps>][,tag=<vlanid>]",
429 description
=> <<EODESCR,
430 Specify network devices.
432 MODEL is one of: $nic_model_list_txt
434 XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
435 automatically generated if not specified.
437 The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
439 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'.
441 If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
447 The DHCP server assign addresses to the guest starting from 10.0.2.15.
451 PVE
::JSONSchema
::register_standard_option
("pve-qm-net", $netdesc);
453 for (my $i = 0; $i < $MAX_NETS; $i++) {
454 $confdesc->{"net$i"} = $netdesc;
461 type
=> 'string', format
=> 'pve-qm-drive',
462 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]',
463 description
=> "Use volume as IDE hard disk or CD-ROM (n is 0 to " .($MAX_IDE_DISKS -1) . ").",
465 PVE
::JSONSchema
::register_standard_option
("pve-qm-ide", $idedesc);
469 type
=> 'string', format
=> 'pve-qm-drive',
470 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]',
471 description
=> "Use volume as SCSI hard disk or CD-ROM (n is 0 to " . ($MAX_SCSI_DISKS - 1) . ").",
473 PVE
::JSONSchema
::register_standard_option
("pve-qm-scsi", $scsidesc);
477 type
=> 'string', format
=> 'pve-qm-drive',
478 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]',
479 description
=> "Use volume as SATA hard disk or CD-ROM (n is 0 to " . ($MAX_SATA_DISKS - 1). ").",
481 PVE
::JSONSchema
::register_standard_option
("pve-qm-sata", $satadesc);
485 type
=> 'string', format
=> 'pve-qm-drive',
486 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]',
487 description
=> "Use volume as VIRTIO hard disk (n is 0 to " . ($MAX_VIRTIO_DISKS - 1) . ").",
489 PVE
::JSONSchema
::register_standard_option
("pve-qm-virtio", $virtiodesc);
493 type
=> 'string', format
=> 'pve-qm-usb-device',
494 typetext
=> 'host=HOSTUSBDEVICE',
495 description
=> <<EODESCR,
496 Configure an USB device (n is 0 to 4). This can be used to
497 pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
499 'bus-port(.port)*' (decimal numbers) or
500 'vendor_id:product_id' (hexadeciaml numbers)
502 You can use the 'lsusb -t' command to list existing usb devices.
504 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
508 PVE
::JSONSchema
::register_standard_option
("pve-qm-usb", $usbdesc);
512 type
=> 'string', format
=> 'pve-qm-hostpci',
513 typetext
=> "HOSTPCIDEVICE",
514 description
=> <<EODESCR,
515 Map host pci devices. HOSTPCIDEVICE syntax is:
517 'bus:dev.func' (hexadecimal numbers)
519 You can us the 'lspci' command to list existing pci devices.
521 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
523 Experimental: user reported problems with this option.
526 PVE
::JSONSchema
::register_standard_option
("pve-qm-hostpci", $hostpcidesc);
531 pattern
=> '/dev/ttyS\d+',
532 description
=> <<EODESCR,
533 Map host serial devices (n is 0 to 3).
535 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
537 Experimental: user reported problems with this option.
544 pattern
=> '/dev/parport\d+',
545 description
=> <<EODESCR,
546 Map host parallel devices (n is 0 to 2).
548 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
550 Experimental: user reported problems with this option.
554 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
555 $confdesc->{"parallel$i"} = $paralleldesc;
558 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
559 $confdesc->{"serial$i"} = $serialdesc;
562 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
563 $confdesc->{"hostpci$i"} = $hostpcidesc;
566 for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
567 $drivename_hash->{"ide$i"} = 1;
568 $confdesc->{"ide$i"} = $idedesc;
571 for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
572 $drivename_hash->{"sata$i"} = 1;
573 $confdesc->{"sata$i"} = $satadesc;
576 for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
577 $drivename_hash->{"scsi$i"} = 1;
578 $confdesc->{"scsi$i"} = $scsidesc ;
581 for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
582 $drivename_hash->{"virtio$i"} = 1;
583 $confdesc->{"virtio$i"} = $virtiodesc;
586 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
587 $confdesc->{"usb$i"} = $usbdesc;
592 type
=> 'string', format
=> 'pve-volume-id',
593 description
=> "Reference to unused volumes.",
596 for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
597 $confdesc->{"unused$i"} = $unuseddesc;
600 my $kvm_api_version = 0;
604 return $kvm_api_version if $kvm_api_version;
606 my $fh = IO
::File-
>new("</dev/kvm") ||
609 if (my $v = $fh->ioctl(KVM_GET_API_VERSION
(), 0)) {
610 $kvm_api_version = $v;
615 return $kvm_api_version;
618 my $kvm_user_version;
620 sub kvm_user_version
{
622 return $kvm_user_version if $kvm_user_version;
624 $kvm_user_version = 'unknown';
626 my $tmp = `kvm -help 2>/dev/null`;
628 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?) /) {
629 $kvm_user_version = $2;
632 return $kvm_user_version;
636 my $kernel_has_vhost_net = -c
'/dev/vhost-net';
639 # order is important - used to autoselect boot disk
640 return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
641 (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
642 (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
643 (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
646 sub valid_drivename
{
649 return defined($drivename_hash->{$dev});
654 return defined($confdesc->{$key});
658 return $nic_model_list;
661 sub os_list_description
{
666 w2k
=> 'Windows 2000',
667 w2k3
=>, 'Windows 2003',
668 w2k8
=> 'Windows 2008',
669 wvista
=> 'Windows Vista',
680 return $cdrom_path if $cdrom_path;
682 return $cdrom_path = "/dev/cdrom" if -l
"/dev/cdrom";
683 return $cdrom_path = "/dev/cdrom1" if -l
"/dev/cdrom1";
684 return $cdrom_path = "/dev/cdrom2" if -l
"/dev/cdrom2";
688 my ($storecfg, $vmid, $cdrom) = @_;
690 if ($cdrom eq 'cdrom') {
691 return get_cdrom_path
();
692 } elsif ($cdrom eq 'none') {
694 } elsif ($cdrom =~ m
|^/|) {
697 return PVE
::Storage
::path
($storecfg, $cdrom);
701 # try to convert old style file names to volume IDs
702 sub filename_to_volume_id
{
703 my ($vmid, $file, $media) = @_;
705 if (!($file eq 'none' || $file eq 'cdrom' ||
706 $file =~ m
|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
708 return undef if $file =~ m
|/|;
710 if ($media && $media eq 'cdrom') {
711 $file = "local:iso/$file";
713 $file = "local:$vmid/$file";
720 sub verify_media_type
{
721 my ($opt, $vtype, $media) = @_;
726 if ($media eq 'disk') {
728 } elsif ($media eq 'cdrom') {
731 die "internal error";
734 return if ($vtype eq $etype);
736 raise_param_exc
({ $opt => "unexpected media type ($vtype != $etype)" });
739 sub cleanup_drive_path
{
740 my ($opt, $storecfg, $drive) = @_;
742 # try to convert filesystem paths to volume IDs
744 if (($drive->{file
} !~ m/^(cdrom|none)$/) &&
745 ($drive->{file
} !~ m
|^/dev/.+|) &&
746 ($drive->{file
} !~ m/^([^:]+):(.+)$/) &&
747 ($drive->{file
} !~ m/^\d+$/)) {
748 my ($vtype, $volid) = PVE
::Storage
::path_to_volume_id
($storecfg, $drive->{file
});
749 raise_param_exc
({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
750 $drive->{media
} = 'cdrom' if !$drive->{media
} && $vtype eq 'iso';
751 verify_media_type
($opt, $vtype, $drive->{media
});
752 $drive->{file
} = $volid;
755 $drive->{media
} = 'cdrom' if !$drive->{media
} && $drive->{file
} =~ m/^(cdrom|none)$/;
758 sub create_conf_nolock
{
759 my ($vmid, $settings) = @_;
761 my $filename = config_file
($vmid);
763 die "configuration file '$filename' already exists\n" if -f
$filename;
765 my $defaults = load_defaults
();
767 $settings->{name
} = "vm$vmid" if !$settings->{name
};
768 $settings->{memory
} = $defaults->{memory
} if !$settings->{memory
};
771 foreach my $opt (keys %$settings) {
772 next if !$confdesc->{$opt};
774 my $value = $settings->{$opt};
777 $data .= "$opt: $value\n";
780 PVE
::Tools
::file_set_contents
($filename, $data);
783 my $parse_size = sub {
786 return undef if $value !~ m/^(\d+(\.\d+)?)([KMG])?$/;
787 my ($size, $unit) = ($1, $3);
790 $size = $size * 1024;
791 } elsif ($unit eq 'M') {
792 $size = $size * 1024 * 1024;
793 } elsif ($unit eq 'G') {
794 $size = $size * 1024 * 1024 * 1024;
800 my $format_size = sub {
805 my $kb = int($size/1024);
806 return $size if $kb*1024 != $size;
808 my $mb = int($kb/1024);
809 return "${kb}K" if $mb*1024 != $kb;
811 my $gb = int($mb/1024);
812 return "${mb}M" if $gb*1024 != $mb;
817 # ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
818 # [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
819 # [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
820 # [,aio=native|threads]
823 my ($key, $data) = @_;
827 # $key may be undefined - used to verify JSON parameters
828 if (!defined($key)) {
829 $res->{interface
} = 'unknown'; # should not harm when used to verify parameters
831 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
832 $res->{interface
} = $1;
838 foreach my $p (split (/,/, $data)) {
839 next if $p =~ m/^\s*$/;
841 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)=(.+)$/) {
842 my ($k, $v) = ($1, $2);
844 $k = 'file' if $k eq 'volume';
846 return undef if defined $res->{$k};
848 if ($k eq 'bps' || $k eq 'bps_rd' || $k eq 'bps_wr') {
849 return undef if !$v || $v !~ m/^\d+/;
851 $v = sprintf("%.3f", $v / (1024*1024));
855 if (!$res->{file
} && $p !~ m/=/) {
863 return undef if !$res->{file
};
865 return undef if $res->{cache
} &&
866 $res->{cache
} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
867 return undef if $res->{snapshot
} && $res->{snapshot
} !~ m/^(on|off)$/;
868 return undef if $res->{cyls
} && $res->{cyls
} !~ m/^\d+$/;
869 return undef if $res->{heads
} && $res->{heads
} !~ m/^\d+$/;
870 return undef if $res->{secs
} && $res->{secs
} !~ m/^\d+$/;
871 return undef if $res->{media
} && $res->{media
} !~ m/^(disk|cdrom)$/;
872 return undef if $res->{trans
} && $res->{trans
} !~ m/^(none|lba|auto)$/;
873 return undef if $res->{format
} && $res->{format
} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
874 return undef if $res->{rerror
} && $res->{rerror
} !~ m/^(ignore|report|stop)$/;
875 return undef if $res->{werror
} && $res->{werror
} !~ m/^(enospc|ignore|report|stop)$/;
876 return undef if $res->{backup
} && $res->{backup
} !~ m/^(yes|no)$/;
877 return undef if $res->{aio
} && $res->{aio
} !~ m/^(native|threads)$/;
880 return undef if $res->{mbps_rd
} && $res->{mbps
};
881 return undef if $res->{mbps_wr
} && $res->{mbps
};
883 return undef if $res->{mbps
} && $res->{mbps
} !~ m/^\d+(\.\d+)?$/;
884 return undef if $res->{mbps_rd
} && $res->{mbps_rd
} !~ m/^\d+(\.\d+)?$/;
885 return undef if $res->{mbps_wr
} && $res->{mbps_wr
} !~ m/^\d+(\.\d+)?$/;
887 return undef if $res->{iops_rd
} && $res->{iops
};
888 return undef if $res->{iops_wr
} && $res->{iops
};
889 return undef if $res->{iops
} && $res->{iops
} !~ m/^\d+$/;
890 return undef if $res->{iops_rd
} && $res->{iops_rd
} !~ m/^\d+$/;
891 return undef if $res->{iops_wr
} && $res->{iops_wr
} !~ m/^\d+$/;
895 return undef if !defined($res->{size
} = &$parse_size($res->{size
}));
898 if ($res->{media
} && ($res->{media
} eq 'cdrom')) {
899 return undef if $res->{snapshot
} || $res->{trans
} || $res->{format
};
900 return undef if $res->{heads
} || $res->{secs
} || $res->{cyls
};
901 return undef if $res->{interface
} eq 'virtio';
904 # rerror does not work with scsi drives
905 if ($res->{rerror
}) {
906 return undef if $res->{interface
} eq 'scsi';
912 my @qemu_drive_options = qw(heads secs cyls trans media format cache snapshot rerror werror aio iops iops_rd iops_wr);
915 my ($vmid, $drive) = @_;
918 foreach my $o (@qemu_drive_options, 'mbps', 'mbps_rd', 'mbps_wr', 'backup') {
919 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
922 if ($drive->{size
}) {
923 $opts .= ",size=" . &$format_size($drive->{size
});
926 return "$drive->{file}$opts";
930 my($fh, $noerr) = @_;
933 my $SG_GET_VERSION_NUM = 0x2282;
935 my $versionbuf = "\x00" x
8;
936 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
938 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
941 my $version = unpack("I", $versionbuf);
942 if ($version < 30000) {
943 die "scsi generic interface too old\n" if !$noerr;
947 my $buf = "\x00" x
36;
948 my $sensebuf = "\x00" x
8;
949 my $cmd = pack("C x3 C x11", 0x12, 36);
951 # see /usr/include/scsi/sg.h
952 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";
954 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
955 length($sensebuf), 0, length($buf), $buf,
956 $cmd, $sensebuf, 6000);
958 $ret = ioctl($fh, $SG_IO, $packet);
960 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
964 my @res = unpack($sg_io_hdr_t, $packet);
965 if ($res[17] || $res[18]) {
966 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
971 ($res->{device
}, $res->{removable
}, $res->{venodor
},
972 $res->{product
}, $res->{revision
}) = unpack("C C x6 A8 A16 A4", $buf);
980 my $fh = IO
::File-
>new("+<$path") || return undef;
981 my $res = scsi_inquiry
($fh, 1);
987 sub print_drivedevice_full
{
988 my ($storecfg, $conf, $vmid, $drive, $bridges) = @_;
993 if ($drive->{interface
} eq 'virtio') {
994 my $pciaddr = print_pci_addr
("$drive->{interface}$drive->{index}", $bridges);
995 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
996 } elsif ($drive->{interface
} eq 'scsi') {
997 $maxdev = ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi') ?
256 : 7;
998 my $controller = int($drive->{index} / $maxdev);
999 my $unit = $drive->{index} % $maxdev;
1000 my $devicetype = 'hd';
1002 if (drive_is_cdrom
($drive)) {
1005 if ($drive->{file
} =~ m
|^/|) {
1006 $path = $drive->{file
};
1008 $path = PVE
::Storage
::path
($storecfg, $drive->{file
});
1011 if($path =~ m/^iscsi\:\/\
//){
1012 $devicetype = 'generic';
1015 $devicetype = 'block' if path_is_scsi
($path);
1019 if (!$conf->{scsihw
} || $conf->{scsihw
} eq 'lsi'){
1020 $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';
1022 $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}";
1025 } elsif ($drive->{interface
} eq 'ide'){
1027 my $controller = int($drive->{index} / $maxdev);
1028 my $unit = $drive->{index} % $maxdev;
1029 my $devicetype = ($drive->{media
} && $drive->{media
} eq 'cdrom') ?
"cd" : "hd";
1031 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1032 } elsif ($drive->{interface
} eq 'sata'){
1033 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
1034 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1035 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1036 } elsif ($drive->{interface
} eq 'usb') {
1038 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1040 die "unsupported interface type";
1043 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex
};
1048 sub print_drive_full
{
1049 my ($storecfg, $vmid, $drive) = @_;
1052 foreach my $o (@qemu_drive_options) {
1053 next if $o eq 'bootindex';
1054 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
1057 foreach my $o (qw(bps bps_rd bps_wr)) {
1058 my $v = $drive->{"m$o"};
1059 $opts .= ",$o=" . int($v*1024*1024) if $v;
1062 # use linux-aio by default (qemu default is threads)
1063 $opts .= ",aio=native" if !$drive->{aio
};
1066 my $volid = $drive->{file
};
1067 if (drive_is_cdrom
($drive)) {
1068 $path = get_iso_path
($storecfg, $vmid, $volid);
1070 if ($volid =~ m
|^/|) {
1073 $path = PVE
::Storage
::path
($storecfg, $volid);
1075 if (!$drive->{cache
} && ($path =~ m
|^/dev/| || $path =~ m
|\
.raw
$|)) {
1076 $opts .= ",cache=none";
1080 my $pathinfo = $path ?
"file=$path," : '';
1082 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1085 sub print_netdevice_full
{
1086 my ($vmid, $conf, $net, $netid, $bridges) = @_;
1088 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
1090 my $device = $net->{model
};
1091 if ($net->{model
} eq 'virtio') {
1092 $device = 'virtio-net-pci';
1095 # qemu > 0.15 always try to boot from network - we disable that by
1096 # not loading the pxe rom file
1097 my $extra = ($bootorder !~ m/n/) ?
"romfile=," : '';
1098 my $pciaddr = print_pci_addr
("$netid", $bridges);
1099 my $tmpstr = "$device,${extra}mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
1100 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex
} ;
1104 sub print_netdev_full
{
1105 my ($vmid, $conf, $net, $netid) = @_;
1108 if ($netid =~ m/^net(\d+)$/) {
1112 die "got strange net id '$i'\n" if $i >= ${MAX_NETS
};
1114 my $ifname = "tap${vmid}i$i";
1116 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1117 die "interface name '$ifname' is too long (max 15 character)\n"
1118 if length($ifname) >= 16;
1120 my $vhostparam = '';
1121 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model
} eq 'virtio';
1123 my $vmname = $conf->{name
} || "vm$vmid";
1125 if ($net->{bridge
}) {
1126 return "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge$vhostparam";
1128 return "type=user,id=$netid,hostname=$vmname";
1132 sub drive_is_cdrom
{
1135 return $drive && $drive->{media
} && ($drive->{media
} eq 'cdrom');
1142 return undef if !$value;
1146 if ($value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/) {
1147 $res->{pciid
} = $value;
1155 # netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1161 foreach my $kvp (split(/,/, $data)) {
1163 if ($kvp =~ m/^(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
1165 my $mac = uc($3) || PVE
::Tools
::random_ether_addr
();
1166 $res->{model
} = $model;
1167 $res->{macaddr
} = $mac;
1168 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1169 $res->{bridge
} = $1;
1170 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1172 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1180 return undef if !$res->{model
};
1188 my $res = "$net->{model}";
1189 $res .= "=$net->{macaddr}" if $net->{macaddr
};
1190 $res .= ",bridge=$net->{bridge}" if $net->{bridge
};
1191 $res .= ",rate=$net->{rate}" if $net->{rate
};
1192 $res .= ",tag=$net->{tag}" if $net->{tag
};
1197 sub add_random_macs
{
1198 my ($settings) = @_;
1200 foreach my $opt (keys %$settings) {
1201 next if $opt !~ m/^net(\d+)$/;
1202 my $net = parse_net
($settings->{$opt});
1204 $settings->{$opt} = print_net
($net);
1208 sub add_unused_volume
{
1209 my ($config, $volid) = @_;
1212 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1213 my $test = "unused$ind";
1214 if (my $vid = $config->{$test}) {
1215 return if $vid eq $volid; # do not add duplicates
1221 die "To many unused volume - please delete them first.\n" if !$key;
1223 $config->{$key} = $volid;
1228 # fixme: remove all thos $noerr parameters?
1230 PVE
::JSONSchema
::register_format
('pve-qm-bootdisk', \
&verify_bootdisk
);
1231 sub verify_bootdisk
{
1232 my ($value, $noerr) = @_;
1234 return $value if valid_drivename
($value);
1236 return undef if $noerr;
1238 die "invalid boot disk '$value'\n";
1241 PVE
::JSONSchema
::register_format
('pve-qm-net', \
&verify_net
);
1243 my ($value, $noerr) = @_;
1245 return $value if parse_net
($value);
1247 return undef if $noerr;
1249 die "unable to parse network options\n";
1252 PVE
::JSONSchema
::register_format
('pve-qm-drive', \
&verify_drive
);
1254 my ($value, $noerr) = @_;
1256 return $value if parse_drive
(undef, $value);
1258 return undef if $noerr;
1260 die "unable to parse drive options\n";
1263 PVE
::JSONSchema
::register_format
('pve-qm-hostpci', \
&verify_hostpci
);
1264 sub verify_hostpci
{
1265 my ($value, $noerr) = @_;
1267 return $value if parse_hostpci
($value);
1269 return undef if $noerr;
1271 die "unable to parse pci id\n";
1274 PVE
::JSONSchema
::register_format
('pve-qm-watchdog', \
&verify_watchdog
);
1275 sub verify_watchdog
{
1276 my ($value, $noerr) = @_;
1278 return $value if parse_watchdog
($value);
1280 return undef if $noerr;
1282 die "unable to parse watchdog options\n";
1285 sub parse_watchdog
{
1288 return undef if !$value;
1292 foreach my $p (split(/,/, $value)) {
1293 next if $p =~ m/^\s*$/;
1295 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1297 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1298 $res->{action
} = $2;
1307 PVE
::JSONSchema
::register_format
('pve-qm-startup', \
&verify_startup
);
1308 sub verify_startup
{
1309 my ($value, $noerr) = @_;
1311 return $value if parse_startup
($value);
1313 return undef if $noerr;
1315 die "unable to parse startup options\n";
1321 return undef if !$value;
1325 foreach my $p (split(/,/, $value)) {
1326 next if $p =~ m/^\s*$/;
1328 if ($p =~ m/^(order=)?(\d+)$/) {
1330 } elsif ($p =~ m/^up=(\d+)$/) {
1332 } elsif ($p =~ m/^down=(\d+)$/) {
1342 sub parse_usb_device
{
1345 return undef if !$value;
1347 my @dl = split(/,/, $value);
1351 foreach my $v (@dl) {
1352 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1354 $res->{vendorid
} = $2;
1355 $res->{productid
} = $4;
1356 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1358 $res->{hostbus
} = $1;
1359 $res->{hostport
} = $2;
1364 return undef if !$found;
1369 PVE
::JSONSchema
::register_format
('pve-qm-usb-device', \
&verify_usb_device
);
1370 sub verify_usb_device
{
1371 my ($value, $noerr) = @_;
1373 return $value if parse_usb_device
($value);
1375 return undef if $noerr;
1377 die "unable to parse usb device\n";
1380 # add JSON properties for create and set function
1381 sub json_config_properties
{
1384 foreach my $opt (keys %$confdesc) {
1385 $prop->{$opt} = $confdesc->{$opt};
1392 my ($key, $value) = @_;
1394 die "unknown setting '$key'\n" if !$confdesc->{$key};
1396 my $type = $confdesc->{$key}->{type
};
1398 if (!defined($value)) {
1399 die "got undefined value\n";
1402 if ($value =~ m/[\n\r]/) {
1403 die "property contains a line feed\n";
1406 if ($type eq 'boolean') {
1407 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1408 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1409 die "type check ('boolean') failed - got '$value'\n";
1410 } elsif ($type eq 'integer') {
1411 return int($1) if $value =~ m/^(\d+)$/;
1412 die "type check ('integer') failed - got '$value'\n";
1413 } elsif ($type eq 'string') {
1414 if (my $fmt = $confdesc->{$key}->{format
}) {
1415 if ($fmt eq 'pve-qm-drive') {
1416 # special case - we need to pass $key to parse_drive()
1417 my $drive = parse_drive
($key, $value);
1418 return $value if $drive;
1419 die "unable to parse drive options\n";
1421 PVE
::JSONSchema
::check_format
($fmt, $value);
1424 $value =~ s/^\"(.*)\"$/$1/;
1427 die "internal error"
1431 sub lock_config_full
{
1432 my ($vmid, $timeout, $code, @param) = @_;
1434 my $filename = config_file_lock
($vmid);
1436 my $res = lock_file
($filename, $timeout, $code, @param);
1444 my ($vmid, $code, @param) = @_;
1446 return lock_config_full
($vmid, 10, $code, @param);
1449 sub cfs_config_path
{
1450 my ($vmid, $node) = @_;
1452 $node = $nodename if !$node;
1453 return "nodes/$node/qemu-server/$vmid.conf";
1456 sub check_iommu_support
{
1457 #fixme : need to check IOMMU support
1458 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1466 my ($vmid, $node) = @_;
1468 my $cfspath = cfs_config_path
($vmid, $node);
1469 return "/etc/pve/$cfspath";
1472 sub config_file_lock
{
1475 return "$lock_dir/lock-$vmid.conf";
1481 my $conf = config_file
($vmid);
1482 utime undef, undef, $conf;
1486 my ($storecfg, $vmid, $keep_empty_config) = @_;
1488 my $conffile = config_file
($vmid);
1490 my $conf = load_config
($vmid);
1494 # only remove disks owned by this VM
1495 foreach_drive
($conf, sub {
1496 my ($ds, $drive) = @_;
1498 return if drive_is_cdrom
($drive);
1500 my $volid = $drive->{file
};
1501 return if !$volid || $volid =~ m
|^/|;
1503 my ($path, $owner) = PVE
::Storage
::path
($storecfg, $volid);
1504 return if !$path || !$owner || ($owner != $vmid);
1506 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1509 if ($keep_empty_config) {
1510 PVE
::Tools
::file_set_contents
($conffile, "memory: 128\n");
1515 # also remove unused disk
1517 my $dl = PVE
::Storage
::vdisk_list
($storecfg, undef, $vmid);
1520 PVE
::Storage
::foreach_volid
($dl, sub {
1521 my ($volid, $sid, $volname, $d) = @_;
1522 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1532 my ($vmid, $node) = @_;
1534 my $cfspath = cfs_config_path
($vmid, $node);
1536 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath);
1538 die "no such VM ('$vmid')\n" if !defined($conf);
1543 sub parse_vm_config
{
1544 my ($filename, $raw) = @_;
1546 return undef if !defined($raw);
1549 digest
=> Digest
::SHA
::sha1_hex
($raw),
1552 $filename =~ m
|/qemu-server/(\d
+)\
.conf
$|
1553 || die "got strange filename '$filename'";
1559 while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
1562 next if $line =~ m/^\s*$/;
1564 if ($line =~ m/^\#(.*)\s*$/) {
1565 $descr .= PVE
::Tools
::decode_text
($1) . "\n";
1569 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
1570 $descr .= PVE
::Tools
::decode_text
($2);
1571 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1574 $res->{$key} = $value;
1575 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1578 eval { $value = check_type
($key, $value); };
1580 warn "vm $vmid - unable to parse value of '$key' - $@";
1582 my $fmt = $confdesc->{$key}->{format
};
1583 if ($fmt && $fmt eq 'pve-qm-drive') {
1584 my $v = parse_drive
($key, $value);
1585 if (my $volid = filename_to_volume_id
($vmid, $v->{file
}, $v->{media
})) {
1586 $v->{file
} = $volid;
1587 $value = print_drive
($vmid, $v);
1589 warn "vm $vmid - unable to parse value of '$key'\n";
1594 if ($key eq 'cdrom') {
1595 $res->{ide2
} = $value;
1597 $res->{$key} = $value;
1603 $res->{description
} = $descr if $descr;
1605 # convert old smp to sockets
1606 if ($res->{smp
} && !$res->{sockets
}) {
1607 $res->{sockets
} = $res->{smp
};
1614 sub write_vm_config
{
1615 my ($filename, $conf) = @_;
1617 if ($conf->{cdrom
}) {
1618 die "option ide2 conflicts with cdrom\n" if $conf->{ide2
};
1619 $conf->{ide2
} = $conf->{cdrom
};
1620 delete $conf->{cdrom
};
1623 # we do not use 'smp' any longer
1624 if ($conf->{sockets
}) {
1625 delete $conf->{smp
};
1626 } elsif ($conf->{smp
}) {
1627 $conf->{sockets
} = $conf->{smp
};
1628 delete $conf->{cores
};
1629 delete $conf->{smp
};
1632 my $new_volids = {};
1633 foreach my $key (keys %$conf) {
1634 next if $key eq 'digest' || $key eq 'description';
1635 my $value = $conf->{$key};
1636 eval { $value = check_type
($key, $value); };
1637 die "unable to parse value of '$key' - $@" if $@;
1639 $conf->{$key} = $value;
1641 if (valid_drivename
($key)) {
1642 my $drive = PVE
::QemuServer
::parse_drive
($key, $value);
1643 $new_volids->{$drive->{file
}} = 1 if $drive && $drive->{file
};
1647 # remove 'unusedX' settings if we re-add a volume
1648 foreach my $key (keys %$conf) {
1649 my $value = $conf->{$key};
1650 if ($key =~ m/^unused/ && $new_volids->{$value}) {
1651 delete $conf->{$key};
1658 # add description as comment to top of file
1659 my $descr = $conf->{description
} || '';
1660 foreach my $cl (split(/\n/, $descr)) {
1661 $raw .= '#' . PVE
::Tools
::encode_text
($cl) . "\n";
1664 foreach my $key (sort keys %$conf) {
1665 next if $key eq 'digest' || $key eq 'description';
1666 $raw .= "$key: $conf->{$key}\n";
1672 sub update_config_nolock
{
1673 my ($vmid, $conf, $skiplock) = @_;
1675 check_lock
($conf) if !$skiplock;
1677 my $cfspath = cfs_config_path
($vmid);
1679 PVE
::Cluster
::cfs_write_file
($cfspath, $conf);
1683 my ($vmid, $conf, $skiplock) = @_;
1685 lock_config
($vmid, &update_config_nolock
, $conf, $skiplock);
1692 # we use static defaults from our JSON schema configuration
1693 foreach my $key (keys %$confdesc) {
1694 if (defined(my $default = $confdesc->{$key}->{default})) {
1695 $res->{$key} = $default;
1699 my $conf = PVE
::Cluster
::cfs_read_file
('datacenter.cfg');
1700 $res->{keyboard
} = $conf->{keyboard
} if $conf->{keyboard
};
1706 my $vmlist = PVE
::Cluster
::get_vmlist
();
1708 return $res if !$vmlist || !$vmlist->{ids
};
1709 my $ids = $vmlist->{ids
};
1711 foreach my $vmid (keys %$ids) {
1712 my $d = $ids->{$vmid};
1713 next if !$d->{node
} || $d->{node
} ne $nodename;
1714 next if !$d->{type
} || $d->{type
} ne 'qemu';
1715 $res->{$vmid}->{exists} = 1;
1720 # test if VM uses local resources (to prevent migration)
1721 sub check_local_resources
{
1722 my ($conf, $noerr) = @_;
1726 $loc_res = 1 if $conf->{hostusb
}; # old syntax
1727 $loc_res = 1 if $conf->{hostpci
}; # old syntax
1729 foreach my $k (keys %$conf) {
1730 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
1733 die "VM uses local resources\n" if $loc_res && !$noerr;
1738 # check is used storages are available on all nodes (use by migrate)
1739 sub check_storage_availability
{
1740 my ($storecfg, $conf, $node) = @_;
1742 foreach_drive
($conf, sub {
1743 my ($ds, $drive) = @_;
1745 my $volid = $drive->{file
};
1748 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
1751 # check if storage is available on both nodes
1752 my $scfg = PVE
::Storage
::storage_check_node
($storecfg, $sid);
1753 PVE
::Storage
::storage_check_node
($storecfg, $sid, $node);
1760 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1764 my ($pidfile, $pid) = @_;
1766 my $fh = IO
::File-
>new("/proc/$pid/cmdline", "r");
1770 return undef if !$line;
1771 my @param = split(/\0/, $line);
1773 my $cmd = $param[0];
1774 return if !$cmd || ($cmd !~ m
|kvm
$|);
1776 for (my $i = 0; $i < scalar (@param); $i++) {
1779 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1780 my $p = $param[$i+1];
1781 return 1 if $p && ($p eq $pidfile);
1790 my ($vmid, $nocheck, $node) = @_;
1792 my $filename = config_file
($vmid, $node);
1794 die "unable to find configuration file for VM $vmid - no such machine\n"
1795 if !$nocheck && ! -f
$filename;
1797 my $pidfile = pidfile_name
($vmid);
1799 if (my $fd = IO
::File-
>new("<$pidfile")) {
1804 my $mtime = $st->mtime;
1805 if ($mtime > time()) {
1806 warn "file '$filename' modified in future\n";
1809 if ($line =~ m/^(\d+)$/) {
1811 if (check_cmdline
($pidfile, $pid)) {
1812 if (my $pinfo = PVE
::ProcFSTools
::check_process_running
($pid)) {
1824 my $vzlist = config_list
();
1826 my $fd = IO
::Dir-
>new($var_run_tmpdir) || return $vzlist;
1828 while (defined(my $de = $fd->read)) {
1829 next if $de !~ m/^(\d+)\.pid$/;
1831 next if !defined($vzlist->{$vmid});
1832 if (my $pid = check_running
($vmid)) {
1833 $vzlist->{$vmid}->{pid
} = $pid;
1841 my ($storecfg, $conf) = @_;
1843 my $bootdisk = $conf->{bootdisk
};
1844 return undef if !$bootdisk;
1845 return undef if !valid_drivename
($bootdisk);
1847 return undef if !$conf->{$bootdisk};
1849 my $drive = parse_drive
($bootdisk, $conf->{$bootdisk});
1850 return undef if !defined($drive);
1852 return undef if drive_is_cdrom
($drive);
1854 my $volid = $drive->{file
};
1855 return undef if !$volid;
1857 return $drive->{size
};
1860 my $last_proc_pid_stat;
1862 # get VM status information
1863 # This must be fast and should not block ($full == false)
1864 # We only query KVM using QMP if $full == true (this can be slow)
1866 my ($opt_vmid, $full) = @_;
1870 my $storecfg = PVE
::Storage
::config
();
1872 my $list = vzlist
();
1873 my ($uptime) = PVE
::ProcFSTools
::read_proc_uptime
(1);
1875 my $cpucount = $cpuinfo->{cpus
} || 1;
1877 foreach my $vmid (keys %$list) {
1878 next if $opt_vmid && ($vmid ne $opt_vmid);
1880 my $cfspath = cfs_config_path
($vmid);
1881 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath) || {};
1884 $d->{pid
} = $list->{$vmid}->{pid
};
1886 # fixme: better status?
1887 $d->{status
} = $list->{$vmid}->{pid
} ?
'running' : 'stopped';
1889 my $size = disksize
($storecfg, $conf);
1890 if (defined($size)) {
1891 $d->{disk
} = 0; # no info available
1892 $d->{maxdisk
} = $size;
1898 $d->{cpus
} = ($conf->{sockets
} || 1) * ($conf->{cores
} || 1);
1899 $d->{cpus
} = $cpucount if $d->{cpus
} > $cpucount;
1901 $d->{name
} = $conf->{name
} || "VM $vmid";
1902 $d->{maxmem
} = $conf->{memory
} ?
$conf->{memory
}*(1024*1024) : 0;
1912 $d->{diskwrite
} = 0;
1917 my $netdev = PVE
::ProcFSTools
::read_proc_net_dev
();
1918 foreach my $dev (keys %$netdev) {
1919 next if $dev !~ m/^tap([1-9]\d*)i/;
1921 my $d = $res->{$vmid};
1924 $d->{netout
} += $netdev->{$dev}->{receive
};
1925 $d->{netin
} += $netdev->{$dev}->{transmit
};
1928 my $ctime = gettimeofday
;
1930 foreach my $vmid (keys %$list) {
1932 my $d = $res->{$vmid};
1933 my $pid = $d->{pid
};
1936 my $pstat = PVE
::ProcFSTools
::read_proc_pid_stat
($pid);
1937 next if !$pstat; # not running
1939 my $used = $pstat->{utime} + $pstat->{stime
};
1941 $d->{uptime
} = int(($uptime - $pstat->{starttime
})/$cpuinfo->{user_hz
});
1943 if ($pstat->{vsize
}) {
1944 $d->{mem
} = int(($pstat->{rss
}/$pstat->{vsize
})*$d->{maxmem
});
1947 my $old = $last_proc_pid_stat->{$pid};
1949 $last_proc_pid_stat->{$pid} = {
1957 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz
};
1959 if ($dtime > 1000) {
1960 my $dutime = $used - $old->{used
};
1962 $d->{cpu
} = (($dutime/$dtime)* $cpucount) / $d->{cpus
};
1963 $last_proc_pid_stat->{$pid} = {
1969 $d->{cpu
} = $old->{cpu
};
1973 return $res if !$full;
1975 my $qmpclient = PVE
::QMPClient-
>new();
1977 my $blockstatscb = sub {
1978 my ($vmid, $resp) = @_;
1979 my $data = $resp->{'return'} || [];
1980 my $totalrdbytes = 0;
1981 my $totalwrbytes = 0;
1982 for my $blockstat (@$data) {
1983 $totalrdbytes = $totalrdbytes + $blockstat->{stats
}->{rd_bytes
};
1984 $totalwrbytes = $totalwrbytes + $blockstat->{stats
}->{wr_bytes
};
1986 $res->{$vmid}->{diskread
} = $totalrdbytes;
1987 $res->{$vmid}->{diskwrite
} = $totalwrbytes;
1990 my $statuscb = sub {
1991 my ($vmid, $resp) = @_;
1992 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
1994 my $status = 'unknown';
1995 if (!defined($status = $resp->{'return'}->{status
})) {
1996 warn "unable to get VM status\n";
2000 $res->{$vmid}->{qmpstatus
} = $resp->{'return'}->{status
};
2003 foreach my $vmid (keys %$list) {
2004 next if $opt_vmid && ($vmid ne $opt_vmid);
2005 next if !$res->{$vmid}->{pid
}; # not running
2006 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
2009 $qmpclient->queue_execute();
2011 foreach my $vmid (keys %$list) {
2012 next if $opt_vmid && ($vmid ne $opt_vmid);
2013 $res->{$vmid}->{qmpstatus
} = $res->{$vmid}->{status
} if !$res->{$vmid}->{qmpstatus
};
2020 my ($conf, $func) = @_;
2022 foreach my $ds (keys %$conf) {
2023 next if !valid_drivename
($ds);
2025 my $drive = parse_drive
($ds, $conf->{$ds});
2028 &$func($ds, $drive);
2032 sub config_to_command
{
2033 my ($storecfg, $vmid, $conf, $defaults, $migrate_uri) = @_;
2039 my $kvmver = kvm_user_version
();
2040 my $vernum = 0; # unknown
2041 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2042 $vernum = $1*1000000+$2*1000;
2043 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
2044 $vernum = $1*1000000+$2*1000+$3;
2047 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
2049 my $have_ovz = -f
'/proc/vz/vestat';
2051 push @$cmd, '/usr/bin/kvm';
2053 push @$cmd, '-id', $vmid;
2057 my $qmpsocket = qmp_socket
($vmid);
2058 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2059 push @$cmd, '-mon', "chardev=qmp,mode=control";
2061 my $socket = vnc_socket
($vmid);
2062 push @$cmd, '-vnc', "unix:$socket,x509,password";
2064 push @$cmd, '-pidfile' , pidfile_name
($vmid);
2066 push @$cmd, '-daemonize';
2068 push @$cmd, '-incoming', $migrate_uri if $migrate_uri;
2070 push @$cmd, '-S' if $migrate_uri;
2073 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2074 next if !$conf->{"usb$i"};
2077 # include usb device config
2078 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
2080 # enable absolute mouse coordinates (needed by vnc)
2081 my $tablet = defined($conf->{tablet
}) ?
$conf->{tablet
} : $defaults->{tablet
};
2084 push @$devices, '-device', 'usb-tablet,bus=ehci.0,port=6';
2086 push @$devices, '-usbdevice', 'tablet';
2091 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2092 my $d = parse_hostpci
($conf->{"hostpci$i"});
2094 $pciaddr = print_pci_addr
("hostpci$i", $bridges);
2095 push @$devices, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
2099 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2100 my $d = parse_usb_device
($conf->{"usb$i"});
2102 if ($d->{vendorid
} && $d->{productid
}) {
2103 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
2104 } elsif (defined($d->{hostbus
}) && defined($d->{hostport
})) {
2105 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
2110 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
2111 if (my $path = $conf->{"serial$i"}) {
2112 die "no such serial device\n" if ! -c
$path;
2113 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2114 push @$devices, '-device', "isa-serial,chardev=serial$i";
2119 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
2120 if (my $path = $conf->{"parallel$i"}) {
2121 die "no such parallel device\n" if ! -c
$path;
2122 push @$devices, '-chardev', "parport,id=parallel$i,path=$path";
2123 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
2127 my $vmname = $conf->{name
} || "vm$vmid";
2129 push @$cmd, '-name', $vmname;
2132 $sockets = $conf->{smp
} if $conf->{smp
}; # old style - no longer iused
2133 $sockets = $conf->{sockets
} if $conf->{sockets
};
2135 my $cores = $conf->{cores
} || 1;
2137 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2139 push @$cmd, '-cpu', $conf->{cpu
} if $conf->{cpu
};
2141 push @$cmd, '-nodefaults';
2143 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
2145 my $bootindex_hash = {};
2147 foreach my $o (split(//, $bootorder)) {
2148 $bootindex_hash->{$o} = $i*100;
2152 push @$cmd, '-boot', "menu=on";
2154 push @$cmd, '-no-acpi' if defined($conf->{acpi
}) && $conf->{acpi
} == 0;
2156 push @$cmd, '-no-reboot' if defined($conf->{reboot
}) && $conf->{reboot
} == 0;
2158 my $vga = $conf->{vga
};
2160 if ($conf->{ostype
} && ($conf->{ostype
} eq 'win7' || $conf->{ostype
} eq 'w2k8')) {
2167 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2170 my $tdf = defined($conf->{tdf
}) ?
$conf->{tdf
} : $defaults->{tdf
};
2171 # ignore - no longer supported by newer kvm
2172 # push @$cmd, '-tdf' if $tdf;
2174 my $nokvm = defined($conf->{kvm
}) && $conf->{kvm
} == 0 ?
1 : 0;
2176 if (my $ost = $conf->{ostype
}) {
2177 # other, wxp, w2k, w2k3, w2k8, wvista, win7, l24, l26
2179 if ($ost =~ m/^w/) { # windows
2180 push @$cmd, '-localtime' if !defined($conf->{localtime});
2182 # use rtc-td-hack when acpi is enabled
2183 if (!(defined($conf->{acpi
}) && $conf->{acpi
} == 0)) {
2184 push @$cmd, '-rtc-td-hack';
2188 if ($ost eq 'win7' || $ost eq 'w2k8' || $ost eq 'wvista') {
2189 push @$cmd, '-no-kvm-pit-reinjection';
2190 push @$cmd, '-no-hpet';
2200 push @$cmd, '-no-kvm';
2202 die "No accelerator found!\n" if !$cpuinfo->{hvm
};
2205 push @$cmd, '-localtime' if $conf->{localtime};
2207 push @$cmd, '-startdate', $conf->{startdate
} if $conf->{startdate
};
2209 push @$cmd, '-S' if $conf->{freeze
};
2211 # set keyboard layout
2212 my $kb = $conf->{keyboard
} || $defaults->{keyboard
};
2213 push @$cmd, '-k', $kb if $kb;
2216 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2217 #push @$cmd, '-soundhw', 'es1370';
2218 #push @$cmd, '-soundhw', $soundhw if $soundhw;
2220 if($conf->{agent
}) {
2221 my $qgasocket = qga_socket
($vmid);
2222 my $pciaddr = print_pci_addr
("qga0", $bridges);
2223 push @$devices, '-chardev', "socket,path=$qgasocket,server,nowait,id=qga0";
2224 push @$devices, '-device', "virtio-serial,id=qga0$pciaddr";
2225 push @$devices, '-device', 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0';
2228 $pciaddr = print_pci_addr
("balloon0", $bridges);
2229 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr" if $conf->{balloon
};
2231 if ($conf->{watchdog
}) {
2232 my $wdopts = parse_watchdog
($conf->{watchdog
});
2233 $pciaddr = print_pci_addr
("watchdog", $bridges);
2234 my $watchdog = $wdopts->{model
} || 'i6300esb';
2235 push @$devices, '-device', "$watchdog$pciaddr";
2236 push @$devices, '-watchdog-action', $wdopts->{action
} if $wdopts->{action
};
2240 my $scsicontroller = {};
2241 my $ahcicontroller = {};
2242 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : $defaults->{scsihw
};
2244 foreach_drive
($conf, sub {
2245 my ($ds, $drive) = @_;
2247 if (PVE
::Storage
::parse_volume_id
($drive->{file
}, 1)) {
2248 push @$vollist, $drive->{file
};
2251 $use_virtio = 1 if $ds =~ m/^virtio/;
2253 if (drive_is_cdrom
($drive)) {
2254 if ($bootindex_hash->{d
}) {
2255 $drive->{bootindex
} = $bootindex_hash->{d
};
2256 $bootindex_hash->{d
} += 1;
2259 if ($bootindex_hash->{c
}) {
2260 $drive->{bootindex
} = $bootindex_hash->{c
} if $conf->{bootdisk
} && ($conf->{bootdisk
} eq $ds);
2261 $bootindex_hash->{c
} += 1;
2265 if ($drive->{interface
} eq 'scsi') {
2267 my $maxdev = ($scsihw ne 'lsi') ?
256 : 7;
2268 my $controller = int($drive->{index} / $maxdev);
2269 $pciaddr = print_pci_addr
("scsihw$controller", $bridges);
2270 push @$devices, '-device', "$scsihw,id=scsihw$controller$pciaddr" if !$scsicontroller->{$controller};
2271 $scsicontroller->{$controller}=1;
2274 if ($drive->{interface
} eq 'sata') {
2275 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
2276 $pciaddr = print_pci_addr
("ahci$controller", $bridges);
2277 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
2278 $ahcicontroller->{$controller}=1;
2281 push @$devices, '-drive',print_drive_full
($storecfg, $vmid, $drive);
2282 push @$devices, '-device',print_drivedevice_full
($storecfg, $conf, $vmid, $drive, $bridges);
2285 push @$cmd, '-m', $conf->{memory
} || $defaults->{memory
};
2287 for (my $i = 0; $i < $MAX_NETS; $i++) {
2288 next if !$conf->{"net$i"};
2289 my $d = parse_net
($conf->{"net$i"});
2292 $use_virtio = 1 if $d->{model
} eq 'virtio';
2294 if ($bootindex_hash->{n
}) {
2295 $d->{bootindex
} = $bootindex_hash->{n
};
2296 $bootindex_hash->{n
} += 1;
2299 my $netdevfull = print_netdev_full
($vmid,$conf,$d,"net$i");
2300 push @$devices, '-netdev', $netdevfull;
2302 my $netdevicefull = print_netdevice_full
($vmid,$conf,$d,"net$i",$bridges);
2303 push @$devices, '-device', $netdevicefull;
2307 while (my ($k, $v) = each %$bridges) {
2308 $pciaddr = print_pci_addr
("pci.$k");
2309 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
2313 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2314 # when the VM uses virtio devices.
2315 if (!$use_virtio && $have_ovz) {
2317 my $cpuunits = defined($conf->{cpuunits
}) ?
2318 $conf->{cpuunits
} : $defaults->{cpuunits
};
2320 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2322 # fixme: cpulimit is currently ignored
2323 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2327 if ($conf->{args
}) {
2328 my $aa = PVE
::Tools
::split_args
($conf->{args
});
2332 push @$cmd, @$devices;
2333 return wantarray ?
($cmd, $vollist) : $cmd;
2338 return "${var_run_tmpdir}/$vmid.vnc";
2343 return "${var_run_tmpdir}/$vmid.qmp";
2348 return "${var_run_tmpdir}/$vmid.qga";
2353 return "${var_run_tmpdir}/$vmid.pid";
2356 sub next_migrate_port
{
2358 for (my $p = 60000; $p < 60010; $p++) {
2360 my $sock = IO
::Socket
::INET-
>new(Listen
=> 5,
2361 LocalAddr
=> 'localhost',
2372 die "unable to find free migration port";
2375 sub vm_devices_list
{
2378 my $res = vm_mon_cmd
($vmid, 'query-pci');
2381 foreach my $pcibus (@$res) {
2382 foreach my $device (@{$pcibus->{devices
}}) {
2383 next if !$device->{'qdev_id'};
2384 $devices->{$device->{'qdev_id'}} = $device;
2392 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
2394 return 1 if !check_running
($vmid) || !$conf->{hotplug
};
2396 my $devices_list = vm_devices_list
($vmid);
2397 return 1 if defined($devices_list->{$deviceid});
2399 qemu_bridgeadd
($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
2401 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2402 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2403 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
2404 qemu_deviceadd
($vmid, $devicefull);
2405 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2406 qemu_drivedel
($vmid, $deviceid);
2411 if ($deviceid =~ m/^(scsihw)(\d+)$/) {
2412 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : "lsi";
2413 my $pciaddr = print_pci_addr
($deviceid);
2414 my $devicefull = "$scsihw,id=$deviceid$pciaddr";
2415 qemu_deviceadd
($vmid, $devicefull);
2416 return undef if(!qemu_deviceaddverify
($vmid, $deviceid));
2419 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2420 return 1 if ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi'); #virtio-scsi not yet support hotplug
2421 return undef if !qemu_findorcreatescsihw
($storecfg,$conf, $vmid, $device);
2422 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2423 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
2424 if(!qemu_deviceadd
($vmid, $devicefull)) {
2425 qemu_drivedel
($vmid, $deviceid);
2430 if ($deviceid =~ m/^(net)(\d+)$/) {
2431 return undef if !qemu_netdevadd
($vmid, $conf, $device, $deviceid);
2432 my $netdevicefull = print_netdevice_full
($vmid, $conf, $device, $deviceid);
2433 qemu_deviceadd
($vmid, $netdevicefull);
2434 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2435 qemu_netdevdel
($vmid, $deviceid);
2440 if ($deviceid =~ m/^(pci\.)(\d+)$/) {
2442 my $pciaddr = print_pci_addr
($deviceid);
2443 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
2444 qemu_deviceadd
($vmid, $devicefull);
2445 return undef if !qemu_deviceaddverify
($vmid, $deviceid);
2451 sub vm_deviceunplug
{
2452 my ($vmid, $conf, $deviceid) = @_;
2454 return 1 if !check_running
($vmid) || !$conf->{hotplug
};
2456 my $devices_list = vm_devices_list
($vmid);
2457 return 1 if !defined($devices_list->{$deviceid});
2459 die "can't unplug bootdisk" if $conf->{bootdisk
} && $conf->{bootdisk
} eq $deviceid;
2461 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2462 return undef if !qemu_drivedel
($vmid, $deviceid);
2463 qemu_devicedel
($vmid, $deviceid);
2464 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2467 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2468 return undef if !qemu_devicedel
($vmid, $deviceid);
2471 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2472 return undef if !qemu_devicedel
($vmid, $deviceid);
2473 return undef if !qemu_drivedel
($vmid, $deviceid);
2476 if ($deviceid =~ m/^(net)(\d+)$/) {
2477 return undef if !qemu_netdevdel
($vmid, $deviceid);
2478 qemu_devicedel
($vmid, $deviceid);
2479 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2485 sub qemu_deviceadd
{
2486 my ($vmid, $devicefull) = @_;
2488 my $ret = vm_human_monitor_command
($vmid, "device_add $devicefull");
2490 # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
2491 return 1 if $ret eq "";
2492 syslog
("err", "error on hotplug device : $ret");
2497 sub qemu_devicedel
{
2498 my($vmid, $deviceid) = @_;
2500 my $ret = vm_human_monitor_command
($vmid, "device_del $deviceid");
2502 return 1 if $ret eq "";
2503 syslog
("err", "detaching device $deviceid failed : $ret");
2508 my($storecfg, $vmid, $device) = @_;
2510 my $drive = print_drive_full
($storecfg, $vmid, $device);
2511 my $ret = vm_human_monitor_command
($vmid, "drive_add auto $drive");
2512 # If the command succeeds qemu prints: "OK"
2513 if ($ret !~ m/OK/s) {
2514 syslog
("err", "adding drive failed: $ret");
2521 my($vmid, $deviceid) = @_;
2523 my $ret = vm_human_monitor_command
($vmid, "drive_del drive-$deviceid");
2525 if ($ret =~ m/Device \'.*?\' not found/s) {
2526 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
2528 elsif ($ret ne "") {
2529 syslog
("err", "deleting drive $deviceid failed : $ret");
2535 sub qemu_deviceaddverify
{
2536 my ($vmid,$deviceid) = @_;
2538 for (my $i = 0; $i <= 5; $i++) {
2539 my $devices_list = vm_devices_list
($vmid);
2540 return 1 if defined($devices_list->{$deviceid});
2543 syslog
("err", "error on hotplug device $deviceid");
2548 sub qemu_devicedelverify
{
2549 my ($vmid,$deviceid) = @_;
2551 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2552 for (my $i = 0; $i <= 5; $i++) {
2553 my $devices_list = vm_devices_list
($vmid);
2554 return 1 if !defined($devices_list->{$deviceid});
2557 syslog
("err", "error on hot-unplugging device $deviceid");
2561 sub qemu_findorcreatescsihw
{
2562 my ($storecfg, $conf, $vmid, $device) = @_;
2564 my $maxdev = ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi') ?
256 : 7;
2565 my $controller = int($device->{index} / $maxdev);
2566 my $scsihwid="scsihw$controller";
2567 my $devices_list = vm_devices_list
($vmid);
2569 if(!defined($devices_list->{$scsihwid})) {
2570 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $scsihwid);
2575 sub qemu_bridgeadd
{
2576 my ($storecfg, $conf, $vmid, $device) = @_;
2579 my $bridgeid = undef;
2580 print_pci_addr
($device, $bridges);
2582 while (my ($k, $v) = each %$bridges) {
2585 return if $bridgeid < 1;
2586 my $bridge = "pci.$bridgeid";
2587 my $devices_list = vm_devices_list
($vmid);
2589 if(!defined($devices_list->{$bridge})) {
2590 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $bridge);
2595 sub qemu_netdevadd
{
2596 my ($vmid, $conf, $device, $deviceid) = @_;
2598 my $netdev = print_netdev_full
($vmid, $conf, $device, $deviceid);
2599 my $ret = vm_human_monitor_command
($vmid, "netdev_add $netdev");
2602 #if the command succeeds, no output is sent. So any non-empty string shows an error
2603 return 1 if $ret eq "";
2604 syslog
("err", "adding netdev failed: $ret");
2608 sub qemu_netdevdel
{
2609 my ($vmid, $deviceid) = @_;
2611 my $ret = vm_human_monitor_command
($vmid, "netdev_del $deviceid");
2613 #if the command succeeds, no output is sent. So any non-empty string shows an error
2614 return 1 if $ret eq "";
2615 syslog
("err", "deleting netdev failed: $ret");
2619 sub qemu_block_set_io_throttle
{
2620 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2622 return if !check_running
($vmid) ;
2625 $bps_rd = 0 if !$bps_rd;
2626 $bps_wr = 0 if !$bps_wr;
2627 $iops = 0 if !$iops;
2628 $iops_rd = 0 if !$iops_rd;
2629 $iops_wr = 0 if !$iops_wr;
2631 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));
2635 # old code, only used to shutdown old VM after update
2637 my ($fh, $timeout) = @_;
2639 my $sel = new IO
::Select
;
2646 while (scalar (@ready = $sel->can_read($timeout))) {
2648 if ($count = $fh->sysread($buf, 8192)) {
2649 if ($buf =~ /^(.*)\(qemu\) $/s) {
2656 if (!defined($count)) {
2663 die "monitor read timeout\n" if !scalar(@ready);
2668 # old code, only used to shutdown old VM after update
2669 sub vm_monitor_command
{
2670 my ($vmid, $cmdstr, $nocheck) = @_;
2675 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
2677 my $sname = "${var_run_tmpdir}/$vmid.mon";
2679 my $sock = IO
::Socket
::UNIX-
>new( Peer
=> $sname ) ||
2680 die "unable to connect to VM $vmid socket - $!\n";
2684 # hack: migrate sometime blocks the monitor (when migrate_downtime
2686 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2687 $timeout = 60*60; # 1 hour
2691 my $data = __read_avail
($sock, $timeout);
2693 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2694 die "got unexpected qemu monitor banner\n";
2697 my $sel = new IO
::Select
;
2700 if (!scalar(my @ready = $sel->can_write($timeout))) {
2701 die "monitor write error - timeout";
2704 my $fullcmd = "$cmdstr\r";
2706 # syslog('info', "VM $vmid monitor command: $cmdstr");
2709 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
2710 die "monitor write error - $!";
2713 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2717 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2718 $timeout = 60*60; # 1 hour
2719 } elsif ($cmdstr =~ m/^(eject|change)/) {
2720 $timeout = 60; # note: cdrom mount command is slow
2722 if ($res = __read_avail
($sock, $timeout)) {
2724 my @lines = split("\r?\n", $res);
2726 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
2728 $res = join("\n", @lines);
2736 syslog
("err", "VM $vmid monitor command failed - $err");
2743 sub qemu_block_resize
{
2744 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
2746 my $running = PVE
::QemuServer
::check_running
($vmid);
2748 return if !PVE
::Storage
::volume_resize
($storecfg, $volid, $size, $running);
2750 return if !$running;
2752 vm_mon_cmd
($vmid, "block_resize", device
=> $deviceid, size
=> int($size));
2757 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom) = @_;
2759 lock_config
($vmid, sub {
2760 my $conf = load_config
($vmid, $migratedfrom);
2762 check_lock
($conf) if !$skiplock;
2764 die "VM $vmid already running\n" if check_running
($vmid, undef, $migratedfrom);
2767 my $migrate_port = 0;
2770 if ($statefile eq 'tcp') {
2771 $migrate_port = next_migrate_port
();
2772 $migrate_uri = "tcp:localhost:${migrate_port}";
2774 if (-f
$statefile) {
2775 $migrate_uri = "exec:cat $statefile";
2777 warn "state file '$statefile' does not exist - doing normal startup\n";
2782 my $defaults = load_defaults
();
2784 # set environment variable useful inside network script
2785 $ENV{PVE_MIGRATED_FROM
} = $migratedfrom if $migratedfrom;
2787 my ($cmd, $vollist) = config_to_command
($storecfg, $vmid, $conf, $defaults, $migrate_uri);
2789 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2790 my $d = parse_hostpci
($conf->{"hostpci$i"});
2792 my $info = pci_device_info
("0000:$d->{pciid}");
2793 die "IOMMU not present\n" if !check_iommu_support
();
2794 die "no pci device info for device '$d->{pciid}'\n" if !$info;
2795 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub
($info);
2796 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset
($info);
2799 PVE
::Storage
::activate_volumes
($storecfg, $vollist);
2801 eval { run_command
($cmd, timeout
=> $migrate_uri ?
undef : 30); };
2803 die "start failed: $err" if $err;
2807 if ($statefile eq 'tcp') {
2808 print "migration listens on port $migrate_port\n";
2811 # fixme: send resume - is that necessary ?
2812 eval { vm_mon_cmd
($vmid, "cont"); };
2816 # always set migrate speed (overwrite kvm default of 32m)
2817 # we set a very hight default of 8192m which is basically unlimited
2818 my $migrate_speed = $defaults->{migrate_speed
} || 8192;
2819 $migrate_speed = $conf->{migrate_speed
} || $migrate_speed;
2820 $migrate_speed = $migrate_speed * 1048576;
2822 vm_mon_cmd
($vmid, "migrate_set_speed", value
=> $migrate_speed);
2825 my $migrate_downtime = $defaults->{migrate_downtime
};
2826 $migrate_downtime = $conf->{migrate_downtime
} if defined($conf->{migrate_downtime
});
2827 if (defined($migrate_downtime)) {
2828 eval { vm_mon_cmd
($vmid, "migrate_set_downtime", value
=> $migrate_downtime); };
2832 my $capabilities = {};
2833 $capabilities->{capability
} = "xbzrle";
2834 $capabilities->{state} = JSON
::true
;
2835 eval { PVE
::QemuServer
::vm_mon_cmd_nocheck
($vmid, "migrate-set-capabilities", capabilities
=> [$capabilities]); };
2838 vm_balloonset
($vmid, $conf->{balloon
}) if $conf->{balloon
};
2844 my ($vmid, $execute, %params) = @_;
2846 my $cmd = { execute
=> $execute, arguments
=> \
%params };
2847 vm_qmp_command
($vmid, $cmd);
2850 sub vm_mon_cmd_nocheck
{
2851 my ($vmid, $execute, %params) = @_;
2853 my $cmd = { execute
=> $execute, arguments
=> \
%params };
2854 vm_qmp_command
($vmid, $cmd, 1);
2857 sub vm_qmp_command
{
2858 my ($vmid, $cmd, $nocheck) = @_;
2863 if ($cmd->{arguments
} && $cmd->{arguments
}->{timeout
}) {
2864 $timeout = $cmd->{arguments
}->{timeout
};
2865 delete $cmd->{arguments
}->{timeout
};
2869 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
2870 my $sname = PVE
::QemuServer
::qmp_socket
($vmid);
2872 my $qmpclient = PVE
::QMPClient-
>new();
2874 $res = $qmpclient->cmd($vmid, $cmd, $timeout);
2875 } elsif (-e
"${var_run_tmpdir}/$vmid.mon") {
2876 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
2877 if scalar(%{$cmd->{arguments
}});
2878 vm_monitor_command
($vmid, $cmd->{execute
}, $nocheck);
2880 die "unable to open monitor socket\n";
2884 syslog
("err", "VM $vmid qmp command failed - $err");
2891 sub vm_human_monitor_command
{
2892 my ($vmid, $cmdline) = @_;
2897 execute
=> 'human-monitor-command',
2898 arguments
=> { 'command-line' => $cmdline},
2901 return vm_qmp_command
($vmid, $cmd);
2904 sub vm_commandline
{
2905 my ($storecfg, $vmid) = @_;
2907 my $conf = load_config
($vmid);
2909 my $defaults = load_defaults
();
2911 my $cmd = config_to_command
($storecfg, $vmid, $conf, $defaults);
2913 return join(' ', @$cmd);
2917 my ($vmid, $skiplock) = @_;
2919 lock_config
($vmid, sub {
2921 my $conf = load_config
($vmid);
2923 check_lock
($conf) if !$skiplock;
2925 vm_mon_cmd
($vmid, "system_reset");
2929 sub get_vm_volumes
{
2933 foreach_drive
($conf, sub {
2934 my ($ds, $drive) = @_;
2936 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($drive->{file
}, 1);
2939 my $volid = $drive->{file
};
2940 return if !$volid || $volid =~ m
|^/|;
2942 push @$vollist, $volid;
2948 sub vm_stop_cleanup
{
2949 my ($storecfg, $vmid, $conf, $keepActive) = @_;
2952 fairsched_rmnod
($vmid); # try to destroy group
2955 my $vollist = get_vm_volumes
($conf);
2956 PVE
::Storage
::deactivate_volumes
($storecfg, $vollist);
2959 foreach my $ext (qw(mon qmp pid vnc qga)) {
2960 unlink "/var/run/qemu-server/${vmid}.$ext";
2963 warn $@ if $@; # avoid errors - just warn
2966 # Note: use $nockeck to skip tests if VM configuration file exists.
2967 # We need that when migration VMs to other nodes (files already moved)
2968 # Note: we set $keepActive in vzdump stop mode - volumes need to stay active
2970 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive, $migratedfrom) = @_;
2972 $force = 1 if !defined($force) && !$shutdown;
2975 my $pid = check_running
($vmid, $nocheck, $migratedfrom);
2976 kill 15, $pid if $pid;
2977 my $conf = load_config
($vmid, $migratedfrom);
2978 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive);
2982 lock_config
($vmid, sub {
2984 my $pid = check_running
($vmid, $nocheck);
2989 $conf = load_config
($vmid);
2990 check_lock
($conf) if !$skiplock;
2991 if (!defined($timeout) && $shutdown && $conf->{startup
}) {
2992 my $opts = parse_startup
($conf->{startup
});
2993 $timeout = $opts->{down
} if $opts->{down
};
2997 $timeout = 60 if !defined($timeout);
3001 $nocheck ? vm_mon_cmd_nocheck
($vmid, "system_powerdown") : vm_mon_cmd
($vmid, "system_powerdown");
3004 $nocheck ? vm_mon_cmd_nocheck
($vmid, "quit") : vm_mon_cmd
($vmid, "quit");
3011 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
3016 if ($count >= $timeout) {
3018 warn "VM still running - terminating now with SIGTERM\n";
3021 die "VM quit/powerdown failed - got timeout\n";
3024 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
3029 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
3032 die "VM quit/powerdown failed\n";
3040 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
3045 if ($count >= $timeout) {
3046 warn "VM still running - terminating now with SIGKILL\n";
3051 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
3056 my ($vmid, $skiplock) = @_;
3058 lock_config
($vmid, sub {
3060 my $conf = load_config
($vmid);
3062 check_lock
($conf) if !$skiplock;
3064 vm_mon_cmd
($vmid, "stop");
3069 my ($vmid, $skiplock) = @_;
3071 lock_config
($vmid, sub {
3073 my $conf = load_config
($vmid);
3075 check_lock
($conf) if !$skiplock;
3077 vm_mon_cmd
($vmid, "cont");
3082 my ($vmid, $skiplock, $key) = @_;
3084 lock_config
($vmid, sub {
3086 my $conf = load_config
($vmid);
3088 # there is no qmp command, so we use the human monitor command
3089 vm_human_monitor_command
($vmid, "sendkey $key");
3094 my ($storecfg, $vmid, $skiplock) = @_;
3096 lock_config
($vmid, sub {
3098 my $conf = load_config
($vmid);
3100 check_lock
($conf) if !$skiplock;
3102 if (!check_running
($vmid)) {
3103 fairsched_rmnod
($vmid); # try to destroy group
3104 destroy_vm
($storecfg, $vmid);
3106 die "VM $vmid is running - destroy failed\n";
3114 my ($filename, $buf) = @_;
3116 my $fh = IO
::File-
>new($filename, "w");
3117 return undef if !$fh;
3119 my $res = print $fh $buf;
3126 sub pci_device_info
{
3131 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
3132 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
3134 my $irq = file_read_firstline
("$pcisysfs/devices/$name/irq");
3135 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3137 my $vendor = file_read_firstline
("$pcisysfs/devices/$name/vendor");
3138 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3140 my $product = file_read_firstline
("$pcisysfs/devices/$name/device");
3141 return undef if !defined($product) || $product !~ s/^0x//;
3146 product
=> $product,
3152 has_fl_reset
=> -f
"$pcisysfs/devices/$name/reset" || 0,
3161 my $name = $dev->{name
};
3163 my $fn = "$pcisysfs/devices/$name/reset";
3165 return file_write
($fn, "1");
3168 sub pci_dev_bind_to_stub
{
3171 my $name = $dev->{name
};
3173 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3174 return 1 if -d
$testdir;
3176 my $data = "$dev->{vendor} $dev->{product}";
3177 return undef if !file_write
("$pcisysfs/drivers/pci-stub/new_id", $data);
3179 my $fn = "$pcisysfs/devices/$name/driver/unbind";
3180 if (!file_write
($fn, $name)) {
3181 return undef if -f
$fn;
3184 $fn = "$pcisysfs/drivers/pci-stub/bind";
3185 if (! -d
$testdir) {
3186 return undef if !file_write
($fn, $name);
3192 sub print_pci_addr
{
3193 my ($id, $bridges) = @_;
3197 #addr1 : ide,parallel,serial (motherboard)
3198 #addr2 : first videocard
3199 balloon0
=> { bus
=> 0, addr
=> 3 },
3200 watchdog
=> { bus
=> 0, addr
=> 4 },
3201 scsihw0
=> { bus
=> 0, addr
=> 5 },
3202 scsihw1
=> { bus
=> 0, addr
=> 6 },
3203 ahci0
=> { bus
=> 0, addr
=> 7 },
3204 qga0
=> { bus
=> 0, addr
=> 8 },
3205 virtio0
=> { bus
=> 0, addr
=> 10 },
3206 virtio1
=> { bus
=> 0, addr
=> 11 },
3207 virtio2
=> { bus
=> 0, addr
=> 12 },
3208 virtio3
=> { bus
=> 0, addr
=> 13 },
3209 virtio4
=> { bus
=> 0, addr
=> 14 },
3210 virtio5
=> { bus
=> 0, addr
=> 15 },
3211 hostpci0
=> { bus
=> 0, addr
=> 16 },
3212 hostpci1
=> { bus
=> 0, addr
=> 17 },
3213 net0
=> { bus
=> 0, addr
=> 18 },
3214 net1
=> { bus
=> 0, addr
=> 19 },
3215 net2
=> { bus
=> 0, addr
=> 20 },
3216 net3
=> { bus
=> 0, addr
=> 21 },
3217 net4
=> { bus
=> 0, addr
=> 22 },
3218 net5
=> { bus
=> 0, addr
=> 23 },
3219 #addr29 : usb-host (pve-usb.cfg)
3220 'pci.1' => { bus
=> 0, addr
=> 30 },
3221 'pci.2' => { bus
=> 0, addr
=> 31 },
3222 'net6' => { bus
=> 1, addr
=> 1 },
3223 'net7' => { bus
=> 1, addr
=> 2 },
3224 'net8' => { bus
=> 1, addr
=> 3 },
3225 'net9' => { bus
=> 1, addr
=> 4 },
3226 'net10' => { bus
=> 1, addr
=> 5 },
3227 'net11' => { bus
=> 1, addr
=> 6 },
3228 'net12' => { bus
=> 1, addr
=> 7 },
3229 'net13' => { bus
=> 1, addr
=> 8 },
3230 'net14' => { bus
=> 1, addr
=> 9 },
3231 'net15' => { bus
=> 1, addr
=> 10 },
3232 'net16' => { bus
=> 1, addr
=> 11 },
3233 'net17' => { bus
=> 1, addr
=> 12 },
3234 'net18' => { bus
=> 1, addr
=> 13 },
3235 'net19' => { bus
=> 1, addr
=> 14 },
3236 'net20' => { bus
=> 1, addr
=> 15 },
3237 'net21' => { bus
=> 1, addr
=> 16 },
3238 'net22' => { bus
=> 1, addr
=> 17 },
3239 'net23' => { bus
=> 1, addr
=> 18 },
3240 'net24' => { bus
=> 1, addr
=> 19 },
3241 'net25' => { bus
=> 1, addr
=> 20 },
3242 'net26' => { bus
=> 1, addr
=> 21 },
3243 'net27' => { bus
=> 1, addr
=> 22 },
3244 'net28' => { bus
=> 1, addr
=> 23 },
3245 'net29' => { bus
=> 1, addr
=> 24 },
3246 'net30' => { bus
=> 1, addr
=> 25 },
3247 'net31' => { bus
=> 1, addr
=> 26 },
3248 'virtio6' => { bus
=> 2, addr
=> 1 },
3249 'virtio7' => { bus
=> 2, addr
=> 2 },
3250 'virtio8' => { bus
=> 2, addr
=> 3 },
3251 'virtio9' => { bus
=> 2, addr
=> 4 },
3252 'virtio10' => { bus
=> 2, addr
=> 5 },
3253 'virtio11' => { bus
=> 2, addr
=> 6 },
3254 'virtio12' => { bus
=> 2, addr
=> 7 },
3255 'virtio13' => { bus
=> 2, addr
=> 8 },
3256 'virtio14' => { bus
=> 2, addr
=> 9 },
3257 'virtio15' => { bus
=> 2, addr
=> 10 },
3260 if (defined($devices->{$id}->{bus
}) && defined($devices->{$id}->{addr
})) {
3261 my $addr = sprintf("0x%x", $devices->{$id}->{addr
});
3262 my $bus = $devices->{$id}->{bus
};
3263 $res = ",bus=pci.$bus,addr=$addr";
3264 $bridges->{$bus} = 1 if $bridges;
3271 my ($vmid, $value) = @_;
3273 vm_mon_cmd
($vmid, "balloon", value
=> $value);
3276 # vzdump restore implementaion
3278 sub archive_read_firstfile
{
3279 my $archive = shift;
3281 die "ERROR: file '$archive' does not exist\n" if ! -f
$archive;
3283 # try to detect archive type first
3284 my $pid = open (TMP
, "tar tf '$archive'|") ||
3285 die "unable to open file '$archive'\n";
3286 my $firstfile = <TMP
>;
3290 die "ERROR: archive contaions no data\n" if !$firstfile;
3296 sub restore_cleanup
{
3297 my $statfile = shift;
3299 print STDERR
"starting cleanup\n";
3301 if (my $fd = IO
::File-
>new($statfile, "r")) {
3302 while (defined(my $line = <$fd>)) {
3303 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3306 if ($volid =~ m
|^/|) {
3307 unlink $volid || die 'unlink failed\n';
3309 my $cfg = cfs_read_file
('storage.cfg');
3310 PVE
::Storage
::vdisk_free
($cfg, $volid);
3312 print STDERR
"temporary volume '$volid' sucessfuly removed\n";
3314 print STDERR
"unable to cleanup '$volid' - $@" if $@;
3316 print STDERR
"unable to parse line in statfile - $line";
3323 sub restore_archive
{
3324 my ($archive, $vmid, $user, $opts) = @_;
3326 if ($archive ne '-') {
3327 my $firstfile = archive_read_firstfile
($archive);
3328 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
3329 if $firstfile ne 'qemu-server.conf';
3332 my $tocmd = "/usr/lib/qemu-server/qmextract";
3334 $tocmd .= " --storage " . PVE
::Tools
::shellquote
($opts->{storage
}) if $opts->{storage
};
3335 $tocmd .= " --pool " . PVE
::Tools
::shellquote
($opts->{pool
}) if $opts->{pool
};
3336 $tocmd .= ' --prealloc' if $opts->{prealloc
};
3337 $tocmd .= ' --info' if $opts->{info
};
3339 # tar option "xf" does not autodetect compression when read from STDIN,
3340 # so we pipe to zcat
3341 my $cmd = "zcat -f|tar xf " . PVE
::Tools
::shellquote
($archive) . " " .
3342 PVE
::Tools
::shellquote
("--to-command=$tocmd");
3344 my $tmpdir = "/var/tmp/vzdumptmp$$";
3347 local $ENV{VZDUMP_TMPDIR
} = $tmpdir;
3348 local $ENV{VZDUMP_VMID
} = $vmid;
3349 local $ENV{VZDUMP_USER
} = $user;
3351 my $conffile = PVE
::QemuServer
::config_file
($vmid);
3352 my $tmpfn = "$conffile.$$.tmp";
3354 # disable interrupts (always do cleanups)
3355 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
3356 print STDERR
"got interrupt - ignored\n";
3361 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
3362 die "interrupted by signal\n";
3365 if ($archive eq '-') {
3366 print "extracting archive from STDIN\n";
3367 run_command
($cmd, input
=> "<&STDIN");
3369 print "extracting archive '$archive'\n";
3373 return if $opts->{info
};
3377 my $statfile = "$tmpdir/qmrestore.stat";
3378 if (my $fd = IO
::File-
>new($statfile, "r")) {
3379 while (defined (my $line = <$fd>)) {
3380 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3381 $map->{$1} = $2 if $1;
3383 print STDERR
"unable to parse line in statfile - $line\n";
3389 my $confsrc = "$tmpdir/qemu-server.conf";
3391 my $srcfd = new IO
::File
($confsrc, "r") ||
3392 die "unable to open file '$confsrc'\n";
3394 my $outfd = new IO
::File
($tmpfn, "w") ||
3395 die "unable to write config for VM $vmid\n";
3399 while (defined (my $line = <$srcfd>)) {
3400 next if $line =~ m/^\#vzdump\#/;
3401 next if $line =~ m/^lock:/;
3402 next if $line =~ m/^unused\d+:/;
3404 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3405 # try to convert old 1.X settings
3406 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3407 foreach my $devconfig (PVE
::Tools
::split_list
($ethcfg)) {
3408 my ($model, $macaddr) = split(/\=/, $devconfig);
3409 $macaddr = PVE
::Tools
::random_ether_addr
() if !$macaddr || $opts->{unique
};
3412 bridge
=> "vmbr$ind",
3413 macaddr
=> $macaddr,
3415 my $netstr = print_net
($net);
3416 print $outfd "net${netcount}: $netstr\n";
3419 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && ($opts->{unique
})) {
3420 my ($id, $netstr) = ($1, $2);
3421 my $net = parse_net
($netstr);
3422 $net->{macaddr
} = PVE
::Tools
::random_ether_addr
() if $net->{macaddr
};
3423 $netstr = print_net
($net);
3424 print $outfd "$id: $netstr\n";
3425 } elsif ($line =~ m/^((ide|scsi|virtio)\d+):\s*(\S+)\s*$/) {
3428 if ($line =~ m/backup=no/) {
3429 print $outfd "#$line";
3430 } elsif ($virtdev && $map->{$virtdev}) {
3431 my $di = PVE
::QemuServer
::parse_drive
($virtdev, $value);
3432 $di->{file
} = $map->{$virtdev};
3433 $value = PVE
::QemuServer
::print_drive
($vmid, $di);
3434 print $outfd "$virtdev: $value\n";
3452 restore_cleanup
("$tmpdir/qmrestore.stat") if !$opts->{info
};
3459 rename $tmpfn, $conffile ||
3460 die "unable to commit configuration file '$conffile'\n";