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)],
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|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 KVM hardware virtualization.",
299 description
=> "Enable/disable time drift fix. This is ignored for kvm versions newer that 1.0 (not needed anymore).",
305 description
=> "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.",
310 description
=> "Freeze CPU at startup (use 'c' monitor command to start execution).",
315 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",
316 enum
=> [qw(std cirrus vmware)],
320 type
=> 'string', format
=> 'pve-qm-watchdog',
321 typetext
=> '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]',
322 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)",
327 typetext
=> "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)",
328 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'.",
329 pattern
=> '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)',
334 type
=> 'string', format
=> 'pve-qm-startup',
335 typetext
=> '[[order=]\d+] [,up=\d+] [,down=\d+] ',
336 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.",
341 description
=> <<EODESCR,
342 Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
344 args: -no-reboot -no-hpet
351 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.",
356 description
=> "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.",
360 migrate_downtime
=> {
363 description
=> "Set maximum tolerated downtime (in seconds) for migrations.",
369 type
=> 'string', format
=> 'pve-qm-drive',
370 typetext
=> 'volume',
371 description
=> "This is an alias for option -ide2",
375 description
=> "Emulated CPU type.",
377 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) ],
382 # what about other qemu settings ?
384 #machine => 'string',
397 ##soundhw => 'string',
399 while (my ($k, $v) = each %$confdesc) {
400 PVE
::JSONSchema
::register_standard_option
("pve-qm-$k", $v);
403 my $MAX_IDE_DISKS = 4;
404 my $MAX_SCSI_DISKS = 14;
405 my $MAX_VIRTIO_DISKS = 16;
406 my $MAX_SATA_DISKS = 6;
407 my $MAX_USB_DEVICES = 5;
409 my $MAX_UNUSED_DISKS = 8;
410 my $MAX_HOSTPCI_DEVICES = 2;
411 my $MAX_SERIAL_PORTS = 4;
412 my $MAX_PARALLEL_PORTS = 3;
414 my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000', 'pcnet', 'virtio',
415 'ne2k_isa', 'i82551', 'i82557b', 'i82559er'];
416 my $nic_model_list_txt = join(' ', sort @$nic_model_list);
421 type
=> 'string', format
=> 'pve-qm-net',
422 typetext
=> "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,rate=<mbps>][,tag=<vlanid>]",
423 description
=> <<EODESCR,
424 Specify network devices.
426 MODEL is one of: $nic_model_list_txt
428 XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
429 automatically generated if not specified.
431 The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
433 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'.
435 If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
441 The DHCP server assign addresses to the guest starting from 10.0.2.15.
445 PVE
::JSONSchema
::register_standard_option
("pve-qm-net", $netdesc);
447 for (my $i = 0; $i < $MAX_NETS; $i++) {
448 $confdesc->{"net$i"} = $netdesc;
455 type
=> 'string', format
=> 'pve-qm-drive',
456 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]',
457 description
=> "Use volume as IDE hard disk or CD-ROM (n is 0 to " .($MAX_IDE_DISKS -1) . ").",
459 PVE
::JSONSchema
::register_standard_option
("pve-qm-ide", $idedesc);
463 type
=> 'string', format
=> 'pve-qm-drive',
464 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]',
465 description
=> "Use volume as SCSI hard disk or CD-ROM (n is 0 to " . ($MAX_SCSI_DISKS - 1) . ").",
467 PVE
::JSONSchema
::register_standard_option
("pve-qm-scsi", $scsidesc);
471 type
=> 'string', format
=> 'pve-qm-drive',
472 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]',
473 description
=> "Use volume as SATA hard disk or CD-ROM (n is 0 to " . ($MAX_SATA_DISKS - 1). ").",
475 PVE
::JSONSchema
::register_standard_option
("pve-qm-sata", $satadesc);
479 type
=> 'string', format
=> 'pve-qm-drive',
480 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]',
481 description
=> "Use volume as VIRTIO hard disk (n is 0 to " . ($MAX_VIRTIO_DISKS - 1) . ").",
483 PVE
::JSONSchema
::register_standard_option
("pve-qm-virtio", $virtiodesc);
487 type
=> 'string', format
=> 'pve-qm-usb-device',
488 typetext
=> 'host=HOSTUSBDEVICE',
489 description
=> <<EODESCR,
490 Configure an USB device (n is 0 to 4). This can be used to
491 pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
493 'bus-port(.port)*' (decimal numbers) or
494 'vendor_id:product_id' (hexadeciaml numbers)
496 You can use the 'lsusb -t' command to list existing usb devices.
498 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
502 PVE
::JSONSchema
::register_standard_option
("pve-qm-usb", $usbdesc);
506 type
=> 'string', format
=> 'pve-qm-hostpci',
507 typetext
=> "HOSTPCIDEVICE",
508 description
=> <<EODESCR,
509 Map host pci devices. HOSTPCIDEVICE syntax is:
511 'bus:dev.func' (hexadecimal numbers)
513 You can us the 'lspci' command to list existing pci devices.
515 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
517 Experimental: user reported problems with this option.
520 PVE
::JSONSchema
::register_standard_option
("pve-qm-hostpci", $hostpcidesc);
525 pattern
=> '/dev/ttyS\d+',
526 description
=> <<EODESCR,
527 Map host serial devices (n is 0 to 3).
529 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
531 Experimental: user reported problems with this option.
538 pattern
=> '/dev/parport\d+',
539 description
=> <<EODESCR,
540 Map host parallel devices (n is 0 to 2).
542 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
544 Experimental: user reported problems with this option.
548 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
549 $confdesc->{"parallel$i"} = $paralleldesc;
552 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
553 $confdesc->{"serial$i"} = $serialdesc;
556 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
557 $confdesc->{"hostpci$i"} = $hostpcidesc;
560 for (my $i = 0; $i < $MAX_IDE_DISKS; $i++) {
561 $drivename_hash->{"ide$i"} = 1;
562 $confdesc->{"ide$i"} = $idedesc;
565 for (my $i = 0; $i < $MAX_SATA_DISKS; $i++) {
566 $drivename_hash->{"sata$i"} = 1;
567 $confdesc->{"sata$i"} = $satadesc;
570 for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++) {
571 $drivename_hash->{"scsi$i"} = 1;
572 $confdesc->{"scsi$i"} = $scsidesc ;
575 for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++) {
576 $drivename_hash->{"virtio$i"} = 1;
577 $confdesc->{"virtio$i"} = $virtiodesc;
580 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
581 $confdesc->{"usb$i"} = $usbdesc;
586 type
=> 'string', format
=> 'pve-volume-id',
587 description
=> "Reference to unused volumes.",
590 for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++) {
591 $confdesc->{"unused$i"} = $unuseddesc;
594 my $kvm_api_version = 0;
598 return $kvm_api_version if $kvm_api_version;
600 my $fh = IO
::File-
>new("</dev/kvm") ||
603 if (my $v = $fh->ioctl(KVM_GET_API_VERSION
(), 0)) {
604 $kvm_api_version = $v;
609 return $kvm_api_version;
612 my $kvm_user_version;
614 sub kvm_user_version
{
616 return $kvm_user_version if $kvm_user_version;
618 $kvm_user_version = 'unknown';
620 my $tmp = `kvm -help 2>/dev/null`;
622 if ($tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+(\.\d+)?) /) {
623 $kvm_user_version = $2;
626 return $kvm_user_version;
630 my $kernel_has_vhost_net = -c
'/dev/vhost-net';
633 # order is important - used to autoselect boot disk
634 return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
635 (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
636 (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
637 (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
640 sub valid_drivename
{
643 return defined($drivename_hash->{$dev});
648 return defined($confdesc->{$key});
652 return $nic_model_list;
655 sub os_list_description
{
660 w2k
=> 'Windows 2000',
661 w2k3
=>, 'Windows 2003',
662 w2k8
=> 'Windows 2008',
663 wvista
=> 'Windows Vista',
674 return $cdrom_path if $cdrom_path;
676 return $cdrom_path = "/dev/cdrom" if -l
"/dev/cdrom";
677 return $cdrom_path = "/dev/cdrom1" if -l
"/dev/cdrom1";
678 return $cdrom_path = "/dev/cdrom2" if -l
"/dev/cdrom2";
682 my ($storecfg, $vmid, $cdrom) = @_;
684 if ($cdrom eq 'cdrom') {
685 return get_cdrom_path
();
686 } elsif ($cdrom eq 'none') {
688 } elsif ($cdrom =~ m
|^/|) {
691 return PVE
::Storage
::path
($storecfg, $cdrom);
695 # try to convert old style file names to volume IDs
696 sub filename_to_volume_id
{
697 my ($vmid, $file, $media) = @_;
699 if (!($file eq 'none' || $file eq 'cdrom' ||
700 $file =~ m
|^/dev/.+| || $file =~ m/^([^:]+):(.+)$/)) {
702 return undef if $file =~ m
|/|;
704 if ($media && $media eq 'cdrom') {
705 $file = "local:iso/$file";
707 $file = "local:$vmid/$file";
714 sub verify_media_type
{
715 my ($opt, $vtype, $media) = @_;
720 if ($media eq 'disk') {
722 } elsif ($media eq 'cdrom') {
725 die "internal error";
728 return if ($vtype eq $etype);
730 raise_param_exc
({ $opt => "unexpected media type ($vtype != $etype)" });
733 sub cleanup_drive_path
{
734 my ($opt, $storecfg, $drive) = @_;
736 # try to convert filesystem paths to volume IDs
738 if (($drive->{file
} !~ m/^(cdrom|none)$/) &&
739 ($drive->{file
} !~ m
|^/dev/.+|) &&
740 ($drive->{file
} !~ m/^([^:]+):(.+)$/) &&
741 ($drive->{file
} !~ m/^\d+$/)) {
742 my ($vtype, $volid) = PVE
::Storage
::path_to_volume_id
($storecfg, $drive->{file
});
743 raise_param_exc
({ $opt => "unable to associate path '$drive->{file}' to any storage"}) if !$vtype;
744 $drive->{media
} = 'cdrom' if !$drive->{media
} && $vtype eq 'iso';
745 verify_media_type
($opt, $vtype, $drive->{media
});
746 $drive->{file
} = $volid;
749 $drive->{media
} = 'cdrom' if !$drive->{media
} && $drive->{file
} =~ m/^(cdrom|none)$/;
752 sub create_conf_nolock
{
753 my ($vmid, $settings) = @_;
755 my $filename = config_file
($vmid);
757 die "configuration file '$filename' already exists\n" if -f
$filename;
759 my $defaults = load_defaults
();
761 $settings->{name
} = "vm$vmid" if !$settings->{name
};
762 $settings->{memory
} = $defaults->{memory
} if !$settings->{memory
};
765 foreach my $opt (keys %$settings) {
766 next if !$confdesc->{$opt};
768 my $value = $settings->{$opt};
771 $data .= "$opt: $value\n";
774 PVE
::Tools
::file_set_contents
($filename, $data);
777 # ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
778 # [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
779 # [,rerror=ignore|report|stop][,werror=enospc|ignore|report|stop]
780 # [,aio=native|threads]
783 my ($key, $data) = @_;
787 # $key may be undefined - used to verify JSON parameters
788 if (!defined($key)) {
789 $res->{interface
} = 'unknown'; # should not harm when used to verify parameters
791 } elsif ($key =~ m/^([^\d]+)(\d+)$/) {
792 $res->{interface
} = $1;
798 foreach my $p (split (/,/, $data)) {
799 next if $p =~ m/^\s*$/;
801 if ($p =~ m/^(file|volume|cyls|heads|secs|trans|media|snapshot|cache|format|rerror|werror|backup|aio|bps|bps_rd|bps_wr|iops|iops_rd|iops_wr|size)=(.+)$/) {
802 my ($k, $v) = ($1, $2);
804 $k = 'file' if $k eq 'volume';
806 return undef if defined $res->{$k};
810 if (!$res->{file
} && $p !~ m/=/) {
818 return undef if !$res->{file
};
820 return undef if $res->{cache
} &&
821 $res->{cache
} !~ m/^(off|none|writethrough|writeback|unsafe|directsync)$/;
822 return undef if $res->{snapshot
} && $res->{snapshot
} !~ m/^(on|off)$/;
823 return undef if $res->{cyls
} && $res->{cyls
} !~ m/^\d+$/;
824 return undef if $res->{heads
} && $res->{heads
} !~ m/^\d+$/;
825 return undef if $res->{secs
} && $res->{secs
} !~ m/^\d+$/;
826 return undef if $res->{media
} && $res->{media
} !~ m/^(disk|cdrom)$/;
827 return undef if $res->{trans
} && $res->{trans
} !~ m/^(none|lba|auto)$/;
828 return undef if $res->{format
} && $res->{format
} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/;
829 return undef if $res->{rerror
} && $res->{rerror
} !~ m/^(ignore|report|stop)$/;
830 return undef if $res->{werror
} && $res->{werror
} !~ m/^(enospc|ignore|report|stop)$/;
831 return undef if $res->{backup
} && $res->{backup
} !~ m/^(yes|no)$/;
832 return undef if $res->{aio
} && $res->{aio
} !~ m/^(native|threads)$/;
834 return undef if $res->{bps_rd
} && $res->{bps
};
835 return undef if $res->{bps_wr
} && $res->{bps
};
836 return undef if $res->{iops_rd
} && $res->{iops
};
837 return undef if $res->{iops_wr
} && $res->{iops
};
839 return undef if $res->{bps
} && $res->{bps
} !~ m/^\d+$/;
840 return undef if $res->{bps_rd
} && $res->{bps_rd
} !~ m/^\d+$/;
841 return undef if $res->{bps_wr
} && $res->{bps_wr
} !~ m/^\d+$/;
842 return undef if $res->{iops
} && $res->{iops
} !~ m/^\d+$/;
843 return undef if $res->{iops_rd
} && $res->{iops_rd
} !~ m/^\d+$/;
844 return undef if $res->{iops_wr
} && $res->{iops_wr
} !~ m/^\d+$/;
848 return undef if $res->{size
} !~ m/^([1-9]\d*(\.\d+)?)([KMG])?$/;
849 my ($size, $unit) = ($1, $3);
852 $size = $size * 1024;
853 } elsif ($unit eq 'M') {
854 $size = $size * 1024 * 1024;
855 } elsif ($unit eq 'G') {
856 $size = $size * 1024 * 1024 * 1024;
859 $res->{size
} = int($size);
862 if ($res->{media
} && ($res->{media
} eq 'cdrom')) {
863 return undef if $res->{snapshot
} || $res->{trans
} || $res->{format
};
864 return undef if $res->{heads
} || $res->{secs
} || $res->{cyls
};
865 return undef if $res->{interface
} eq 'virtio';
868 # rerror does not work with scsi drives
869 if ($res->{rerror
}) {
870 return undef if $res->{interface
} eq 'scsi';
876 my @qemu_drive_options = qw(heads secs cyls trans media format cache snapshot rerror werror aio bps bps_rd bps_wr iops iops_rd iops_wr);
878 my $format_size = sub {
883 my $kb = int($size/1024);
884 return $size if $kb*1024 != $size;
886 my $mb = int($kb/1024);
887 return "${kb}K" if $mb*1024 != $kb;
889 my $gb = int($mb/1024);
890 return "${mb}M" if $gb*1024 != $mb;
896 my ($vmid, $drive) = @_;
899 foreach my $o (@qemu_drive_options, 'backup') {
900 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
903 if ($drive->{size
}) {
904 $opts .= ",size=" . &$format_size($drive->{size
});
907 return "$drive->{file}$opts";
911 my($fh, $noerr) = @_;
914 my $SG_GET_VERSION_NUM = 0x2282;
916 my $versionbuf = "\x00" x
8;
917 my $ret = ioctl($fh, $SG_GET_VERSION_NUM, $versionbuf);
919 die "scsi ioctl SG_GET_VERSION_NUM failoed - $!\n" if !$noerr;
922 my $version = unpack("I", $versionbuf);
923 if ($version < 30000) {
924 die "scsi generic interface too old\n" if !$noerr;
928 my $buf = "\x00" x
36;
929 my $sensebuf = "\x00" x
8;
930 my $cmd = pack("C x3 C x11", 0x12, 36);
932 # see /usr/include/scsi/sg.h
933 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";
935 my $packet = pack($sg_io_hdr_t, ord('S'), -3, length($cmd),
936 length($sensebuf), 0, length($buf), $buf,
937 $cmd, $sensebuf, 6000);
939 $ret = ioctl($fh, $SG_IO, $packet);
941 die "scsi ioctl SG_IO failed - $!\n" if !$noerr;
945 my @res = unpack($sg_io_hdr_t, $packet);
946 if ($res[17] || $res[18]) {
947 die "scsi ioctl SG_IO status error - $!\n" if !$noerr;
952 ($res->{device
}, $res->{removable
}, $res->{venodor
},
953 $res->{product
}, $res->{revision
}) = unpack("C C x6 A8 A16 A4", $buf);
961 my $fh = IO
::File-
>new("+<$path") || return undef;
962 my $res = scsi_inquiry
($fh, 1);
968 sub print_drivedevice_full
{
969 my ($storecfg, $conf, $vmid, $drive, $bridges) = @_;
974 if ($drive->{interface
} eq 'virtio') {
975 my $pciaddr = print_pci_addr
("$drive->{interface}$drive->{index}", $bridges);
976 $device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
977 } elsif ($drive->{interface
} eq 'scsi') {
978 $maxdev = ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi') ?
256 : 7;
979 my $controller = int($drive->{index} / $maxdev);
980 my $unit = $drive->{index} % $maxdev;
981 my $devicetype = 'hd';
983 if (drive_is_cdrom
($drive)) {
986 if ($drive->{file
} =~ m
|^/|) {
987 $path = $drive->{file
};
989 $path = PVE
::Storage
::path
($storecfg, $drive->{file
});
991 $devicetype = 'block' if path_is_scsi
($path);
994 if (!$conf->{scsihw
} || $conf->{scsihw
} eq 'lsi'){
995 $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';
997 $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}";
1000 } elsif ($drive->{interface
} eq 'ide'){
1002 my $controller = int($drive->{index} / $maxdev);
1003 my $unit = $drive->{index} % $maxdev;
1004 my $devicetype = ($drive->{media
} && $drive->{media
} eq 'cdrom') ?
"cd" : "hd";
1006 $device = "ide-$devicetype,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1007 } elsif ($drive->{interface
} eq 'sata'){
1008 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
1009 my $unit = $drive->{index} % $MAX_SATA_DISKS;
1010 $device = "ide-drive,bus=ahci$controller.$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
1011 } elsif ($drive->{interface
} eq 'usb') {
1013 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
1015 die "unsupported interface type";
1018 $device .= ",bootindex=$drive->{bootindex}" if $drive->{bootindex
};
1023 sub print_drive_full
{
1024 my ($storecfg, $vmid, $drive) = @_;
1027 foreach my $o (@qemu_drive_options) {
1028 next if $o eq 'bootindex';
1029 $opts .= ",$o=$drive->{$o}" if $drive->{$o};
1032 # use linux-aio by default (qemu default is threads)
1033 $opts .= ",aio=native" if !$drive->{aio
};
1036 my $volid = $drive->{file
};
1037 if (drive_is_cdrom
($drive)) {
1038 $path = get_iso_path
($storecfg, $vmid, $volid);
1040 if ($volid =~ m
|^/|) {
1043 $path = PVE
::Storage
::path
($storecfg, $volid);
1045 if (!$drive->{cache
} && ($path =~ m
|^/dev/| || $path =~ m
|\
.raw
$|)) {
1046 $opts .= ",cache=none";
1050 my $pathinfo = $path ?
"file=$path," : '';
1052 return "${pathinfo}if=none,id=drive-$drive->{interface}$drive->{index}$opts";
1055 sub print_netdevice_full
{
1056 my ($vmid, $conf, $net, $netid, $bridges) = @_;
1058 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
1060 my $device = $net->{model
};
1061 if ($net->{model
} eq 'virtio') {
1062 $device = 'virtio-net-pci';
1065 # qemu > 0.15 always try to boot from network - we disable that by
1066 # not loading the pxe rom file
1067 my $extra = ($bootorder !~ m/n/) ?
"romfile=," : '';
1068 my $pciaddr = print_pci_addr
("$netid", $bridges);
1069 my $tmpstr = "$device,${extra}mac=$net->{macaddr},netdev=$netid$pciaddr,id=$netid";
1070 $tmpstr .= ",bootindex=$net->{bootindex}" if $net->{bootindex
} ;
1074 sub print_netdev_full
{
1075 my ($vmid, $conf, $net, $netid) = @_;
1078 if ($netid =~ m/^net(\d+)$/) {
1082 die "got strange net id '$i'\n" if $i >= ${MAX_NETS
};
1084 my $ifname = "tap${vmid}i$i";
1086 # kvm uses TUNSETIFF ioctl, and that limits ifname length
1087 die "interface name '$ifname' is too long (max 15 character)\n"
1088 if length($ifname) >= 16;
1090 my $vhostparam = '';
1091 $vhostparam = ',vhost=on' if $kernel_has_vhost_net && $net->{model
} eq 'virtio';
1093 my $vmname = $conf->{name
} || "vm$vmid";
1095 if ($net->{bridge
}) {
1096 return "type=tap,id=$netid,ifname=${ifname},script=/var/lib/qemu-server/pve-bridge$vhostparam";
1098 return "type=user,id=$netid,hostname=$vmname";
1102 sub drive_is_cdrom
{
1105 return $drive && $drive->{media
} && ($drive->{media
} eq 'cdrom');
1112 return undef if !$value;
1116 if ($value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/) {
1117 $res->{pciid
} = $value;
1125 # netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
1131 foreach my $kvp (split(/,/, $data)) {
1133 if ($kvp =~ m/^(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i) {
1135 my $mac = uc($3) || PVE
::Tools
::random_ether_addr
();
1136 $res->{model
} = $model;
1137 $res->{macaddr
} = $mac;
1138 } elsif ($kvp =~ m/^bridge=(\S+)$/) {
1139 $res->{bridge
} = $1;
1140 } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
1142 } elsif ($kvp =~ m/^tag=(\d+)$/) {
1150 return undef if !$res->{model
};
1158 my $res = "$net->{model}";
1159 $res .= "=$net->{macaddr}" if $net->{macaddr
};
1160 $res .= ",bridge=$net->{bridge}" if $net->{bridge
};
1161 $res .= ",rate=$net->{rate}" if $net->{rate
};
1162 $res .= ",tag=$net->{tag}" if $net->{tag
};
1167 sub add_random_macs
{
1168 my ($settings) = @_;
1170 foreach my $opt (keys %$settings) {
1171 next if $opt !~ m/^net(\d+)$/;
1172 my $net = parse_net
($settings->{$opt});
1174 $settings->{$opt} = print_net
($net);
1178 sub add_unused_volume
{
1179 my ($config, $volid) = @_;
1182 for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
1183 my $test = "unused$ind";
1184 if (my $vid = $config->{$test}) {
1185 return if $vid eq $volid; # do not add duplicates
1191 die "To many unused volume - please delete them first.\n" if !$key;
1193 $config->{$key} = $volid;
1198 # fixme: remove all thos $noerr parameters?
1200 PVE
::JSONSchema
::register_format
('pve-qm-bootdisk', \
&verify_bootdisk
);
1201 sub verify_bootdisk
{
1202 my ($value, $noerr) = @_;
1204 return $value if valid_drivename
($value);
1206 return undef if $noerr;
1208 die "invalid boot disk '$value'\n";
1211 PVE
::JSONSchema
::register_format
('pve-qm-net', \
&verify_net
);
1213 my ($value, $noerr) = @_;
1215 return $value if parse_net
($value);
1217 return undef if $noerr;
1219 die "unable to parse network options\n";
1222 PVE
::JSONSchema
::register_format
('pve-qm-drive', \
&verify_drive
);
1224 my ($value, $noerr) = @_;
1226 return $value if parse_drive
(undef, $value);
1228 return undef if $noerr;
1230 die "unable to parse drive options\n";
1233 PVE
::JSONSchema
::register_format
('pve-qm-hostpci', \
&verify_hostpci
);
1234 sub verify_hostpci
{
1235 my ($value, $noerr) = @_;
1237 return $value if parse_hostpci
($value);
1239 return undef if $noerr;
1241 die "unable to parse pci id\n";
1244 PVE
::JSONSchema
::register_format
('pve-qm-watchdog', \
&verify_watchdog
);
1245 sub verify_watchdog
{
1246 my ($value, $noerr) = @_;
1248 return $value if parse_watchdog
($value);
1250 return undef if $noerr;
1252 die "unable to parse watchdog options\n";
1255 sub parse_watchdog
{
1258 return undef if !$value;
1262 foreach my $p (split(/,/, $value)) {
1263 next if $p =~ m/^\s*$/;
1265 if ($p =~ m/^(model=)?(i6300esb|ib700)$/) {
1267 } elsif ($p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/) {
1268 $res->{action
} = $2;
1277 PVE
::JSONSchema
::register_format
('pve-qm-startup', \
&verify_startup
);
1278 sub verify_startup
{
1279 my ($value, $noerr) = @_;
1281 return $value if parse_startup
($value);
1283 return undef if $noerr;
1285 die "unable to parse startup options\n";
1291 return undef if !$value;
1295 foreach my $p (split(/,/, $value)) {
1296 next if $p =~ m/^\s*$/;
1298 if ($p =~ m/^(order=)?(\d+)$/) {
1300 } elsif ($p =~ m/^up=(\d+)$/) {
1302 } elsif ($p =~ m/^down=(\d+)$/) {
1312 sub parse_usb_device
{
1315 return undef if !$value;
1317 my @dl = split(/,/, $value);
1321 foreach my $v (@dl) {
1322 if ($v =~ m/^host=(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
1324 $res->{vendorid
} = $2;
1325 $res->{productid
} = $4;
1326 } elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
1328 $res->{hostbus
} = $1;
1329 $res->{hostport
} = $2;
1334 return undef if !$found;
1339 PVE
::JSONSchema
::register_format
('pve-qm-usb-device', \
&verify_usb_device
);
1340 sub verify_usb_device
{
1341 my ($value, $noerr) = @_;
1343 return $value if parse_usb_device
($value);
1345 return undef if $noerr;
1347 die "unable to parse usb device\n";
1350 # add JSON properties for create and set function
1351 sub json_config_properties
{
1354 foreach my $opt (keys %$confdesc) {
1355 $prop->{$opt} = $confdesc->{$opt};
1362 my ($key, $value) = @_;
1364 die "unknown setting '$key'\n" if !$confdesc->{$key};
1366 my $type = $confdesc->{$key}->{type
};
1368 if (!defined($value)) {
1369 die "got undefined value\n";
1372 if ($value =~ m/[\n\r]/) {
1373 die "property contains a line feed\n";
1376 if ($type eq 'boolean') {
1377 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
1378 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
1379 die "type check ('boolean') failed - got '$value'\n";
1380 } elsif ($type eq 'integer') {
1381 return int($1) if $value =~ m/^(\d+)$/;
1382 die "type check ('integer') failed - got '$value'\n";
1383 } elsif ($type eq 'string') {
1384 if (my $fmt = $confdesc->{$key}->{format
}) {
1385 if ($fmt eq 'pve-qm-drive') {
1386 # special case - we need to pass $key to parse_drive()
1387 my $drive = parse_drive
($key, $value);
1388 return $value if $drive;
1389 die "unable to parse drive options\n";
1391 PVE
::JSONSchema
::check_format
($fmt, $value);
1394 $value =~ s/^\"(.*)\"$/$1/;
1397 die "internal error"
1401 sub lock_config_full
{
1402 my ($vmid, $timeout, $code, @param) = @_;
1404 my $filename = config_file_lock
($vmid);
1406 my $res = lock_file
($filename, $timeout, $code, @param);
1414 my ($vmid, $code, @param) = @_;
1416 return lock_config_full
($vmid, 10, $code, @param);
1419 sub cfs_config_path
{
1420 my ($vmid, $node) = @_;
1422 $node = $nodename if !$node;
1423 return "nodes/$node/qemu-server/$vmid.conf";
1426 sub check_iommu_support
{
1427 #fixme : need to check IOMMU support
1428 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1436 my ($vmid, $node) = @_;
1438 my $cfspath = cfs_config_path
($vmid, $node);
1439 return "/etc/pve/$cfspath";
1442 sub config_file_lock
{
1445 return "$lock_dir/lock-$vmid.conf";
1451 my $conf = config_file
($vmid);
1452 utime undef, undef, $conf;
1456 my ($storecfg, $vmid, $keep_empty_config) = @_;
1458 my $conffile = config_file
($vmid);
1460 my $conf = load_config
($vmid);
1464 # only remove disks owned by this VM
1465 foreach_drive
($conf, sub {
1466 my ($ds, $drive) = @_;
1468 return if drive_is_cdrom
($drive);
1470 my $volid = $drive->{file
};
1471 return if !$volid || $volid =~ m
|^/|;
1473 my ($path, $owner) = PVE
::Storage
::path
($storecfg, $volid);
1474 return if !$path || !$owner || ($owner != $vmid);
1476 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1479 if ($keep_empty_config) {
1480 PVE
::Tools
::file_set_contents
($conffile, "memory: 128\n");
1485 # also remove unused disk
1487 my $dl = PVE
::Storage
::vdisk_list
($storecfg, undef, $vmid);
1490 PVE
::Storage
::foreach_volid
($dl, sub {
1491 my ($volid, $sid, $volname, $d) = @_;
1492 PVE
::Storage
::vdisk_free
($storecfg, $volid);
1502 my ($vmid, $node) = @_;
1504 my $cfspath = cfs_config_path
($vmid, $node);
1506 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath);
1508 die "no such VM ('$vmid')\n" if !defined($conf);
1513 sub parse_vm_config
{
1514 my ($filename, $raw) = @_;
1516 return undef if !defined($raw);
1519 digest
=> Digest
::SHA
::sha1_hex
($raw),
1522 $filename =~ m
|/qemu-server/(\d
+)\
.conf
$|
1523 || die "got strange filename '$filename'";
1529 while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
1532 next if $line =~ m/^\s*$/;
1534 if ($line =~ m/^\#(.*)\s*$/) {
1535 $descr .= PVE
::Tools
::decode_text
($1) . "\n";
1539 if ($line =~ m/^(description):\s*(.*\S)\s*$/) {
1540 $descr .= PVE
::Tools
::decode_text
($2);
1541 } elsif ($line =~ m/^(args):\s*(.*\S)\s*$/) {
1544 $res->{$key} = $value;
1545 } elsif ($line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/) {
1548 eval { $value = check_type
($key, $value); };
1550 warn "vm $vmid - unable to parse value of '$key' - $@";
1552 my $fmt = $confdesc->{$key}->{format
};
1553 if ($fmt && $fmt eq 'pve-qm-drive') {
1554 my $v = parse_drive
($key, $value);
1555 if (my $volid = filename_to_volume_id
($vmid, $v->{file
}, $v->{media
})) {
1556 $v->{file
} = $volid;
1557 $value = print_drive
($vmid, $v);
1559 warn "vm $vmid - unable to parse value of '$key'\n";
1564 if ($key eq 'cdrom') {
1565 $res->{ide2
} = $value;
1567 $res->{$key} = $value;
1573 $res->{description
} = $descr if $descr;
1575 # convert old smp to sockets
1576 if ($res->{smp
} && !$res->{sockets
}) {
1577 $res->{sockets
} = $res->{smp
};
1584 sub write_vm_config
{
1585 my ($filename, $conf) = @_;
1587 if ($conf->{cdrom
}) {
1588 die "option ide2 conflicts with cdrom\n" if $conf->{ide2
};
1589 $conf->{ide2
} = $conf->{cdrom
};
1590 delete $conf->{cdrom
};
1593 # we do not use 'smp' any longer
1594 if ($conf->{sockets
}) {
1595 delete $conf->{smp
};
1596 } elsif ($conf->{smp
}) {
1597 $conf->{sockets
} = $conf->{smp
};
1598 delete $conf->{cores
};
1599 delete $conf->{smp
};
1602 my $new_volids = {};
1603 foreach my $key (keys %$conf) {
1604 next if $key eq 'digest' || $key eq 'description';
1605 my $value = $conf->{$key};
1606 eval { $value = check_type
($key, $value); };
1607 die "unable to parse value of '$key' - $@" if $@;
1609 $conf->{$key} = $value;
1611 if (valid_drivename
($key)) {
1612 my $drive = PVE
::QemuServer
::parse_drive
($key, $value);
1613 $new_volids->{$drive->{file
}} = 1 if $drive && $drive->{file
};
1617 # remove 'unusedX' settings if we re-add a volume
1618 foreach my $key (keys %$conf) {
1619 my $value = $conf->{$key};
1620 if ($key =~ m/^unused/ && $new_volids->{$value}) {
1621 delete $conf->{$key};
1628 # add description as comment to top of file
1629 my $descr = $conf->{description
} || '';
1630 foreach my $cl (split(/\n/, $descr)) {
1631 $raw .= '#' . PVE
::Tools
::encode_text
($cl) . "\n";
1634 foreach my $key (sort keys %$conf) {
1635 next if $key eq 'digest' || $key eq 'description';
1636 $raw .= "$key: $conf->{$key}\n";
1642 sub update_config_nolock
{
1643 my ($vmid, $conf, $skiplock) = @_;
1645 check_lock
($conf) if !$skiplock;
1647 my $cfspath = cfs_config_path
($vmid);
1649 PVE
::Cluster
::cfs_write_file
($cfspath, $conf);
1653 my ($vmid, $conf, $skiplock) = @_;
1655 lock_config
($vmid, &update_config_nolock
, $conf, $skiplock);
1662 # we use static defaults from our JSON schema configuration
1663 foreach my $key (keys %$confdesc) {
1664 if (defined(my $default = $confdesc->{$key}->{default})) {
1665 $res->{$key} = $default;
1669 my $conf = PVE
::Cluster
::cfs_read_file
('datacenter.cfg');
1670 $res->{keyboard
} = $conf->{keyboard
} if $conf->{keyboard
};
1676 my $vmlist = PVE
::Cluster
::get_vmlist
();
1678 return $res if !$vmlist || !$vmlist->{ids
};
1679 my $ids = $vmlist->{ids
};
1681 foreach my $vmid (keys %$ids) {
1682 my $d = $ids->{$vmid};
1683 next if !$d->{node
} || $d->{node
} ne $nodename;
1684 next if !$d->{type
} || $d->{type
} ne 'qemu';
1685 $res->{$vmid}->{exists} = 1;
1690 # test if VM uses local resources (to prevent migration)
1691 sub check_local_resources
{
1692 my ($conf, $noerr) = @_;
1696 $loc_res = 1 if $conf->{hostusb
}; # old syntax
1697 $loc_res = 1 if $conf->{hostpci
}; # old syntax
1699 foreach my $k (keys %$conf) {
1700 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
1703 die "VM uses local resources\n" if $loc_res && !$noerr;
1708 # check is used storages are available on all nodes (use by migrate)
1709 sub check_storage_availability
{
1710 my ($storecfg, $conf, $node) = @_;
1712 foreach_drive
($conf, sub {
1713 my ($ds, $drive) = @_;
1715 my $volid = $drive->{file
};
1718 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($volid, 1);
1721 # check if storage is available on both nodes
1722 my $scfg = PVE
::Storage
::storage_check_node
($storecfg, $sid);
1723 PVE
::Storage
::storage_check_node
($storecfg, $sid, $node);
1730 die "VM is locked ($conf->{lock})\n" if $conf->{lock};
1734 my ($pidfile, $pid) = @_;
1736 my $fh = IO
::File-
>new("/proc/$pid/cmdline", "r");
1740 return undef if !$line;
1741 my @param = split(/\0/, $line);
1743 my $cmd = $param[0];
1744 return if !$cmd || ($cmd !~ m
|kvm
$|);
1746 for (my $i = 0; $i < scalar (@param); $i++) {
1749 if (($p eq '-pidfile') || ($p eq '--pidfile')) {
1750 my $p = $param[$i+1];
1751 return 1 if $p && ($p eq $pidfile);
1760 my ($vmid, $nocheck, $node) = @_;
1762 my $filename = config_file
($vmid, $node);
1764 die "unable to find configuration file for VM $vmid - no such machine\n"
1765 if !$nocheck && ! -f
$filename;
1767 my $pidfile = pidfile_name
($vmid);
1769 if (my $fd = IO
::File-
>new("<$pidfile")) {
1774 my $mtime = $st->mtime;
1775 if ($mtime > time()) {
1776 warn "file '$filename' modified in future\n";
1779 if ($line =~ m/^(\d+)$/) {
1781 if (check_cmdline
($pidfile, $pid)) {
1782 if (my $pinfo = PVE
::ProcFSTools
::check_process_running
($pid)) {
1794 my $vzlist = config_list
();
1796 my $fd = IO
::Dir-
>new($var_run_tmpdir) || return $vzlist;
1798 while (defined(my $de = $fd->read)) {
1799 next if $de !~ m/^(\d+)\.pid$/;
1801 next if !defined($vzlist->{$vmid});
1802 if (my $pid = check_running
($vmid)) {
1803 $vzlist->{$vmid}->{pid
} = $pid;
1811 my ($storecfg, $conf) = @_;
1813 my $bootdisk = $conf->{bootdisk
};
1814 return undef if !$bootdisk;
1815 return undef if !valid_drivename
($bootdisk);
1817 return undef if !$conf->{$bootdisk};
1819 my $drive = parse_drive
($bootdisk, $conf->{$bootdisk});
1820 return undef if !defined($drive);
1822 return undef if drive_is_cdrom
($drive);
1824 my $volid = $drive->{file
};
1825 return undef if !$volid;
1827 return $drive->{size
};
1830 my $last_proc_pid_stat;
1832 # get VM status information
1833 # This must be fast and should not block ($full == false)
1834 # We only query KVM using QMP if $full == true (this can be slow)
1836 my ($opt_vmid, $full) = @_;
1840 my $storecfg = PVE
::Storage
::config
();
1842 my $list = vzlist
();
1843 my ($uptime) = PVE
::ProcFSTools
::read_proc_uptime
(1);
1845 my $cpucount = $cpuinfo->{cpus
} || 1;
1847 foreach my $vmid (keys %$list) {
1848 next if $opt_vmid && ($vmid ne $opt_vmid);
1850 my $cfspath = cfs_config_path
($vmid);
1851 my $conf = PVE
::Cluster
::cfs_read_file
($cfspath) || {};
1854 $d->{pid
} = $list->{$vmid}->{pid
};
1856 # fixme: better status?
1857 $d->{status
} = $list->{$vmid}->{pid
} ?
'running' : 'stopped';
1859 my $size = disksize
($storecfg, $conf);
1860 if (defined($size)) {
1861 $d->{disk
} = 0; # no info available
1862 $d->{maxdisk
} = $size;
1868 $d->{cpus
} = ($conf->{sockets
} || 1) * ($conf->{cores
} || 1);
1869 $d->{cpus
} = $cpucount if $d->{cpus
} > $cpucount;
1871 $d->{name
} = $conf->{name
} || "VM $vmid";
1872 $d->{maxmem
} = $conf->{memory
} ?
$conf->{memory
}*(1024*1024) : 0;
1882 $d->{diskwrite
} = 0;
1887 my $netdev = PVE
::ProcFSTools
::read_proc_net_dev
();
1888 foreach my $dev (keys %$netdev) {
1889 next if $dev !~ m/^tap([1-9]\d*)i/;
1891 my $d = $res->{$vmid};
1894 $d->{netout
} += $netdev->{$dev}->{receive
};
1895 $d->{netin
} += $netdev->{$dev}->{transmit
};
1898 my $ctime = gettimeofday
;
1900 foreach my $vmid (keys %$list) {
1902 my $d = $res->{$vmid};
1903 my $pid = $d->{pid
};
1906 my $pstat = PVE
::ProcFSTools
::read_proc_pid_stat
($pid);
1907 next if !$pstat; # not running
1909 my $used = $pstat->{utime} + $pstat->{stime
};
1911 $d->{uptime
} = int(($uptime - $pstat->{starttime
})/$cpuinfo->{user_hz
});
1913 if ($pstat->{vsize
}) {
1914 $d->{mem
} = int(($pstat->{rss
}/$pstat->{vsize
})*$d->{maxmem
});
1917 my $old = $last_proc_pid_stat->{$pid};
1919 $last_proc_pid_stat->{$pid} = {
1927 my $dtime = ($ctime - $old->{time}) * $cpucount * $cpuinfo->{user_hz
};
1929 if ($dtime > 1000) {
1930 my $dutime = $used - $old->{used
};
1932 $d->{cpu
} = (($dutime/$dtime)* $cpucount) / $d->{cpus
};
1933 $last_proc_pid_stat->{$pid} = {
1939 $d->{cpu
} = $old->{cpu
};
1943 return $res if !$full;
1945 my $qmpclient = PVE
::QMPClient-
>new();
1947 my $blockstatscb = sub {
1948 my ($vmid, $resp) = @_;
1949 my $data = $resp->{'return'} || [];
1950 my $totalrdbytes = 0;
1951 my $totalwrbytes = 0;
1952 for my $blockstat (@$data) {
1953 $totalrdbytes = $totalrdbytes + $blockstat->{stats
}->{rd_bytes
};
1954 $totalwrbytes = $totalwrbytes + $blockstat->{stats
}->{wr_bytes
};
1956 $res->{$vmid}->{diskread
} = $totalrdbytes;
1957 $res->{$vmid}->{diskwrite
} = $totalwrbytes;
1960 my $statuscb = sub {
1961 my ($vmid, $resp) = @_;
1962 $qmpclient->queue_cmd($vmid, $blockstatscb, 'query-blockstats');
1964 my $status = 'unknown';
1965 if (!defined($status = $resp->{'return'}->{status
})) {
1966 warn "unable to get VM status\n";
1970 $res->{$vmid}->{qmpstatus
} = $resp->{'return'}->{status
};
1973 foreach my $vmid (keys %$list) {
1974 next if $opt_vmid && ($vmid ne $opt_vmid);
1975 next if !$res->{$vmid}->{pid
}; # not running
1976 $qmpclient->queue_cmd($vmid, $statuscb, 'query-status');
1979 $qmpclient->queue_execute();
1981 foreach my $vmid (keys %$list) {
1982 next if $opt_vmid && ($vmid ne $opt_vmid);
1983 $res->{$vmid}->{qmpstatus
} = $res->{$vmid}->{status
} if !$res->{$vmid}->{qmpstatus
};
1990 my ($conf, $func) = @_;
1992 foreach my $ds (keys %$conf) {
1993 next if !valid_drivename
($ds);
1995 my $drive = parse_drive
($ds, $conf->{$ds});
1998 &$func($ds, $drive);
2002 sub config_to_command
{
2003 my ($storecfg, $vmid, $conf, $defaults, $migrate_uri) = @_;
2009 my $kvmver = kvm_user_version
();
2010 my $vernum = 0; # unknown
2011 if ($kvmver =~ m/^(\d+)\.(\d+)$/) {
2012 $vernum = $1*1000000+$2*1000;
2013 } elsif ($kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
2014 $vernum = $1*1000000+$2*1000+$3;
2017 die "detected old qemu-kvm binary ($kvmver)\n" if $vernum < 15000;
2019 my $have_ovz = -f
'/proc/vz/vestat';
2021 push @$cmd, '/usr/bin/kvm';
2023 push @$cmd, '-id', $vmid;
2027 my $qmpsocket = qmp_socket
($vmid);
2028 push @$cmd, '-chardev', "socket,id=qmp,path=$qmpsocket,server,nowait";
2029 push @$cmd, '-mon', "chardev=qmp,mode=control";
2031 my $socket = vnc_socket
($vmid);
2032 push @$cmd, '-vnc', "unix:$socket,x509,password";
2034 push @$cmd, '-pidfile' , pidfile_name
($vmid);
2036 push @$cmd, '-daemonize';
2038 push @$cmd, '-incoming', $migrate_uri if $migrate_uri;
2041 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2042 next if !$conf->{"usb$i"};
2045 # include usb device config
2046 push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
2048 # enable absolute mouse coordinates (needed by vnc)
2049 my $tablet = defined($conf->{tablet
}) ?
$conf->{tablet
} : $defaults->{tablet
};
2052 push @$devices, '-device', 'usb-tablet,bus=ehci.0,port=6';
2054 push @$devices, '-usbdevice', 'tablet';
2059 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2060 my $d = parse_hostpci
($conf->{"hostpci$i"});
2062 $pciaddr = print_pci_addr
("hostpci$i", $bridges);
2063 push @$devices, '-device', "pci-assign,host=$d->{pciid},id=hostpci$i$pciaddr";
2067 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++) {
2068 my $d = parse_usb_device
($conf->{"usb$i"});
2070 if ($d->{vendorid
} && $d->{productid
}) {
2071 push @$devices, '-device', "usb-host,vendorid=0x$d->{vendorid},productid=0x$d->{productid}";
2072 } elsif (defined($d->{hostbus
}) && defined($d->{hostport
})) {
2073 push @$devices, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
2078 for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++) {
2079 if (my $path = $conf->{"serial$i"}) {
2080 die "no such serial device\n" if ! -c
$path;
2081 push @$devices, '-chardev', "tty,id=serial$i,path=$path";
2082 push @$devices, '-device', "isa-serial,chardev=serial$i";
2087 for (my $i = 0; $i < $MAX_PARALLEL_PORTS; $i++) {
2088 if (my $path = $conf->{"parallel$i"}) {
2089 die "no such parallel device\n" if ! -c
$path;
2090 push @$devices, '-chardev', "parport,id=parallel$i,path=$path";
2091 push @$devices, '-device', "isa-parallel,chardev=parallel$i";
2095 my $vmname = $conf->{name
} || "vm$vmid";
2097 push @$cmd, '-name', $vmname;
2100 $sockets = $conf->{smp
} if $conf->{smp
}; # old style - no longer iused
2101 $sockets = $conf->{sockets
} if $conf->{sockets
};
2103 my $cores = $conf->{cores
} || 1;
2105 push @$cmd, '-smp', "sockets=$sockets,cores=$cores";
2107 push @$cmd, '-cpu', $conf->{cpu
} if $conf->{cpu
};
2109 push @$cmd, '-nodefaults';
2111 my $bootorder = $conf->{boot
} || $confdesc->{boot
}->{default};
2113 my $bootindex_hash = {};
2115 foreach my $o (split(//, $bootorder)) {
2116 $bootindex_hash->{$o} = $i*100;
2120 push @$cmd, '-boot', "menu=on";
2122 push @$cmd, '-no-acpi' if defined($conf->{acpi
}) && $conf->{acpi
} == 0;
2124 push @$cmd, '-no-reboot' if defined($conf->{reboot
}) && $conf->{reboot
} == 0;
2126 my $vga = $conf->{vga
};
2128 if ($conf->{ostype
} && ($conf->{ostype
} eq 'win7' || $conf->{ostype
} eq 'w2k8')) {
2135 push @$cmd, '-vga', $vga if $vga; # for kvm 77 and later
2138 my $tdf = defined($conf->{tdf
}) ?
$conf->{tdf
} : $defaults->{tdf
};
2139 # ignore - no longer supported by newer kvm
2140 # push @$cmd, '-tdf' if $tdf;
2142 my $nokvm = defined($conf->{kvm
}) && $conf->{kvm
} == 0 ?
1 : 0;
2144 if (my $ost = $conf->{ostype
}) {
2145 # other, wxp, w2k, w2k3, w2k8, wvista, win7, l24, l26
2147 if ($ost =~ m/^w/) { # windows
2148 push @$cmd, '-localtime' if !defined($conf->{localtime});
2150 # use rtc-td-hack when acpi is enabled
2151 if (!(defined($conf->{acpi
}) && $conf->{acpi
} == 0)) {
2152 push @$cmd, '-rtc-td-hack';
2156 if ($ost eq 'win7' || $ost eq 'w2k8' || $ost eq 'wvista') {
2157 push @$cmd, '-no-kvm-pit-reinjection';
2158 push @$cmd, '-no-hpet';
2168 push @$cmd, '-no-kvm';
2170 die "No accelerator found!\n" if !$cpuinfo->{hvm
};
2173 push @$cmd, '-localtime' if $conf->{localtime};
2175 push @$cmd, '-startdate', $conf->{startdate
} if $conf->{startdate
};
2177 push @$cmd, '-S' if $conf->{freeze
};
2179 # set keyboard layout
2180 my $kb = $conf->{keyboard
} || $defaults->{keyboard
};
2181 push @$cmd, '-k', $kb if $kb;
2184 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2185 #push @$cmd, '-soundhw', 'es1370';
2186 #push @$cmd, '-soundhw', $soundhw if $soundhw;
2187 $pciaddr = print_pci_addr
("balloon0", $bridges);
2188 push @$devices, '-device', "virtio-balloon-pci,id=balloon0$pciaddr" if $conf->{balloon
};
2190 if ($conf->{watchdog
}) {
2191 my $wdopts = parse_watchdog
($conf->{watchdog
});
2192 $pciaddr = print_pci_addr
("watchdog", $bridges);
2193 my $watchdog = $wdopts->{model
} || 'i6300esb';
2194 push @$devices, '-device', "$watchdog$pciaddr";
2195 push @$devices, '-watchdog-action', $wdopts->{action
} if $wdopts->{action
};
2199 my $scsicontroller = {};
2200 my $ahcicontroller = {};
2201 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : $defaults->{scsihw
};
2203 foreach_drive
($conf, sub {
2204 my ($ds, $drive) = @_;
2206 if (PVE
::Storage
::parse_volume_id
($drive->{file
}, 1)) {
2207 push @$vollist, $drive->{file
};
2210 $use_virtio = 1 if $ds =~ m/^virtio/;
2212 if (drive_is_cdrom
($drive)) {
2213 if ($bootindex_hash->{d
}) {
2214 $drive->{bootindex
} = $bootindex_hash->{d
};
2215 $bootindex_hash->{d
} += 1;
2218 if ($bootindex_hash->{c
}) {
2219 $drive->{bootindex
} = $bootindex_hash->{c
} if $conf->{bootdisk
} && ($conf->{bootdisk
} eq $ds);
2220 $bootindex_hash->{c
} += 1;
2224 if ($drive->{interface
} eq 'scsi') {
2226 my $maxdev = ($scsihw ne 'lsi') ?
256 : 7;
2227 my $controller = int($drive->{index} / $maxdev);
2228 $pciaddr = print_pci_addr
("scsihw$controller", $bridges);
2229 push @$devices, '-device', "$scsihw,id=scsihw$controller$pciaddr" if !$scsicontroller->{$controller};
2230 $scsicontroller->{$controller}=1;
2233 if ($drive->{interface
} eq 'sata') {
2234 my $controller = int($drive->{index} / $MAX_SATA_DISKS);
2235 $pciaddr = print_pci_addr
("ahci$controller", $bridges);
2236 push @$devices, '-device', "ahci,id=ahci$controller,multifunction=on$pciaddr" if !$ahcicontroller->{$controller};
2237 $ahcicontroller->{$controller}=1;
2240 push @$devices, '-drive',print_drive_full
($storecfg, $vmid, $drive);
2241 push @$devices, '-device',print_drivedevice_full
($storecfg, $conf, $vmid, $drive, $bridges);
2244 push @$cmd, '-m', $conf->{memory
} || $defaults->{memory
};
2246 for (my $i = 0; $i < $MAX_NETS; $i++) {
2247 next if !$conf->{"net$i"};
2248 my $d = parse_net
($conf->{"net$i"});
2251 $use_virtio = 1 if $d->{model
} eq 'virtio';
2253 if ($bootindex_hash->{n
}) {
2254 $d->{bootindex
} = $bootindex_hash->{n
};
2255 $bootindex_hash->{n
} += 1;
2258 my $netdevfull = print_netdev_full
($vmid,$conf,$d,"net$i");
2259 push @$devices, '-netdev', $netdevfull;
2261 my $netdevicefull = print_netdevice_full
($vmid,$conf,$d,"net$i",$bridges);
2262 push @$devices, '-device', $netdevicefull;
2266 while (my ($k, $v) = each %$bridges) {
2267 $pciaddr = print_pci_addr
("pci.$k");
2268 unshift @$devices, '-device', "pci-bridge,id=pci.$k,chassis_nr=$k$pciaddr" if $k > 0;
2272 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2273 # when the VM uses virtio devices.
2274 if (!$use_virtio && $have_ovz) {
2276 my $cpuunits = defined($conf->{cpuunits
}) ?
2277 $conf->{cpuunits
} : $defaults->{cpuunits
};
2279 push @$cmd, '-cpuunits', $cpuunits if $cpuunits;
2281 # fixme: cpulimit is currently ignored
2282 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2286 if ($conf->{args
}) {
2287 my $aa = PVE
::Tools
::split_args
($conf->{args
});
2291 push @$cmd, @$devices;
2292 return wantarray ?
($cmd, $vollist) : $cmd;
2297 return "${var_run_tmpdir}/$vmid.vnc";
2302 return "${var_run_tmpdir}/$vmid.qmp";
2307 return "${var_run_tmpdir}/$vmid.pid";
2310 sub next_migrate_port
{
2312 for (my $p = 60000; $p < 60010; $p++) {
2314 my $sock = IO
::Socket
::INET-
>new(Listen
=> 5,
2315 LocalAddr
=> 'localhost',
2326 die "unable to find free migration port";
2329 sub vm_devices_list
{
2332 my $res = vm_mon_cmd
($vmid, 'query-pci');
2335 foreach my $pcibus (@$res) {
2336 foreach my $device (@{$pcibus->{devices
}}) {
2337 next if !$device->{'qdev_id'};
2338 $devices->{$device->{'qdev_id'}} = $device;
2346 my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
2348 return 1 if !check_running
($vmid) || !$conf->{hotplug
};
2350 my $devices_list = vm_devices_list
($vmid);
2351 return 1 if defined($devices_list->{$deviceid});
2353 qemu_bridgeadd
($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
2355 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2356 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2357 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
2358 qemu_deviceadd
($vmid, $devicefull);
2359 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2360 qemu_drivedel
($vmid, $deviceid);
2365 if ($deviceid =~ m/^(scsihw)(\d+)$/) {
2366 my $scsihw = defined($conf->{scsihw
}) ?
$conf->{scsihw
} : "lsi";
2367 my $pciaddr = print_pci_addr
($deviceid);
2368 my $devicefull = "$scsihw,id=$deviceid$pciaddr";
2369 qemu_deviceadd
($vmid, $devicefull);
2370 return undef if(!qemu_deviceaddverify
($vmid, $deviceid));
2373 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2374 return 1 if ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi'); #virtio-scsi not yet support hotplug
2375 return undef if !qemu_findorcreatescsihw
($storecfg,$conf, $vmid, $device);
2376 return undef if !qemu_driveadd
($storecfg, $vmid, $device);
2377 my $devicefull = print_drivedevice_full
($storecfg, $conf, $vmid, $device);
2378 if(!qemu_deviceadd
($vmid, $devicefull)) {
2379 qemu_drivedel
($vmid, $deviceid);
2384 if ($deviceid =~ m/^(net)(\d+)$/) {
2385 return undef if !qemu_netdevadd
($vmid, $conf, $device, $deviceid);
2386 my $netdevicefull = print_netdevice_full
($vmid, $conf, $device, $deviceid);
2387 qemu_deviceadd
($vmid, $netdevicefull);
2388 if(!qemu_deviceaddverify
($vmid, $deviceid)) {
2389 qemu_netdevdel
($vmid, $deviceid);
2394 if ($deviceid =~ m/^(pci\.)(\d+)$/) {
2396 my $pciaddr = print_pci_addr
($deviceid);
2397 my $devicefull = "pci-bridge,id=pci.$bridgeid,chassis_nr=$bridgeid$pciaddr";
2398 qemu_deviceadd
($vmid, $devicefull);
2399 return undef if !qemu_deviceaddverify
($vmid, $deviceid);
2405 sub vm_deviceunplug
{
2406 my ($vmid, $conf, $deviceid) = @_;
2408 return 1 if !check_running
($vmid) || !$conf->{hotplug
};
2410 my $devices_list = vm_devices_list
($vmid);
2411 return 1 if !defined($devices_list->{$deviceid});
2413 die "can't unplug bootdisk" if $conf->{bootdisk
} && $conf->{bootdisk
} eq $deviceid;
2415 if ($deviceid =~ m/^(virtio)(\d+)$/) {
2416 return undef if !qemu_drivedel
($vmid, $deviceid);
2417 qemu_devicedel
($vmid, $deviceid);
2418 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2421 if ($deviceid =~ m/^(lsi)(\d+)$/) {
2422 return undef if !qemu_devicedel
($vmid, $deviceid);
2425 if ($deviceid =~ m/^(scsi)(\d+)$/) {
2426 return undef if !qemu_devicedel
($vmid, $deviceid);
2427 return undef if !qemu_drivedel
($vmid, $deviceid);
2430 if ($deviceid =~ m/^(net)(\d+)$/) {
2431 return undef if !qemu_netdevdel
($vmid, $deviceid);
2432 qemu_devicedel
($vmid, $deviceid);
2433 return undef if !qemu_devicedelverify
($vmid, $deviceid);
2439 sub qemu_deviceadd
{
2440 my ($vmid, $devicefull) = @_;
2442 my $ret = vm_human_monitor_command
($vmid, "device_add $devicefull");
2444 # Otherwise, if the command succeeds, no output is sent. So any non-empty string shows an error
2445 return 1 if $ret eq "";
2446 syslog
("err", "error on hotplug device : $ret");
2451 sub qemu_devicedel
{
2452 my($vmid, $deviceid) = @_;
2454 my $ret = vm_human_monitor_command
($vmid, "device_del $deviceid");
2456 return 1 if $ret eq "";
2457 syslog
("err", "detaching device $deviceid failed : $ret");
2462 my($storecfg, $vmid, $device) = @_;
2464 my $drive = print_drive_full
($storecfg, $vmid, $device);
2465 my $ret = vm_human_monitor_command
($vmid, "drive_add auto $drive");
2466 # If the command succeeds qemu prints: "OK"
2467 if ($ret !~ m/OK/s) {
2468 syslog
("err", "adding drive failed: $ret");
2475 my($vmid, $deviceid) = @_;
2477 my $ret = vm_human_monitor_command
($vmid, "drive_del drive-$deviceid");
2479 if ($ret =~ m/Device \'.*?\' not found/s) {
2480 # NB: device not found errors mean the drive was auto-deleted and we ignore the error
2482 elsif ($ret ne "") {
2483 syslog
("err", "deleting drive $deviceid failed : $ret");
2489 sub qemu_deviceaddverify
{
2490 my ($vmid,$deviceid) = @_;
2492 for (my $i = 0; $i <= 5; $i++) {
2493 my $devices_list = vm_devices_list
($vmid);
2494 return 1 if defined($devices_list->{$deviceid});
2497 syslog
("err", "error on hotplug device $deviceid");
2502 sub qemu_devicedelverify
{
2503 my ($vmid,$deviceid) = @_;
2505 #need to verify the device is correctly remove as device_del is async and empty return is not reliable
2506 for (my $i = 0; $i <= 5; $i++) {
2507 my $devices_list = vm_devices_list
($vmid);
2508 return 1 if !defined($devices_list->{$deviceid});
2511 syslog
("err", "error on hot-unplugging device $deviceid");
2515 sub qemu_findorcreatescsihw
{
2516 my ($storecfg, $conf, $vmid, $device) = @_;
2518 my $maxdev = ($conf->{scsihw
} && $conf->{scsihw
} ne 'lsi') ?
256 : 7;
2519 my $controller = int($device->{index} / $maxdev);
2520 my $scsihwid="scsihw$controller";
2521 my $devices_list = vm_devices_list
($vmid);
2523 if(!defined($devices_list->{$scsihwid})) {
2524 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $scsihwid);
2529 sub qemu_bridgeadd
{
2530 my ($storecfg, $conf, $vmid, $device) = @_;
2533 my $bridgeid = undef;
2534 print_pci_addr
($device, $bridges);
2536 while (my ($k, $v) = each %$bridges) {
2539 return if $bridgeid < 1;
2540 my $bridge = "pci.$bridgeid";
2541 my $devices_list = vm_devices_list
($vmid);
2543 if(!defined($devices_list->{$bridge})) {
2544 return undef if !vm_deviceplug
($storecfg, $conf, $vmid, $bridge);
2549 sub qemu_netdevadd
{
2550 my ($vmid, $conf, $device, $deviceid) = @_;
2552 my $netdev = print_netdev_full
($vmid, $conf, $device, $deviceid);
2553 my $ret = vm_human_monitor_command
($vmid, "netdev_add $netdev");
2556 #if the command succeeds, no output is sent. So any non-empty string shows an error
2557 return 1 if $ret eq "";
2558 syslog
("err", "adding netdev failed: $ret");
2562 sub qemu_netdevdel
{
2563 my ($vmid, $deviceid) = @_;
2565 my $ret = vm_human_monitor_command
($vmid, "netdev_del $deviceid");
2567 #if the command succeeds, no output is sent. So any non-empty string shows an error
2568 return 1 if $ret eq "";
2569 syslog
("err", "deleting netdev failed: $ret");
2573 sub qemu_block_set_io_throttle
{
2574 my ($vmid, $deviceid, $bps, $bps_rd, $bps_wr, $iops, $iops_rd, $iops_wr) = @_;
2576 return if !check_running
($vmid) ;
2579 $bps_rd = 0 if !$bps_rd;
2580 $bps_wr = 0 if !$bps_wr;
2581 $iops = 0 if !$iops;
2582 $iops_rd = 0 if !$iops_rd;
2583 $iops_wr = 0 if !$iops_wr;
2585 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));
2589 # old code, only used to shutdown old VM after update
2591 my ($fh, $timeout) = @_;
2593 my $sel = new IO
::Select
;
2600 while (scalar (@ready = $sel->can_read($timeout))) {
2602 if ($count = $fh->sysread($buf, 8192)) {
2603 if ($buf =~ /^(.*)\(qemu\) $/s) {
2610 if (!defined($count)) {
2617 die "monitor read timeout\n" if !scalar(@ready);
2622 # old code, only used to shutdown old VM after update
2623 sub vm_monitor_command
{
2624 my ($vmid, $cmdstr, $nocheck) = @_;
2629 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
2631 my $sname = "${var_run_tmpdir}/$vmid.mon";
2633 my $sock = IO
::Socket
::UNIX-
>new( Peer
=> $sname ) ||
2634 die "unable to connect to VM $vmid socket - $!\n";
2638 # hack: migrate sometime blocks the monitor (when migrate_downtime
2640 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2641 $timeout = 60*60; # 1 hour
2645 my $data = __read_avail
($sock, $timeout);
2647 if ($data !~ m/^QEMU\s+(\S+)\s+monitor\s/) {
2648 die "got unexpected qemu monitor banner\n";
2651 my $sel = new IO
::Select
;
2654 if (!scalar(my @ready = $sel->can_write($timeout))) {
2655 die "monitor write error - timeout";
2658 my $fullcmd = "$cmdstr\r";
2660 # syslog('info', "VM $vmid monitor command: $cmdstr");
2663 if (!($b = $sock->syswrite($fullcmd)) || ($b != length($fullcmd))) {
2664 die "monitor write error - $!";
2667 return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
2671 if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
2672 $timeout = 60*60; # 1 hour
2673 } elsif ($cmdstr =~ m/^(eject|change)/) {
2674 $timeout = 60; # note: cdrom mount command is slow
2676 if ($res = __read_avail
($sock, $timeout)) {
2678 my @lines = split("\r?\n", $res);
2680 shift @lines if $lines[0] !~ m/^unknown command/; # skip echo
2682 $res = join("\n", @lines);
2690 syslog
("err", "VM $vmid monitor command failed - $err");
2697 sub qemu_block_resize
{
2698 my ($vmid, $deviceid, $storecfg, $volid, $size) = @_;
2700 my $running = PVE
::QemuServer
::check_running
($vmid);
2702 return if !PVE
::Storage
::volume_resize
($storecfg, $volid, $size, $running);
2704 return if !$running;
2706 vm_mon_cmd
($vmid, "block_resize", device
=> $deviceid, size
=> int($size));
2711 my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom) = @_;
2713 lock_config
($vmid, sub {
2714 my $conf = load_config
($vmid, $migratedfrom);
2716 check_lock
($conf) if !$skiplock;
2718 die "VM $vmid already running\n" if check_running
($vmid, undef, $migratedfrom);
2721 my $migrate_port = 0;
2724 if ($statefile eq 'tcp') {
2725 $migrate_port = next_migrate_port
();
2726 $migrate_uri = "tcp:localhost:${migrate_port}";
2728 if (-f
$statefile) {
2729 $migrate_uri = "exec:cat $statefile";
2731 warn "state file '$statefile' does not exist - doing normal startup\n";
2736 my $defaults = load_defaults
();
2738 # set environment variable useful inside network script
2739 $ENV{PVE_MIGRATED_FROM
} = $migratedfrom if $migratedfrom;
2741 my ($cmd, $vollist) = config_to_command
($storecfg, $vmid, $conf, $defaults, $migrate_uri);
2743 for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
2744 my $d = parse_hostpci
($conf->{"hostpci$i"});
2746 my $info = pci_device_info
("0000:$d->{pciid}");
2747 die "IOMMU not present\n" if !check_iommu_support
();
2748 die "no pci device info for device '$d->{pciid}'\n" if !$info;
2749 die "can't unbind pci device '$d->{pciid}'\n" if !pci_dev_bind_to_stub
($info);
2750 die "can't reset pci device '$d->{pciid}'\n" if !pci_dev_reset
($info);
2753 PVE
::Storage
::activate_volumes
($storecfg, $vollist);
2755 eval { run_command
($cmd, timeout
=> $migrate_uri ?
undef : 30); };
2757 die "start failed: $err" if $err;
2761 if ($statefile eq 'tcp') {
2762 print "migration listens on port $migrate_port\n";
2765 # fixme: send resume - is that necessary ?
2766 eval { vm_mon_cmd
($vmid, "cont"); };
2770 # always set migrate speed (overwrite kvm default of 32m)
2771 # we set a very hight default of 8192m which is basically unlimited
2772 my $migrate_speed = $defaults->{migrate_speed
} || 8192;
2773 $migrate_speed = $conf->{migrate_speed
} || $migrate_speed;
2774 $migrate_speed = $migrate_speed * 1048576;
2776 vm_mon_cmd
($vmid, "migrate_set_speed", value
=> $migrate_speed);
2779 my $migrate_downtime = $defaults->{migrate_downtime
};
2780 $migrate_downtime = $conf->{migrate_downtime
} if defined($conf->{migrate_downtime
});
2781 if (defined($migrate_downtime)) {
2782 eval { vm_mon_cmd
($vmid, "migrate_set_downtime", value
=> $migrate_downtime); };
2785 vm_balloonset
($vmid, $conf->{balloon
}) if $conf->{balloon
};
2791 my ($vmid, $execute, %params) = @_;
2793 my $cmd = { execute
=> $execute, arguments
=> \
%params };
2794 vm_qmp_command
($vmid, $cmd);
2797 sub vm_mon_cmd_nocheck
{
2798 my ($vmid, $execute, %params) = @_;
2800 my $cmd = { execute
=> $execute, arguments
=> \
%params };
2801 vm_qmp_command
($vmid, $cmd, 1);
2804 sub vm_qmp_command
{
2805 my ($vmid, $cmd, $nocheck) = @_;
2810 die "VM $vmid not running\n" if !check_running
($vmid, $nocheck);
2811 my $sname = PVE
::QemuServer
::qmp_socket
($vmid);
2813 my $qmpclient = PVE
::QMPClient-
>new();
2815 $res = $qmpclient->cmd($vmid, $cmd);
2816 } elsif (-e
"${var_run_tmpdir}/$vmid.mon") {
2817 die "can't execute complex command on old monitor - stop/start your vm to fix the problem\n"
2818 if scalar(%{$cmd->{arguments
}});
2819 vm_monitor_command
($vmid, $cmd->{execute
}, $nocheck);
2821 die "unable to open monitor socket\n";
2825 syslog
("err", "VM $vmid qmp command failed - $err");
2832 sub vm_human_monitor_command
{
2833 my ($vmid, $cmdline) = @_;
2838 execute
=> 'human-monitor-command',
2839 arguments
=> { 'command-line' => $cmdline},
2842 return vm_qmp_command
($vmid, $cmd);
2845 sub vm_commandline
{
2846 my ($storecfg, $vmid) = @_;
2848 my $conf = load_config
($vmid);
2850 my $defaults = load_defaults
();
2852 my $cmd = config_to_command
($storecfg, $vmid, $conf, $defaults);
2854 return join(' ', @$cmd);
2858 my ($vmid, $skiplock) = @_;
2860 lock_config
($vmid, sub {
2862 my $conf = load_config
($vmid);
2864 check_lock
($conf) if !$skiplock;
2866 vm_mon_cmd
($vmid, "system_reset");
2870 sub get_vm_volumes
{
2874 foreach_drive
($conf, sub {
2875 my ($ds, $drive) = @_;
2877 my ($sid, $volname) = PVE
::Storage
::parse_volume_id
($drive->{file
}, 1);
2880 my $volid = $drive->{file
};
2881 return if !$volid || $volid =~ m
|^/|;
2883 push @$vollist, $volid;
2889 sub vm_stop_cleanup
{
2890 my ($storecfg, $vmid, $conf, $keepActive) = @_;
2893 fairsched_rmnod
($vmid); # try to destroy group
2896 my $vollist = get_vm_volumes
($conf);
2897 PVE
::Storage
::deactivate_volumes
($storecfg, $vollist);
2900 foreach my $ext (qw(mon pid vnc)) {
2901 unlink "/var/run/qemu-server/${vmid}.$ext";
2904 warn $@ if $@; # avoid errors - just warn
2907 # Note: use $nockeck to skip tests if VM configuration file exists.
2908 # We need that when migration VMs to other nodes (files already moved)
2909 # Note: we set $keepActive in vzdump stop mode - volumes need to stay active
2911 my ($storecfg, $vmid, $skiplock, $nocheck, $timeout, $shutdown, $force, $keepActive) = @_;
2913 $force = 1 if !defined($force) && !$shutdown;
2915 lock_config
($vmid, sub {
2917 my $pid = check_running
($vmid, $nocheck);
2922 $conf = load_config
($vmid);
2923 check_lock
($conf) if !$skiplock;
2924 if (!defined($timeout) && $shutdown && $conf->{startup
}) {
2925 my $opts = parse_startup
($conf->{startup
});
2926 $timeout = $opts->{down
} if $opts->{down
};
2930 $timeout = 60 if !defined($timeout);
2934 $nocheck ? vm_mon_cmd_nocheck
($vmid, "system_powerdown") : vm_mon_cmd
($vmid, "system_powerdown");
2937 $nocheck ? vm_mon_cmd_nocheck
($vmid, "quit") : vm_mon_cmd
($vmid, "quit");
2944 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
2949 if ($count >= $timeout) {
2951 warn "VM still running - terminating now with SIGTERM\n";
2954 die "VM quit/powerdown failed - got timeout\n";
2957 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
2962 warn "VM quit/powerdown failed - terminating now with SIGTERM\n";
2965 die "VM quit/powerdown failed\n";
2973 while (($count < $timeout) && check_running
($vmid, $nocheck)) {
2978 if ($count >= $timeout) {
2979 warn "VM still running - terminating now with SIGKILL\n";
2984 vm_stop_cleanup
($storecfg, $vmid, $conf, $keepActive) if $conf;
2989 my ($vmid, $skiplock) = @_;
2991 lock_config
($vmid, sub {
2993 my $conf = load_config
($vmid);
2995 check_lock
($conf) if !$skiplock;
2997 vm_mon_cmd
($vmid, "stop");
3002 my ($vmid, $skiplock) = @_;
3004 lock_config
($vmid, sub {
3006 my $conf = load_config
($vmid);
3008 check_lock
($conf) if !$skiplock;
3010 vm_mon_cmd
($vmid, "cont");
3015 my ($vmid, $skiplock, $key) = @_;
3017 lock_config
($vmid, sub {
3019 my $conf = load_config
($vmid);
3021 # there is no qmp command, so we use the human monitor command
3022 vm_human_monitor_command
($vmid, "sendkey $key");
3027 my ($storecfg, $vmid, $skiplock) = @_;
3029 lock_config
($vmid, sub {
3031 my $conf = load_config
($vmid);
3033 check_lock
($conf) if !$skiplock;
3035 if (!check_running
($vmid)) {
3036 fairsched_rmnod
($vmid); # try to destroy group
3037 destroy_vm
($storecfg, $vmid);
3039 die "VM $vmid is running - destroy failed\n";
3047 my ($filename, $buf) = @_;
3049 my $fh = IO
::File-
>new($filename, "w");
3050 return undef if !$fh;
3052 my $res = print $fh $buf;
3059 sub pci_device_info
{
3064 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/;
3065 my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4);
3067 my $irq = file_read_firstline
("$pcisysfs/devices/$name/irq");
3068 return undef if !defined($irq) || $irq !~ m/^\d+$/;
3070 my $vendor = file_read_firstline
("$pcisysfs/devices/$name/vendor");
3071 return undef if !defined($vendor) || $vendor !~ s/^0x//;
3073 my $product = file_read_firstline
("$pcisysfs/devices/$name/device");
3074 return undef if !defined($product) || $product !~ s/^0x//;
3079 product
=> $product,
3085 has_fl_reset
=> -f
"$pcisysfs/devices/$name/reset" || 0,
3094 my $name = $dev->{name
};
3096 my $fn = "$pcisysfs/devices/$name/reset";
3098 return file_write
($fn, "1");
3101 sub pci_dev_bind_to_stub
{
3104 my $name = $dev->{name
};
3106 my $testdir = "$pcisysfs/drivers/pci-stub/$name";
3107 return 1 if -d
$testdir;
3109 my $data = "$dev->{vendor} $dev->{product}";
3110 return undef if !file_write
("$pcisysfs/drivers/pci-stub/new_id", $data);
3112 my $fn = "$pcisysfs/devices/$name/driver/unbind";
3113 if (!file_write
($fn, $name)) {
3114 return undef if -f
$fn;
3117 $fn = "$pcisysfs/drivers/pci-stub/bind";
3118 if (! -d
$testdir) {
3119 return undef if !file_write
($fn, $name);
3125 sub print_pci_addr
{
3126 my ($id, $bridges) = @_;
3130 #addr1 : ide,parallel,serial (motherboard)
3131 #addr2 : first videocard
3132 balloon0
=> { bus
=> 0, addr
=> 3 },
3133 watchdog
=> { bus
=> 0, addr
=> 4 },
3134 scsihw0
=> { bus
=> 0, addr
=> 5 },
3135 scsihw1
=> { bus
=> 0, addr
=> 6 },
3136 ahci0
=> { bus
=> 0, addr
=> 7 },
3137 virtio0
=> { bus
=> 0, addr
=> 10 },
3138 virtio1
=> { bus
=> 0, addr
=> 11 },
3139 virtio2
=> { bus
=> 0, addr
=> 12 },
3140 virtio3
=> { bus
=> 0, addr
=> 13 },
3141 virtio4
=> { bus
=> 0, addr
=> 14 },
3142 virtio5
=> { bus
=> 0, addr
=> 15 },
3143 hostpci0
=> { bus
=> 0, addr
=> 16 },
3144 hostpci1
=> { bus
=> 0, addr
=> 17 },
3145 net0
=> { bus
=> 0, addr
=> 18 },
3146 net1
=> { bus
=> 0, addr
=> 19 },
3147 net2
=> { bus
=> 0, addr
=> 20 },
3148 net3
=> { bus
=> 0, addr
=> 21 },
3149 net4
=> { bus
=> 0, addr
=> 22 },
3150 net5
=> { bus
=> 0, addr
=> 23 },
3151 #addr29 : usb-host (pve-usb.cfg)
3152 'pci.1' => { bus
=> 0, addr
=> 30 },
3153 'pci.2' => { bus
=> 0, addr
=> 31 },
3154 'net6' => { bus
=> 1, addr
=> 1 },
3155 'net7' => { bus
=> 1, addr
=> 2 },
3156 'net8' => { bus
=> 1, addr
=> 3 },
3157 'net9' => { bus
=> 1, addr
=> 4 },
3158 'net10' => { bus
=> 1, addr
=> 5 },
3159 'net11' => { bus
=> 1, addr
=> 6 },
3160 'net12' => { bus
=> 1, addr
=> 7 },
3161 'net13' => { bus
=> 1, addr
=> 8 },
3162 'net14' => { bus
=> 1, addr
=> 9 },
3163 'net15' => { bus
=> 1, addr
=> 10 },
3164 'net16' => { bus
=> 1, addr
=> 11 },
3165 'net17' => { bus
=> 1, addr
=> 12 },
3166 'net18' => { bus
=> 1, addr
=> 13 },
3167 'net19' => { bus
=> 1, addr
=> 14 },
3168 'net20' => { bus
=> 1, addr
=> 15 },
3169 'net21' => { bus
=> 1, addr
=> 16 },
3170 'net22' => { bus
=> 1, addr
=> 17 },
3171 'net23' => { bus
=> 1, addr
=> 18 },
3172 'net24' => { bus
=> 1, addr
=> 19 },
3173 'net25' => { bus
=> 1, addr
=> 20 },
3174 'net26' => { bus
=> 1, addr
=> 21 },
3175 'net27' => { bus
=> 1, addr
=> 22 },
3176 'net28' => { bus
=> 1, addr
=> 23 },
3177 'net29' => { bus
=> 1, addr
=> 24 },
3178 'net30' => { bus
=> 1, addr
=> 25 },
3179 'net31' => { bus
=> 1, addr
=> 26 },
3180 'virtio6' => { bus
=> 2, addr
=> 1 },
3181 'virtio7' => { bus
=> 2, addr
=> 2 },
3182 'virtio8' => { bus
=> 2, addr
=> 3 },
3183 'virtio9' => { bus
=> 2, addr
=> 4 },
3184 'virtio10' => { bus
=> 2, addr
=> 5 },
3185 'virtio11' => { bus
=> 2, addr
=> 6 },
3186 'virtio12' => { bus
=> 2, addr
=> 7 },
3187 'virtio13' => { bus
=> 2, addr
=> 8 },
3188 'virtio14' => { bus
=> 2, addr
=> 9 },
3189 'virtio15' => { bus
=> 2, addr
=> 10 },
3192 if (defined($devices->{$id}->{bus
}) && defined($devices->{$id}->{addr
})) {
3193 my $addr = sprintf("0x%x", $devices->{$id}->{addr
});
3194 my $bus = $devices->{$id}->{bus
};
3195 $res = ",bus=pci.$bus,addr=$addr";
3196 $bridges->{$bus} = 1 if $bridges;
3203 my ($vmid, $value) = @_;
3205 vm_mon_cmd
($vmid, "balloon", value
=> $value);
3208 # vzdump restore implementaion
3210 sub archive_read_firstfile
{
3211 my $archive = shift;
3213 die "ERROR: file '$archive' does not exist\n" if ! -f
$archive;
3215 # try to detect archive type first
3216 my $pid = open (TMP
, "tar tf '$archive'|") ||
3217 die "unable to open file '$archive'\n";
3218 my $firstfile = <TMP
>;
3222 die "ERROR: archive contaions no data\n" if !$firstfile;
3228 sub restore_cleanup
{
3229 my $statfile = shift;
3231 print STDERR
"starting cleanup\n";
3233 if (my $fd = IO
::File-
>new($statfile, "r")) {
3234 while (defined(my $line = <$fd>)) {
3235 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3238 if ($volid =~ m
|^/|) {
3239 unlink $volid || die 'unlink failed\n';
3241 my $cfg = cfs_read_file
('storage.cfg');
3242 PVE
::Storage
::vdisk_free
($cfg, $volid);
3244 print STDERR
"temporary volume '$volid' sucessfuly removed\n";
3246 print STDERR
"unable to cleanup '$volid' - $@" if $@;
3248 print STDERR
"unable to parse line in statfile - $line";
3255 sub restore_archive
{
3256 my ($archive, $vmid, $user, $opts) = @_;
3258 if ($archive ne '-') {
3259 my $firstfile = archive_read_firstfile
($archive);
3260 die "ERROR: file '$archive' dos not lock like a QemuServer vzdump backup\n"
3261 if $firstfile ne 'qemu-server.conf';
3264 my $tocmd = "/usr/lib/qemu-server/qmextract";
3266 $tocmd .= " --storage " . PVE
::Tools
::shellquote
($opts->{storage
}) if $opts->{storage
};
3267 $tocmd .= " --pool " . PVE
::Tools
::shellquote
($opts->{pool
}) if $opts->{pool
};
3268 $tocmd .= ' --prealloc' if $opts->{prealloc
};
3269 $tocmd .= ' --info' if $opts->{info
};
3271 # tar option "xf" does not autodetect compression when read from STDIN,
3272 # so we pipe to zcat
3273 my $cmd = "zcat -f|tar xf " . PVE
::Tools
::shellquote
($archive) . " " .
3274 PVE
::Tools
::shellquote
("--to-command=$tocmd");
3276 my $tmpdir = "/var/tmp/vzdumptmp$$";
3279 local $ENV{VZDUMP_TMPDIR
} = $tmpdir;
3280 local $ENV{VZDUMP_VMID
} = $vmid;
3281 local $ENV{VZDUMP_USER
} = $user;
3283 my $conffile = PVE
::QemuServer
::config_file
($vmid);
3284 my $tmpfn = "$conffile.$$.tmp";
3286 # disable interrupts (always do cleanups)
3287 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
3288 print STDERR
"got interrupt - ignored\n";
3293 local $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
3294 die "interrupted by signal\n";
3297 if ($archive eq '-') {
3298 print "extracting archive from STDIN\n";
3299 run_command
($cmd, input
=> "<&STDIN");
3301 print "extracting archive '$archive'\n";
3305 return if $opts->{info
};
3309 my $statfile = "$tmpdir/qmrestore.stat";
3310 if (my $fd = IO
::File-
>new($statfile, "r")) {
3311 while (defined (my $line = <$fd>)) {
3312 if ($line =~ m/vzdump:([^\s:]*):(\S+)$/) {
3313 $map->{$1} = $2 if $1;
3315 print STDERR
"unable to parse line in statfile - $line\n";
3321 my $confsrc = "$tmpdir/qemu-server.conf";
3323 my $srcfd = new IO
::File
($confsrc, "r") ||
3324 die "unable to open file '$confsrc'\n";
3326 my $outfd = new IO
::File
($tmpfn, "w") ||
3327 die "unable to write config for VM $vmid\n";
3331 while (defined (my $line = <$srcfd>)) {
3332 next if $line =~ m/^\#vzdump\#/;
3333 next if $line =~ m/^lock:/;
3334 next if $line =~ m/^unused\d+:/;
3336 if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
3337 # try to convert old 1.X settings
3338 my ($id, $ind, $ethcfg) = ($1, $2, $3);
3339 foreach my $devconfig (PVE
::Tools
::split_list
($ethcfg)) {
3340 my ($model, $macaddr) = split(/\=/, $devconfig);
3341 $macaddr = PVE
::Tools
::random_ether_addr
() if !$macaddr || $opts->{unique
};
3344 bridge
=> "vmbr$ind",
3345 macaddr
=> $macaddr,
3347 my $netstr = print_net
($net);
3348 print $outfd "net${netcount}: $netstr\n";
3351 } elsif (($line =~ m/^(net\d+):\s*(\S+)\s*$/) && ($opts->{unique
})) {
3352 my ($id, $netstr) = ($1, $2);
3353 my $net = parse_net
($netstr);
3354 $net->{macaddr
} = PVE
::Tools
::random_ether_addr
() if $net->{macaddr
};
3355 $netstr = print_net
($net);
3356 print $outfd "$id: $netstr\n";
3357 } elsif ($line =~ m/^((ide|scsi|virtio)\d+):\s*(\S+)\s*$/) {
3360 if ($line =~ m/backup=no/) {
3361 print $outfd "#$line";
3362 } elsif ($virtdev && $map->{$virtdev}) {
3363 my $di = PVE
::QemuServer
::parse_drive
($virtdev, $value);
3364 $di->{file
} = $map->{$virtdev};
3365 $value = PVE
::QemuServer
::print_drive
($vmid, $di);
3366 print $outfd "$virtdev: $value\n";
3384 restore_cleanup
("$tmpdir/qmrestore.stat") if !$opts->{info
};
3391 rename $tmpfn, $conffile ||
3392 die "unable to commit configuration file '$conffile'\n";