]>
git.proxmox.com Git - qemu-server.git/blob - PVE/QemuServer.pm
1 package PVE
:: QemuServer
;
20 use Storable
qw(dclone) ;
21 use PVE
:: Exception
qw(raise raise_param_exc) ;
23 use PVE
:: Tools
qw(run_command lock_file file_read_firstline) ;
24 use PVE
:: Cluster
qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file) ;
27 use Time
:: HiRes
qw(gettimeofday) ;
29 my $cpuinfo = PVE
:: ProcFSTools
:: read_cpuinfo
();
31 # Note about locking: we use flock on the config file protect
32 # against concurent actions.
33 # Aditionaly, we have a 'lock' setting in the config file. This
34 # can be set to 'migrate' or 'backup'. Most actions are not
35 # allowed when such lock is set. But you can ignore this kind of
36 # lock with the --skiplock flag.
38 cfs_register_file
( '/qemu-server/' , \
& parse_vm_config
);
40 PVE
:: JSONSchema
:: register_standard_option
( 'skiplock' , {
41 description
=> "Ignore locks - only root is allowed to use this option." ,
46 PVE
:: JSONSchema
:: register_standard_option
( 'pve-qm-stateuri' , {
47 description
=> "Some command save/restore state from this location." ,
53 #no warnings 'redefine';
55 unless ( defined (& _VZSYSCALLS_H_
)) {
56 eval 'sub _VZSYSCALLS_H_ () {1;}' unless defined (& _VZSYSCALLS_H_
);
57 require 'sys/syscall.ph' ;
58 if ( defined (& __x86_64__
)) {
59 eval 'sub __NR_fairsched_vcpus () {499;}' unless defined (& __NR_fairsched_vcpus
);
60 eval 'sub __NR_fairsched_mknod () {504;}' unless defined (& __NR_fairsched_mknod
);
61 eval 'sub __NR_fairsched_rmnod () {505;}' unless defined (& __NR_fairsched_rmnod
);
62 eval 'sub __NR_fairsched_chwt () {506;}' unless defined (& __NR_fairsched_chwt
);
63 eval 'sub __NR_fairsched_mvpr () {507;}' unless defined (& __NR_fairsched_mvpr
);
64 eval 'sub __NR_fairsched_rate () {508;}' unless defined (& __NR_fairsched_rate
);
65 eval 'sub __NR_setluid () {501;}' unless defined (& __NR_setluid
);
66 eval 'sub __NR_setublimit () {502;}' unless defined (& __NR_setublimit
);
68 elsif ( defined ( & __i386__
) ) {
69 eval 'sub __NR_fairsched_mknod () {500;}' unless defined (& __NR_fairsched_mknod
);
70 eval 'sub __NR_fairsched_rmnod () {501;}' unless defined (& __NR_fairsched_rmnod
);
71 eval 'sub __NR_fairsched_chwt () {502;}' unless defined (& __NR_fairsched_chwt
);
72 eval 'sub __NR_fairsched_mvpr () {503;}' unless defined (& __NR_fairsched_mvpr
);
73 eval 'sub __NR_fairsched_rate () {504;}' unless defined (& __NR_fairsched_rate
);
74 eval 'sub __NR_fairsched_vcpus () {505;}' unless defined (& __NR_fairsched_vcpus
);
75 eval 'sub __NR_setluid () {511;}' unless defined (& __NR_setluid
);
76 eval 'sub __NR_setublimit () {512;}' unless defined (& __NR_setublimit
);
78 die ( "no fairsched syscall for this arch" );
80 require 'asm/ioctl.ph' ;
81 eval 'sub KVM_GET_API_VERSION () { &_IO(0xAE, 0x);}' unless defined (& KVM_GET_API_VERSION
);
85 my ( $parent, $weight, $desired ) = @_ ;
87 return syscall (& __NR_fairsched_mknod
, int ( $parent ), int ( $weight ), int ( $desired ));
93 return syscall (& __NR_fairsched_rmnod
, int ( $id ));
97 my ( $pid, $newid ) = @_ ;
99 return syscall (& __NR_fairsched_mvpr
, int ( $pid ), int ( $newid ));
102 sub fairsched_vcpus
{
103 my ( $id, $vcpus ) = @_ ;
105 return syscall (& __NR_fairsched_vcpus
, int ( $id ), int ( $vcpus ));
109 my ( $id, $op, $rate ) = @_ ;
111 return syscall (& __NR_fairsched_rate
, int ( $id ), int ( $op ), int ( $rate ));
114 use constant FAIRSCHED_SET_RATE
=> 0 ;
115 use constant FAIRSCHED_DROP_RATE
=> 1 ;
116 use constant FAIRSCHED_GET_RATE
=> 2 ;
118 sub fairsched_cpulimit
{
119 my ( $id, $limit ) = @_ ;
121 my $cpulim1024 = int ( $limit * 1024 / 100 );
122 my $op = $cpulim1024 ? FAIRSCHED_SET_RATE
: FAIRSCHED_DROP_RATE
;
124 return fairsched_rate
( $id, $op, $cpulim1024 );
127 my $nodename = PVE
:: INotify
:: nodename
();
129 mkdir "/etc/pve/nodes/ $nodename " ;
130 my $confdir = "/etc/pve/nodes/ $nodename/qemu -server" ;
133 my $var_run_tmpdir = "/var/run/qemu-server" ;
134 mkdir $var_run_tmpdir ;
136 my $lock_dir = "/var/lock/qemu-server" ;
139 my $pcisysfs = "/sys/bus/pci" ;
141 my $keymaphash = PVE
:: Tools
:: kvmkeymaps
();
147 description
=> "Specifies whether a VM will be started during system bootup." ,
153 description
=> "Automatic restart after crash (currently ignored)." ,
159 description
=> "Activate hotplug for disk and network device" ,
165 description
=> "Allow reboot. If set to '0' the VM exit on reboot." ,
171 description
=> "Lock/unlock the VM." ,
172 enum
=> [ qw(migrate backup) ],
177 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\n NOTE: This option is currently ignored." ,
184 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\n NOTE: You can disable fair-scheduler configuration by setting this to 0." ,
192 description
=> "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device." ,
199 description
=> "Amount of target RAM for the VM in MB." ,
205 description
=> "Keybord layout for vnc server. Default is read from the datacenter configuration file." ,
206 enum
=> [ keys %$keymaphash ],
212 description
=> "Set a name for the VM. Only used on the configuration web interface." ,
217 description
=> "Description for the VM. Only used on the configuration web interface." ,
222 enum
=> [ qw(other wxp w2k w2k3 w2k8 wvista win7 l24 l26) ],
223 description
=> <<EODESC,
224 Used to enable special optimization/features for specific
227 other => unspecified OS
228 wxp => Microsoft Windows XP
229 w2k => Microsoft Windows 2000
230 w2k3 => Microsoft Windows 2003
231 w2k8 => Microsoft Windows 2008
232 wvista => Microsoft Windows Vista
233 win7 => Microsoft Windows 7
234 l24 => Linux 2.4 Kernel
235 l26 => Linux 2.6/3.X Kernel
237 other|l24|l26 ... no special behaviour
238 wxp|w2k|w2k3|w2k8|wvista|win7 ... use --localtime switch
244 description
=> "Boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)." ,
245 pattern
=> '[acdn]{1,4}' ,
250 type
=> 'string' , format
=> 'pve-qm-bootdisk' ,
251 description
=> "Enable booting from specified disk." ,
252 pattern
=> '(ide|scsi|virtio)\d+' ,
257 description
=> "The number of CPUs. Please use option -sockets instead." ,
264 description
=> "The number of CPU sockets." ,
271 description
=> "The number of cores per socket." ,
278 description
=> "Enable/disable ACPI." ,
284 description
=> "Enable/disable KVM hardware virtualization." ,
290 description
=> "Enable/disable time drift fix." ,
296 description
=> "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS." ,
301 description
=> "Freeze CPU at startup (use 'c' monitor command to start execution)." ,
306 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" ,
307 enum
=> [ qw(std cirrus vmware) ],
311 type
=> 'string' , format
=> 'pve-qm-watchdog' ,
312 typetext
=> '[[model=]i6300esb|ib700] [,[action=]reset|shutdown|poweroff|pause|debug|none]' ,
313 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)" ,
318 typetext
=> "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" ,
319 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'." ,
320 pattern
=> '(now|\d{4}-\d{1,2}-\d{1,2}(T\d{1,2}:\d{1,2}:\d{1,2})?)' ,
326 description
=> <<EODESCR,
327 Note: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
329 args: -no-reboot -no-hpet
336 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." ,
341 description
=> "Set maximum speed (in MB/s) for migrations. Value 0 is no limit." ,
345 migrate_downtime
=> {
348 description
=> "Set maximum tolerated downtime (in seconds) for migrations." ,
354 type
=> 'string' , format
=> 'pve-qm-drive' ,
355 typetext
=> 'volume' ,
356 description
=> "This is an alias for option -ide2" ,
360 description
=> "Emulated CPU type." ,
362 enum
=> [ qw(486 athlon pentium pentium2 pentium3 coreduo core2duo kvm32 kvm64 qemu32 qemu64 phenom host) ],
367 # what about other qemu settings ?
369 #machine => 'string',
382 ##soundhw => 'string',
384 while ( my ( $k, $v ) = each %$confdesc ) {
385 PVE
:: JSONSchema
:: register_standard_option
( "pve-qm- $k " , $v );
388 my $MAX_IDE_DISKS = 4 ;
389 my $MAX_SCSI_DISKS = 14 ;
390 my $MAX_VIRTIO_DISKS = 6 ;
391 my $MAX_USB_DEVICES = 5 ;
393 my $MAX_UNUSED_DISKS = 8 ;
394 my $MAX_HOSTPCI_DEVICES = 2 ;
395 my $MAX_SERIAL_PORTS = 4 ;
396 my $MAX_PARALLEL_PORTS = 3 ;
398 my $nic_model_list = [ 'rtl8139' , 'ne2k_pci' , 'e1000' , 'pcnet' , 'virtio' ,
399 'ne2k_isa' , 'i82551' , 'i82557b' , 'i82559er' ];
400 my $nic_model_list_txt = join ( ' ' , sort @$nic_model_list );
405 type
=> 'string' , format
=> 'pve-qm-net' ,
406 typetext
=> "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,rate=<mbps>]" ,
407 description
=> <<EODESCR,
408 Specify network devices.
410 MODEL is one of: $nic_model_list_txt
412 XX:XX:XX:XX:XX:XX should be an unique MAC address. This is
413 automatically generated if not specified.
415 The bridge parameter can be used to automatically add the interface to a bridge device. The Proxmox VE standard bridge is called 'vmbr0'.
417 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'.
419 If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services. The following addresses are used:
425 The DHCP server assign addresses to the guest starting from 10.0.2.15.
429 PVE
:: JSONSchema
:: register_standard_option
( "pve-qm-net" , $netdesc );
431 for ( my $i = 0 ; $i < $MAX_NETS ; $i++ ) {
432 $confdesc ->{ "net $i " } = $netdesc ;
439 type
=> 'string' , format
=> 'pve-qm-drive' ,
440 typetext
=> '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback] [,format=f] [,backup=yes|no] [,aio=native|threads]' ,
441 description
=> "Use volume as IDE hard disk or CD-ROM (n is 0 to 3)." ,
443 PVE
:: JSONSchema
:: register_standard_option
( "pve-qm-ide" , $idedesc );
447 type
=> 'string' , format
=> 'pve-qm-drive' ,
448 typetext
=> '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback] [,format=f] [,backup=yes|no] [,aio=native|threads]' ,
449 description
=> "Use volume as SCSI hard disk or CD-ROM (n is 0 to 13)." ,
451 PVE
:: JSONSchema
:: register_standard_option
( "pve-qm-scsi" , $scsidesc );
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] [,format=f] [,backup=yes|no] [,aio=native|threads]' ,
457 description
=> "Use volume as VIRTIO hard disk (n is 0 to 5)." ,
459 PVE
:: JSONSchema
:: register_standard_option
( "pve-qm-virtio" , $virtiodesc );
463 type
=> 'string' , format
=> 'pve-qm-usb-device' ,
464 typetext
=> 'host=HOSTUSBDEVICE' ,
465 description
=> <<EODESCR,
466 Configure an USB device (n is 0 to 4). This can be used to
467 pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
469 'bus-port(.port)*' (decimal numbers) or
470 'vendor_id:product_id' (hexadeciaml numbers)
472 You can use the 'lsusb -t' command to list existing usb devices.
474 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
478 PVE
:: JSONSchema
:: register_standard_option
( "pve-qm-usb" , $usbdesc );
482 type
=> 'string' , format
=> 'pve-qm-hostpci' ,
483 typetext
=> "HOSTPCIDEVICE" ,
484 description
=> <<EODESCR,
485 Map host pci devices. HOSTPCIDEVICE syntax is:
487 'bus:dev.func' (hexadecimal numbers)
489 You can us the 'lspci' command to list existing pci devices.
491 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
493 Experimental: user reported problems with this option.
496 PVE
:: JSONSchema
:: register_standard_option
( "pve-qm-hostpci" , $hostpcidesc );
501 pattern
=> '/dev/ttyS\d+' ,
502 description
=> <<EODESCR,
503 Map host serial devices (n is 0 to 3).
505 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
507 Experimental: user reported problems with this option.
514 pattern
=> '/dev/parport\d+' ,
515 description
=> <<EODESCR,
516 Map host parallel devices (n is 0 to 2).
518 Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
520 Experimental: user reported problems with this option.
524 for ( my $i = 0 ; $i < $MAX_PARALLEL_PORTS ; $i++ ) {
525 $confdesc ->{ "parallel $i " } = $paralleldesc ;
528 for ( my $i = 0 ; $i < $MAX_SERIAL_PORTS ; $i++ ) {
529 $confdesc ->{ "serial $i " } = $serialdesc ;
532 for ( my $i = 0 ; $i < $MAX_HOSTPCI_DEVICES ; $i++ ) {
533 $confdesc ->{ "hostpci $i " } = $hostpcidesc ;
536 for ( my $i = 0 ; $i < $MAX_IDE_DISKS ; $i++ ) {
537 $drivename_hash ->{ "ide $i " } = 1 ;
538 $confdesc ->{ "ide $i " } = $idedesc ;
541 for ( my $i = 0 ; $i < $MAX_SCSI_DISKS ; $i++ ) {
542 $drivename_hash ->{ "scsi $i " } = 1 ;
543 $confdesc ->{ "scsi $i " } = $scsidesc ;
546 for ( my $i = 0 ; $i < $MAX_VIRTIO_DISKS ; $i++ ) {
547 $drivename_hash ->{ "virtio $i " } = 1 ;
548 $confdesc ->{ "virtio $i " } = $virtiodesc ;
551 for ( my $i = 0 ; $i < $MAX_USB_DEVICES ; $i++ ) {
552 $confdesc ->{ "usb $i " } = $usbdesc ;
557 type
=> 'string' , format
=> 'pve-volume-id' ,
558 description
=> "Reference to unused volumes." ,
561 for ( my $i = 0 ; $i < $MAX_UNUSED_DISKS ; $i++ ) {
562 $confdesc ->{ "unused $i " } = $unuseddesc ;
565 my $kvm_api_version = 0 ;
569 return $kvm_api_version if $kvm_api_version ;
571 my $fh = IO
:: File-
> new ( "</dev/kvm" ) ||
574 if ( my $v = $fh -> ioctl ( KVM_GET_API_VERSION
(), 0 )) {
575 $kvm_api_version = $v ;
580 return $kvm_api_version ;
583 my $kvm_user_version ;
585 sub kvm_user_version
{
587 return $kvm_user_version if $kvm_user_version ;
589 $kvm_user_version = 'unknown' ;
591 my $tmp = `kvm -help 2>/dev/null` ;
593 if ( $tmp =~ m/^QEMU( PC)? emulator version (\d+\.\d+\.\d+) / ) {
594 $kvm_user_version = $2 ;
597 return $kvm_user_version ;
601 my $kernel_has_vhost_net = - c
'/dev/vhost-net' ;
604 # order is important - used to autoselect boot disk
605 return (( map { "ide $_ " } ( 0 .. ( $MAX_IDE_DISKS - 1 ))),
606 ( map { "scsi $_ " } ( 0 .. ( $MAX_SCSI_DISKS - 1 ))),
607 ( map { "virtio $_ " } ( 0 .. ( $MAX_VIRTIO_DISKS - 1 ))));
610 sub valid_drivename
{
613 return defined ( $drivename_hash ->{ $dev });
618 return defined ( $confdesc ->{ $key });
622 return $nic_model_list ;
625 sub os_list_description
{
630 w2k
=> 'Windows 2000' ,
631 w2k3
=>, 'Windows 2003' ,
632 w2k8
=> 'Windows 2008' ,
633 wvista
=> 'Windows Vista' ,
640 # a clumsy way to split an argument string into an array,
641 # we simply pass it to the cli (exec call)
642 # fixme: use Text::ParseWords::shellwords() ?
648 return $args if ! $str ;
650 my $cmd = 'perl -e \' foreach my $a ( @ARGV ) { print " $a\n "; } \' -- ' . $str ;
653 run_command
( $cmd, outfunc
=> sub {
661 die "unable to parse args: $str\n " if $err ;
666 sub disk_devive_info
{
669 die "unknown disk device format ' $dev '" if $dev !~ m/^(ide|scsi|virtio)(\d+)$/ ;
677 } elsif ( $bus eq 'scsi' ) {
681 my $controller = int ( $index / $maxdev );
682 my $unit = $index % $maxdev ;
685 return { bus
=> $bus, desc
=> uc ( $bus ) . " $controller : $unit " ,
686 controller
=> $controller, unit
=> $unit, index => $index };
690 sub qemu_drive_name
{
691 my ( $dev, $media ) = @_ ;
693 my $info = disk_devive_info
( $dev );
696 if (( $info ->{ bus
} eq 'ide' ) || ( $info ->{ bus
} eq 'scsi' )) {
697 $mediastr = ( $media eq 'cdrom' ) ?
"-cd" : "-hd" ;
698 return sprintf ( " %s%i%s%i " , $info ->{ bus
}, $info ->{ controller
},
699 $mediastr, $info ->{ unit
});
701 return sprintf ( " %s%i " , $info ->{ bus
}, $info ->{ index });
709 return $cdrom_path if $cdrom_path ;
711 return $cdrom_path = "/dev/cdrom" if - l
"/dev/cdrom" ;
712 return $cdrom_path = "/dev/cdrom1" if - l
"/dev/cdrom1" ;
713 return $cdrom_path = "/dev/cdrom2" if - l
"/dev/cdrom2" ;
717 my ( $storecfg, $vmid, $cdrom ) = @_ ;
719 if ( $cdrom eq 'cdrom' ) {
720 return get_cdrom_path
();
721 } elsif ( $cdrom eq 'none' ) {
723 } elsif ( $cdrom =~ m
|^/|) {
726 return PVE
:: Storage
:: path
( $storecfg, $cdrom );
730 # try to convert old style file names to volume IDs
731 sub filename_to_volume_id
{
732 my ( $vmid, $file, $media ) = @_ ;
734 if (!( $file eq 'none' || $file eq 'cdrom' ||
735 $file =~ m
|^ /dev/ .+| || $file =~ m/^([^:]+):(.+)$/ )) {
737 return undef if $file =~ m
|/|;
739 if ( $media && $media eq 'cdrom' ) {
740 $file = "local:iso/ $file " ;
742 $file = "local: $vmid/$file " ;
749 sub verify_media_type
{
750 my ( $opt, $vtype, $media ) = @_ ;
755 if ( $media eq 'disk' ) {
757 } elsif ( $media eq 'cdrom' ) {
760 die "internal error" ;
763 return if ( $vtype eq $etype );
765 raise_param_exc
({ $opt => "unexpected media type ( $vtype != $etype )" });
768 sub cleanup_drive_path
{
769 my ( $opt, $storecfg, $drive ) = @_ ;
771 # try to convert filesystem paths to volume IDs
773 if (( $drive ->{ file
} !~ m/^(cdrom|none)$/ ) &&
774 ( $drive ->{ file
} !~ m
|^ /dev/ .+|) &&
775 ( $drive ->{ file
} !~ m/^([^:]+):(.+)$/ ) &&
776 ( $drive ->{ file
} !~ m/^\d+$/ )) {
777 my ( $vtype, $volid ) = PVE
:: Storage
:: path_to_volume_id
( $storecfg, $drive ->{ file
});
778 raise_param_exc
({ $opt => "unable to associate path ' $drive ->{file}' to any storage" }) if ! $vtype ;
779 $drive ->{ media
} = 'cdrom' if ! $drive ->{ media
} && $vtype eq 'iso' ;
780 verify_media_type
( $opt, $vtype, $drive ->{ media
});
781 $drive ->{ file
} = $volid ;
784 $drive ->{ media
} = 'cdrom' if ! $drive ->{ media
} && $drive ->{ file
} =~ m/^(cdrom|none)$/ ;
787 sub create_conf_nolock
{
788 my ( $vmid, $settings ) = @_ ;
790 my $filename = config_file
( $vmid );
792 die "configuration file ' $filename ' already exists \n " if - f
$filename ;
794 my $defaults = load_defaults
();
796 $settings ->{ name
} = "vm $vmid " if ! $settings ->{ name
};
797 $settings ->{ memory
} = $defaults ->{ memory
} if ! $settings ->{ memory
};
800 foreach my $opt ( keys %$settings ) {
801 next if ! $confdesc ->{ $opt };
803 my $value = $settings ->{ $opt };
806 $data .= " $opt : $value\n " ;
809 PVE
:: Tools
:: file_set_contents
( $filename, $data );
812 # ideX = [volume=]volume-id[,media=d][,cyls=c,heads=h,secs=s[,trans=t]]
813 # [,snapshot=on|off][,cache=on|off][,format=f][,backup=yes|no]
814 # [,aio=native|threads]
817 my ( $key, $data ) = @_ ;
821 # $key may be undefined - used to verify JSON parameters
822 if (! defined ( $key )) {
823 $res ->{ interface
} = 'unknown' ; # should not harm when used to verify parameters
825 } elsif ( $key =~ m/^([^\d]+)(\d+)$/ ) {
826 $res ->{ interface
} = $1 ;
832 foreach my $p ( split ( /,/ , $data )) {
833 next if $p =~ m/^\s*$/ ;
835 if ( $p =~ m/^(file|volume|cyls|heads|secs|trans|media|snapshot|cache|format|rerror|werror|backup|aio)=(.+)$/ ) {
836 my ( $k, $v ) = ( $1, $2 );
838 $k = 'file' if $k eq 'volume' ;
840 return undef if defined $res ->{ $k };
844 if (! $res ->{ file
} && $p !~ m/=/ ) {
852 return undef if ! $res ->{ file
};
854 return undef if $res ->{ cache
} &&
855 $res ->{ cache
} !~ m/^(off|none|writethrough|writeback)$/ ;
856 return undef if $res ->{ snapshot
} && $res ->{ snapshot
} !~ m/^(on|off)$/ ;
857 return undef if $res ->{ cyls
} && $res ->{ cyls
} !~ m/^\d+$/ ;
858 return undef if $res ->{ heads
} && $res ->{ heads
} !~ m/^\d+$/ ;
859 return undef if $res ->{ secs
} && $res ->{ secs
} !~ m/^\d+$/ ;
860 return undef if $res ->{ media
} && $res ->{ media
} !~ m/^(disk|cdrom)$/ ;
861 return undef if $res ->{ trans
} && $res ->{ trans
} !~ m/^(none|lba|auto)$/ ;
862 return undef if $res ->{ format
} && $res ->{ format
} !~ m/^(raw|cow|qcow|qcow2|vmdk|cloop)$/ ;
863 return undef if $res ->{ rerror
} && $res ->{ rerror
} !~ m/^(ignore|report|stop)$/ ;
864 return undef if $res ->{ werror
} && $res ->{ werror
} !~ m/^(enospc|ignore|report|stop)$/ ;
865 return undef if $res ->{ backup
} && $res ->{ backup
} !~ m/^(yes|no)$/ ;
866 return undef if $res ->{ aio
} && $res ->{ aio
} !~ m/^(native|threads)$/ ;
868 if ( $res ->{ media
} && ( $res ->{ media
} eq 'cdrom' )) {
869 return undef if $res ->{ snapshot
} || $res ->{ trans
} || $res ->{ format
};
870 return undef if $res ->{ heads
} || $res ->{ secs
} || $res ->{ cyls
};
871 return undef if $res ->{ interface
} eq 'virtio' ;
874 # rerror does not work with scsi drives
875 if ( $res ->{ rerror
}) {
876 return undef if $res ->{ interface
} eq 'scsi' ;
882 my @qemu_drive_options = qw(heads secs cyls trans media format cache snapshot rerror werror aio) ;
885 my ( $vmid, $drive ) = @_ ;
888 foreach my $o ( @qemu_drive_options, 'backup' ) {
889 $opts .= ", $o = $drive ->{ $o }" if $drive ->{ $o };
892 return " $drive ->{file} $opts " ;
895 sub print_drivedevice_full
{
896 my ( $storecfg, $vmid, $drive ) = @_ ;
901 if ( $drive ->{ interface
} eq 'virtio' ) {
902 my $pciaddr = print_pci_addr
( " $drive ->{interface} $drive ->{index}" );
903 $device = "virtio-blk-pci,drive=drive- $drive ->{interface} $drive ->{index},id= $drive ->{interface} $drive ->{index} $pciaddr " ;
906 elsif ( $drive ->{ interface
} eq 'scsi' ) {
909 my $controller = int ( $drive ->{ index } / $maxdev );
910 my $unit = $drive ->{ index } % $maxdev ;
912 $device = "scsi-disk,bus=scsi $controller .0,scsi-id= $unit,drive =drive- $drive ->{interface} $drive ->{index},id=device- $drive ->{interface} $drive ->{index}" ;
915 elsif ( $drive ->{ interface
} eq 'ide' ){
918 my $controller = int ( $drive ->{ index } / $maxdev );
919 my $unit = $drive ->{ index } % $maxdev ;
921 $device = "ide-drive,bus=ide. $controller,unit = $unit,drive =drive- $drive ->{interface} $drive ->{index},id=device- $drive ->{interface} $drive ->{index}" ;
924 if ( $drive ->{ interface
} eq 'usb' ){
925 # -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
931 sub print_drive_full
{
932 my ( $storecfg, $vmid, $drive ) = @_ ;
935 foreach my $o ( @qemu_drive_options ) {
936 $opts .= ", $o = $drive ->{ $o }" if $drive ->{ $o };
939 # use linux-aio by default (qemu default is threads)
940 $opts .= ",aio=native" if ! $drive ->{ aio
};
943 my $volid = $drive ->{ file
};
944 if ( drive_is_cdrom
( $drive )) {
945 $path = get_iso_path
( $storecfg, $vmid, $volid );
947 if ( $volid =~ m
|^/|) {
950 $path = PVE
:: Storage
:: path
( $storecfg, $volid );
954 my $pathinfo = $path ?
"file= $path, " : '' ;
956 return "${pathinfo}if=none,id=drive- $drive ->{interface} $drive ->{index} $opts " ;
963 return $drive && $drive ->{ media
} && ( $drive ->{ media
} eq 'cdrom' );
970 return undef if ! $value ;
974 if ( $value =~ m/^[a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9]$/ ) {
975 $res ->{ pciid
} = $value ;
983 # netX: e1000=XX:XX:XX:XX:XX:XX,bridge=vmbr0,rate=<mbps>
989 foreach my $kvp ( split ( /,/ , $data )) {
991 if ( $kvp =~ m/^(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i ) {
993 my $mac = uc ( $3 ) || PVE
:: Tools
:: random_ether_addr
();
994 $res ->{ model
} = $model ;
995 $res ->{ macaddr
} = $mac ;
996 } elsif ( $kvp =~ m/^bridge=(\S+)$/ ) {
998 } elsif ( $kvp =~ m/^rate=(\d+(\.\d+)?)$/ ) {
1006 return undef if ! $res ->{ model
};
1014 my $res = " $net ->{model}" ;
1015 $res .= "= $net ->{macaddr}" if $net ->{ macaddr
};
1016 $res .= ",bridge= $net ->{bridge}" if $net ->{ bridge
};
1017 $res .= ",rate= $net ->{rate}" if $net ->{ rate
};
1022 sub add_random_macs
{
1023 my ( $settings ) = @_ ;
1025 foreach my $opt ( keys %$settings ) {
1026 next if $opt !~ m/^net(\d+)$/ ;
1027 my $net = parse_net
( $settings ->{ $opt });
1029 $settings ->{ $opt } = print_net
( $net );
1033 sub add_unused_volume
{
1034 my ( $config, $res, $volid ) = @_ ;
1037 for ( my $ind = $MAX_UNUSED_DISKS - 1 ; $ind >= 0 ; $ind --) {
1038 my $test = "unused $ind " ;
1039 if ( my $vid = $config ->{ $test }) {
1040 return if $vid eq $volid ; # do not add duplicates
1046 die "To many unused volume - please delete them first. \n " if ! $key ;
1048 $res ->{ $key } = $volid ;
1051 # fixme: remove all thos $noerr parameters?
1053 PVE
:: JSONSchema
:: register_format
( 'pve-qm-bootdisk' , \
& verify_bootdisk
);
1054 sub verify_bootdisk
{
1055 my ( $value, $noerr ) = @_ ;
1057 return $value if valid_drivename
( $value );
1059 return undef if $noerr ;
1061 die "invalid boot disk ' $value ' \n " ;
1064 PVE
:: JSONSchema
:: register_format
( 'pve-qm-net' , \
& verify_net
);
1066 my ( $value, $noerr ) = @_ ;
1068 return $value if parse_net
( $value );
1070 return undef if $noerr ;
1072 die "unable to parse network options \n " ;
1075 PVE
:: JSONSchema
:: register_format
( 'pve-qm-drive' , \
& verify_drive
);
1077 my ( $value, $noerr ) = @_ ;
1079 return $value if parse_drive
( undef , $value );
1081 return undef if $noerr ;
1083 die "unable to parse drive options \n " ;
1086 PVE
:: JSONSchema
:: register_format
( 'pve-qm-hostpci' , \
& verify_hostpci
);
1087 sub verify_hostpci
{
1088 my ( $value, $noerr ) = @_ ;
1090 return $value if parse_hostpci
( $value );
1092 return undef if $noerr ;
1094 die "unable to parse pci id \n " ;
1097 PVE
:: JSONSchema
:: register_format
( 'pve-qm-watchdog' , \
& verify_watchdog
);
1098 sub verify_watchdog
{
1099 my ( $value, $noerr ) = @_ ;
1101 return $value if parse_watchdog
( $value );
1103 return undef if $noerr ;
1105 die "unable to parse watchdog options \n " ;
1108 sub parse_watchdog
{
1111 return undef if ! $value ;
1115 foreach my $p ( split ( /,/ , $value )) {
1116 next if $p =~ m/^\s*$/ ;
1118 if ( $p =~ m/^(model=)?(i6300esb|ib700)$/ ) {
1120 } elsif ( $p =~ m/^(action=)?(reset|shutdown|poweroff|pause|debug|none)$/ ) {
1121 $res ->{ action
} = $2 ;
1130 sub parse_usb_device
{
1133 return undef if ! $value ;
1135 my @dl = split ( /,/ , $value );
1139 foreach my $v ( @dl ) {
1140 if ( $v =~ m/^host=([0-9A-Fa-f]{4}):([0-9A-Fa-f]{4})$/ ) {
1142 $res ->{ vendorid
} = $1 ;
1143 $res ->{ productid
} = $2 ;
1144 } elsif ( $v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/ ) {
1146 $res ->{ hostbus
} = $1 ;
1147 $res ->{ hostport
} = $2 ;
1152 return undef if ! $found ;
1157 PVE
:: JSONSchema
:: register_format
( 'pve-qm-usb-device' , \
& verify_usb_device
);
1158 sub verify_usb_device
{
1159 my ( $value, $noerr ) = @_ ;
1161 return $value if parse_usb_device
( $value );
1163 return undef if $noerr ;
1165 die "unable to parse usb device \n " ;
1168 # add JSON properties for create and set function
1169 sub json_config_properties
{
1172 foreach my $opt ( keys %$confdesc ) {
1173 $prop ->{ $opt } = $confdesc ->{ $opt };
1180 my ( $key, $value ) = @_ ;
1182 die "unknown setting ' $key ' \n " if ! $confdesc ->{ $key };
1184 my $type = $confdesc ->{ $key }->{ type
};
1186 if (! defined ( $value )) {
1187 die "got undefined value \n " ;
1190 if ( $value =~ m/[\n\r]/ ) {
1191 die "property contains a line feed \n " ;
1194 if ( $type eq 'boolean' ) {
1195 return 1 if ( $value eq '1' ) || ( $value =~ m/^(on|yes|true)$/i );
1196 return 0 if ( $value eq '0' ) || ( $value =~ m/^(off|no|false)$/i );
1197 die "type check ('boolean') failed - got ' $value ' \n " ;
1198 } elsif ( $type eq 'integer' ) {
1199 return int ( $1 ) if $value =~ m/^(\d+)$/ ;
1200 die "type check ('integer') failed - got ' $value ' \n " ;
1201 } elsif ( $type eq 'string' ) {
1202 if ( my $fmt = $confdesc ->{ $key }->{ format
}) {
1203 if ( $fmt eq 'pve-qm-drive' ) {
1204 # special case - we need to pass $key to parse_drive()
1205 my $drive = parse_drive
( $key, $value );
1206 return $value if $drive ;
1207 die "unable to parse drive options \n " ;
1209 PVE
:: JSONSchema
:: check_format
( $fmt, $value );
1212 $value =~ s/^\"(.*)\"$/$1/ ;
1215 die "internal error"
1220 my ( $vmid, $code, @param ) = @_ ;
1222 my $filename = config_file_lock
( $vmid );
1224 my $res = lock_file
( $filename, 10 , $code, @param );
1231 sub cfs_config_path
{
1232 my ( $vmid, $node ) = @_ ;
1234 $node = $nodename if ! $node ;
1235 return "nodes/ $node/qemu -server/ $vmid .conf" ;
1238 sub check_iommu_support
{
1239 #fixme : need to check IOMMU support
1240 #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM
1248 my ( $vmid, $node ) = @_ ;
1250 my $cfspath = cfs_config_path
( $vmid, $node );
1251 return "/etc/pve/ $cfspath " ;
1254 sub config_file_lock
{
1257 return " $lock_dir/lock - $vmid .conf" ;
1263 my $conf = config_file
( $vmid );
1264 utime undef , undef , $conf ;
1268 my ( $storecfg, $vmid, $settings ) = @_ ;
1273 foreach_drive
( $settings, sub {
1274 my ( $ds, $disk ) = @_ ;
1276 return if drive_is_cdrom
( $disk );
1278 my $file = $disk ->{ file
};
1280 if ( $file =~ m/^(([^:\s]+):)?(\d+(\.\d+)?)$/ ) {
1281 my $storeid = $2 || 'local' ;
1283 my $defformat = PVE
:: Storage
:: storage_default_format
( $storecfg, $storeid );
1284 my $fmt = $disk ->{ format
} || $defformat ;
1285 syslog
( 'info' , "VM $vmid creating new disk - size is $size GB" );
1287 my $volid = PVE
:: Storage
:: vdisk_alloc
( $storecfg, $storeid, $vmid,
1288 $fmt, undef , $size*1024*1024 );
1290 $disk ->{ file
} = $volid ;
1291 delete $disk ->{ format
}; # no longer needed
1292 push @$vollist, $volid ;
1293 $settings ->{ $ds } = PVE
:: QemuServer
:: print_drive
( $vmid, $disk );
1296 if ( $disk ->{ file
} =~ m
|^ /dev/ .+|) {
1297 $path = $disk ->{ file
};
1299 $path = PVE
:: Storage
:: path
( $storecfg, $disk ->{ file
});
1301 if (!(- f
$path || - b
$path )) {
1302 die "image ' $path ' does not exists \n " ;
1305 PVE
:: QemuServer
:: vm_deviceadd
( $storecfg,$vmid,$ds, $disk );
1312 syslog
( 'err' , "VM $vmid creating disks failed" );
1313 foreach my $volid ( @$vollist ) {
1314 eval { PVE
:: Storage
:: vdisk_free
( $storecfg, $volid ); };
1324 my ( $storecfg, $vmid, $volid ) = @_ ;
1326 die "reject to unlink absolute path ' $volid '"
1329 my ( $path, $owner ) = PVE
:: Storage
:: path
( $storecfg, $volid );
1331 die "reject to unlink ' $volid ' - not owned by this VM"
1332 if ! $owner || ( $owner != $vmid );
1334 syslog
( 'info' , "VM $vmid deleting volume ' $volid '" );
1336 PVE
:: Storage
:: vdisk_free
( $storecfg, $volid );
1338 touch_config
( $vmid );
1342 my ( $storecfg, $vmid ) = @_ ;
1344 my $conffile = config_file
( $vmid );
1346 my $conf = load_config
( $vmid );
1350 # only remove disks owned by this VM
1351 foreach_drive
( $conf, sub {
1352 my ( $ds, $drive ) = @_ ;
1354 return if drive_is_cdrom
( $drive );
1356 my $volid = $drive ->{ file
};
1357 next if ! $volid || $volid =~ m
|^/|;
1359 my ( $path, $owner ) = PVE
:: Storage
:: path
( $storecfg, $volid );
1360 next if ! $path || ! $owner || ( $owner != $vmid );
1362 PVE
:: Storage
:: vdisk_free
( $storecfg, $volid );
1367 # also remove unused disk
1369 my $dl = PVE
:: Storage
:: vdisk_list
( $storecfg, undef , $vmid );
1372 PVE
:: Storage
:: foreach_volid
( $dl, sub {
1373 my ( $volid, $sid, $volname, $d ) = @_ ;
1374 PVE
:: Storage
:: vdisk_free
( $storecfg, $volid );
1384 sub load_diskinfo_old
{
1385 my ( $storecfg, $vmid, $conf ) = @_ ;
1391 foreach_drive
( $conf, sub {
1396 return if drive_is_cdrom
( $di );
1398 if ( $di ->{ file
} =~ m
|^ /dev/ .+|) {
1399 $info ->{ $di ->{ file
}}->{ size
} = PVE
:: Storage
:: file_size_info
( $di ->{ file
});
1401 push @$vollist, $di ->{ file
};
1406 my $dl = PVE
:: Storage
:: vdisk_list
( $storecfg, undef , $vmid, $vollist );
1408 PVE
:: Storage
:: foreach_volid
( $dl, sub {
1409 my ( $volid, $sid, $volname, $d ) = @_ ;
1410 $info ->{ $volid } = $d ;
1415 foreach my $ds ( keys %$res ) {
1416 my $di = $res ->{ $ds };
1418 $res ->{ $ds }->{ disksize
} = $info ->{ $di ->{ file
}} ?
1419 $info ->{ $di ->{ file
}}->{ size
} / ( 1024 * 1024 ) : 0 ;
1428 my $cfspath = cfs_config_path
( $vmid );
1430 my $conf = PVE
:: Cluster
:: cfs_read_file
( $cfspath );
1432 die "no such VM (' $vmid ') \n " if ! defined ( $conf );
1437 sub parse_vm_config
{
1438 my ( $filename, $raw ) = @_ ;
1440 return undef if ! defined ( $raw );
1443 digest
=> Digest
:: SHA1
:: sha1_hex
( $raw ),
1446 $filename =~ m
| /qemu-server/ ( \d
+) \
. conf
$|
1447 || die "got strange filename ' $filename '" ;
1451 while ( $raw && $raw =~ s/^(.*?)(\n|$)// ) {
1454 next if $line =~ m/^\#/ ;
1456 next if $line =~ m/^\s*$/ ;
1458 if ( $line =~ m/^(description):\s*(.*\S)\s*$/ ) {
1460 my $value = PVE
:: Tools
:: decode_text
( $2 );
1461 $res ->{ $key } = $value ;
1462 } elsif ( $line =~ m/^(args):\s*(.*\S)\s*$/ ) {
1465 $res ->{ $key } = $value ;
1466 } elsif ( $line =~ m/^([a-z][a-z_]*\d*):\s*(\S+)\s*$/ ) {
1469 eval { $value = check_type
( $key, $value ); };
1471 warn "vm $vmid - unable to parse value of ' $key ' - $@ " ;
1473 my $fmt = $confdesc ->{ $key }->{ format
};
1474 if ( $fmt && $fmt eq 'pve-qm-drive' ) {
1475 my $v = parse_drive
( $key, $value );
1476 if ( my $volid = filename_to_volume_id
( $vmid, $v ->{ file
}, $v ->{ media
})) {
1477 $v ->{ file
} = $volid ;
1478 $value = print_drive
( $vmid, $v );
1480 warn "vm $vmid - unable to parse value of ' $key ' \n " ;
1485 if ( $key eq 'cdrom' ) {
1486 $res ->{ ide2
} = $value ;
1488 $res ->{ $key } = $value ;
1494 # convert old smp to sockets
1495 if ( $res ->{ smp
} && ! $res ->{ sockets
}) {
1496 $res ->{ sockets
} = $res ->{ smp
};
1504 my ( $vmid, $settings, $unset, $skiplock ) = @_ ;
1506 lock_config
( $vmid, & change_config_nolock
, $settings, $unset, $skiplock );
1509 sub change_config_nolock
{
1510 my ( $vmid, $settings, $unset, $skiplock ) = @_ ;
1514 $unset ->{ ide2
} = $unset ->{ cdrom
} if $unset ->{ cdrom
};
1516 check_lock
( $settings ) if ! $skiplock ;
1518 # we do not use 'smp' any longer
1519 if ( $settings ->{ sockets
}) {
1521 } elsif ( $settings ->{ smp
}) {
1522 $settings ->{ sockets
} = $settings ->{ smp
};
1526 my $new_volids = {};
1528 foreach my $key ( keys %$settings ) {
1529 next if $key eq 'digest' ;
1530 my $value = $settings ->{ $key };
1531 if ( $key eq 'description' ) {
1532 $value = PVE
:: Tools
:: encode_text
( $value );
1534 eval { $value = check_type
( $key, $value ); };
1535 die "unable to parse value of ' $key ' - $@ " if $@ ;
1536 if ( $key eq 'cdrom' ) {
1537 $res ->{ ide2
} = $value ;
1539 $res ->{ $key } = $value ;
1541 if ( valid_drivename
( $key )) {
1542 my $drive = PVE
:: QemuServer
:: parse_drive
( $key, $value );
1543 $new_volids ->{ $drive ->{ file
}} = 1 if $drive && $drive ->{ file
};
1547 my $filename = config_file
( $vmid );
1548 my $tmpfn = " $filename . $$ .tmp" ;
1550 my $fh = new IO
:: File
( $filename, "r" ) ||
1551 die "unable to read config for VM $vmid\n " ;
1553 my $werror = "unable to write config for VM $vmid\n " ;
1555 my $out = new IO
:: File
( $tmpfn, "w" ) || die $werror ;
1561 while ( my $line = < $fh >) {
1563 if (( $line =~ m/^\#/ ) || ( $line =~ m/^\s*$/ )) {
1564 die $werror unless print $out $line ;
1568 if ( $line =~ m/^([a-z][a-z_]*\d*):\s*(.*\S)\s*$/ ) {
1572 # remove 'unusedX' settings if we re-add a volume
1573 next if $key =~ m/^unused/ && $new_volids ->{ $value };
1575 # convert 'smp' to 'sockets'
1576 $key = 'sockets' if $key eq 'smp' ;
1578 next if $done ->{ $key };
1581 if ( defined ( $res ->{ $key })) {
1582 $value = $res ->{ $key };
1583 delete $res ->{ $key };
1585 if (! defined ( $unset ->{ $key })) {
1586 die $werror unless print $out " $key : $value\n " ;
1592 die "unable to parse config file: $line\n " ;
1595 foreach my $key ( keys %$res ) {
1597 if (! defined ( $unset ->{ $key })) {
1598 die $werror unless print $out " $key : $res ->{ $key } \n " ;
1613 if (! $out -> close ()) {
1614 $err = "close failed - $!\n " ;
1619 if (! rename ( $tmpfn, $filename )) {
1620 $err = "rename failed - $!\n " ;
1630 # we use static defaults from our JSON schema configuration
1631 foreach my $key ( keys %$confdesc ) {
1632 if ( defined ( my $default = $confdesc ->{ $key }->{ default })) {
1633 $res ->{ $key } = $default ;
1637 my $conf = PVE
:: Cluster
:: cfs_read_file
( 'datacenter.cfg' );
1638 $res ->{ keyboard
} = $conf ->{ keyboard
} if $conf ->{ keyboard
};
1644 my $vmlist = PVE
:: Cluster
:: get_vmlist
();
1646 return $res if ! $vmlist || ! $vmlist ->{ ids
};
1647 my $ids = $vmlist ->{ ids
};
1649 foreach my $vmid ( keys %$ids ) {
1650 my $d = $ids ->{ $vmid };
1651 next if ! $d ->{ node
} || $d ->{ node
} ne $nodename ;
1652 next if ! $d ->{ type
} || $d ->{ type
} ne 'qemu' ;
1653 $res ->{ $vmid }->{ exists } = 1 ;
1658 # test if VM uses local resources (to prevent migration)
1659 sub check_local_resources
{
1660 my ( $conf, $noerr ) = @_ ;
1664 $loc_res = 1 if $conf ->{ hostusb
}; # old syntax
1665 $loc_res = 1 if $conf ->{ hostpci
}; # old syntax
1667 foreach my $k ( keys %$conf ) {
1668 $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/ ;
1671 die "VM uses local resources \n " if $loc_res && ! $noerr ;
1679 die "VM is locked ( $conf ->{lock}) \n " if $conf ->{ lock };
1683 my ( $pidfile, $pid ) = @_ ;
1685 my $fh = IO
:: File-
> new ( "/proc/ $pid/cmdline " , "r" );
1689 return undef if ! $line ;
1690 my @param = split ( /\0/ , $line );
1692 my $cmd = $param [ 0 ];
1693 return if ! $cmd || ( $cmd !~ m
| kvm
$|);
1695 for ( my $i = 0 ; $i < scalar ( @param ); $i++ ) {
1698 if (( $p eq '-pidfile' ) || ( $p eq '--pidfile' )) {
1699 my $p = $param [ $i+1 ];
1700 return 1 if $p && ( $p eq $pidfile );
1709 my ( $vmid, $nocheck ) = @_ ;
1711 my $filename = config_file
( $vmid );
1713 die "unable to find configuration file for VM $vmid - no such machine \n "
1714 if ! $nocheck && ! - f
$filename ;
1716 my $pidfile = pidfile_name
( $vmid );
1718 if ( my $fd = IO
:: File-
> new ( "< $pidfile " )) {
1723 my $mtime = $st -> mtime ;
1724 if ( $mtime > time ()) {
1725 warn "file ' $filename ' modified in future \n " ;
1728 if ( $line =~ m/^(\d+)$/ ) {
1730 if ( check_cmdline
( $pidfile, $pid )) {
1731 if ( my $pinfo = PVE
:: ProcFSTools
:: check_process_running
( $pid )) {
1743 my $vzlist = config_list
();
1745 my $fd = IO
:: Dir-
> new ( $var_run_tmpdir ) || return $vzlist ;
1747 while ( defined ( my $de = $fd -> read )) {
1748 next if $de !~ m/^(\d+)\.pid$/ ;
1750 next if ! defined ( $vzlist ->{ $vmid });
1751 if ( my $pid = check_running
( $vmid )) {
1752 $vzlist ->{ $vmid }->{ pid
} = $pid ;
1759 my $storage_timeout_hash = {};
1762 my ( $storecfg, $conf ) = @_ ;
1764 my $bootdisk = $conf ->{ bootdisk
};
1765 return undef if ! $bootdisk ;
1766 return undef if ! valid_drivename
( $bootdisk );
1768 return undef if ! $conf ->{ $bootdisk };
1770 my $drive = parse_drive
( $bootdisk, $conf ->{ $bootdisk });
1771 return undef if ! defined ( $drive );
1773 return undef if drive_is_cdrom
( $drive );
1775 my $volid = $drive ->{ file
};
1776 return undef if ! $volid ;
1782 if ( $volid =~ m
|^/|) {
1783 $path = $timeoutid = $volid ;
1785 $storeid = $timeoutid = PVE
:: Storage
:: parse_volume_id
( $volid );
1786 $path = PVE
:: Storage
:: path
( $storecfg, $volid );
1789 my $last_timeout = $storage_timeout_hash ->{ $timeoutid };
1790 if ( $last_timeout ) {
1791 if (( time () - $last_timeout ) < 30 ) {
1792 # skip storage with errors
1795 delete $storage_timeout_hash ->{ $timeoutid };
1798 my ( $size, $format, $used );
1800 ( $size, $format, $used ) = PVE
:: Storage
:: file_size_info
( $path, 1 );
1802 if (! defined ( $format )) {
1804 $storage_timeout_hash ->{ $timeoutid } = time ();
1808 return wantarray ?
( $size, $used ) : $size ;
1811 my $last_proc_pid_stat ;
1814 my ( $opt_vmid ) = @_ ;
1818 my $storecfg = PVE
:: Storage
:: config
();
1820 my $list = vzlist
();
1821 my ( $uptime ) = PVE
:: ProcFSTools
:: read_proc_uptime
( 1 );
1823 foreach my $vmid ( keys %$list ) {
1824 next if $opt_vmid && ( $vmid ne $opt_vmid );
1826 my $cfspath = cfs_config_path
( $vmid );
1827 my $conf = PVE
:: Cluster
:: cfs_read_file
( $cfspath ) || {};
1830 $d ->{ pid
} = $list ->{ $vmid }->{ pid
};
1832 # fixme: better status?
1833 $d ->{ status
} = $list ->{ $vmid }->{ pid
} ?
'running' : 'stopped' ;
1835 my ( $size, $used ) = disksize
( $storecfg, $conf );
1836 if ( defined ( $size ) && defined ( $used )) {
1838 $d ->{ maxdisk
} = $size ;
1844 $d ->{ cpus
} = ( $conf ->{ sockets
} || 1 ) * ( $conf ->{ cores
} || 1 );
1845 $d ->{ name
} = $conf ->{ name
} || "VM $vmid " ;
1846 $d ->{ maxmem
} = $conf ->{ memory
} ?
$conf ->{ memory
}*( 1024 * 1024 ) : 0 ;
1857 $d ->{ diskwrite
} = 0 ;
1862 my $netdev = PVE
:: ProcFSTools
:: read_proc_net_dev
();
1863 foreach my $dev ( keys %$netdev ) {
1864 next if $dev !~ m/^tap([1-9]\d*)i/ ;
1866 my $d = $res ->{ $vmid };
1869 $d ->{ netout
} += $netdev ->{ $dev }->{ receive
};
1870 $d ->{ netin
} += $netdev ->{ $dev }->{ transmit
};
1873 my $cpucount = $cpuinfo ->{ cpus
} || 1 ;
1874 my $ctime = gettimeofday
;
1876 foreach my $vmid ( keys %$list ) {
1878 my $d = $res ->{ $vmid };
1879 my $pid = $d ->{ pid
};
1882 if ( my $fh = IO
:: File-
> new ( "/proc/ $pid/io " , "r" )) {
1884 while ( defined ( my $line = < $fh >)) {
1885 if ( $line =~ m/^([rw]char):\s+(\d+)$/ ) {
1890 $d ->{ diskread
} = $data ->{ rchar
} || 0 ;
1891 $d ->{ diskwrite
} = $data ->{ wchar
} || 0 ;
1894 my $pstat = PVE
:: ProcFSTools
:: read_proc_pid_stat
( $pid );
1895 next if ! $pstat ; # not running
1897 my $used = $pstat ->{ utime } + $pstat ->{ stime
};
1899 my $vcpus = $d ->{ cpus
} > $cpucount ?
$cpucount : $d ->{ cpus
};
1901 $d ->{ uptime
} = int (( $uptime - $pstat ->{ starttime
})/ $cpuinfo ->{ user_hz
});
1903 if ( $pstat ->{ vsize
}) {
1904 $d ->{ mem
} = int (( $pstat ->{ rss
}/ $pstat ->{ vsize
})* $d ->{ maxmem
});
1907 my $old = $last_proc_pid_stat ->{ $pid };
1909 $last_proc_pid_stat ->{ $pid } = {
1918 my $dtime = ( $ctime - $old ->{ time }) * $cpucount * $cpuinfo ->{ user_hz
};
1920 if ( $dtime > 1000 ) {
1921 my $dutime = $used - $old ->{ used
};
1923 $d ->{ cpu
} = $dutime/$dtime ;
1924 $d ->{ relcpu
} = ( $d ->{ cpu
} * $cpucount ) / $vcpus ;
1925 $last_proc_pid_stat ->{ $pid } = {
1929 relcpu
=> $d ->{ relcpu
},
1932 $d ->{ cpu
} = $old ->{ cpu
};
1933 $d ->{ relcpu
} = $old ->{ relcpu
};
1941 my ( $conf, $func ) = @_ ;
1943 foreach my $ds ( keys %$conf ) {
1944 next if ! valid_drivename
( $ds );
1946 my $drive = parse_drive
( $ds, $conf ->{ $ds });
1949 & $func ( $ds, $drive );
1953 sub config_to_command
{
1954 my ( $storecfg, $vmid, $conf, $defaults, $migrate_uri ) = @_ ;
1958 my $kvmver = kvm_user_version
();
1959 my $vernum = 0 ; # unknown
1960 if ( $kvmver =~ m/^(\d+)\.(\d+)\.(\d+)$/ ) {
1961 $vernum = $1*1000000+$2*1000+$3 ;
1964 die "detected old qemu-kvm binary ( $kvmver ) \n " if $vernum < 14000 ;
1966 my $have_ovz = - f
'/proc/vz/vestat' ;
1968 push @$cmd, '/usr/bin/kvm' ;
1970 push @$cmd, '-id' , $vmid ;
1974 my $socket = monitor_socket
( $vmid );
1975 push @$cmd, '-chardev' , "socket,id=monitor,path= $socket,server,nowait " ;
1976 push @$cmd, '-mon' , "chardev=monitor,mode=readline" ;
1978 $socket = vnc_socket
( $vmid );
1979 push @$cmd, '-vnc' , "unix: $socket,x509,password " ;
1981 push @$cmd, '-pidfile' , pidfile_name
( $vmid );
1983 push @$cmd, '-daemonize' ;
1985 push @$cmd, '-incoming' , $migrate_uri if $migrate_uri ;
1987 # include usb device config
1988 push @$cmd, '-readconfig' , '/usr/share/qemu-server/pve-usb.cfg' ;
1990 # enable absolute mouse coordinates (needed by vnc)
1991 my $tablet = defined ( $conf ->{ tablet
}) ?
$conf ->{ tablet
} : $defaults ->{ tablet
};
1992 push @$cmd, '-device' , 'usb-tablet,bus=ehci.0,port=6' if $tablet ;
1995 for ( my $i = 0 ; $i < $MAX_HOSTPCI_DEVICES ; $i++ ) {
1996 my $d = parse_hostpci
( $conf ->{ "hostpci $i " });
1998 $pciaddr = print_pci_addr
( "hostpci $i " );
1999 push @$cmd, '-device' , "pci-assign,host= $d ->{pciid},id=hostpci $i$pciaddr " ;
2003 for ( my $i = 0 ; $i < $MAX_USB_DEVICES ; $i++ ) {
2004 my $d = parse_usb_device
( $conf ->{ "usb $i " });
2006 if ( $d ->{ vendorid
} && $d ->{ productid
}) {
2007 push @$cmd, '-device' , "usb-host,vendorid= $d ->{vendorid},productid= $d ->{productid}" ;
2008 } elsif ( defined ( $d ->{ hostbus
}) && defined ( $d ->{ hostport
})) {
2009 push @$cmd, '-device' , "usb-host,hostbus= $d ->{hostbus},hostport= $d ->{hostport}" ;
2014 for ( my $i = 0 ; $i < $MAX_SERIAL_PORTS ; $i++ ) {
2015 if ( my $path = $conf ->{ "serial $i " }) {
2016 die "no such serial device \n " if ! - c
$path ;
2017 push @$cmd, '-chardev' , "tty,id=serial $i,path = $path " ;
2018 push @$cmd, '-device' , "isa-serial,chardev=serial $i " ;
2023 for ( my $i = 0 ; $i < $MAX_PARALLEL_PORTS ; $i++ ) {
2024 if ( my $path = $conf ->{ "parallel $i " }) {
2025 die "no such parallel device \n " if ! - c
$path ;
2026 push @$cmd, '-chardev' , "parport,id=parallel $i,path = $path " ;
2027 push @$cmd, '-device' , "isa-parallel,chardev=parallel $i " ;
2031 my $vmname = $conf ->{ name
} || "vm $vmid " ;
2033 push @$cmd, '-name' , $vmname ;
2036 $sockets = $conf ->{ smp
} if $conf ->{ smp
}; # old style - no longer iused
2037 $sockets = $conf ->{ sockets
} if $conf ->{ sockets
};
2039 my $cores = $conf ->{ cores
} || 1 ;
2043 push @$cmd, '-smp' , "sockets= $sockets,cores = $cores " ;
2045 push @$cmd, '-cpu' , $conf ->{ cpu
} if $conf ->{ cpu
};
2047 push @$cmd, '-nodefaults' ;
2049 my $bootorder = $conf ->{ boot
} || $confdesc ->{ boot
}->{ default };
2050 push @$cmd, '-boot' , "menu=on,order= $bootorder " ;
2052 push @$cmd, '-no-acpi' if defined ( $conf ->{ acpi
}) && $conf ->{ acpi
} == 0 ;
2054 push @$cmd, '-no-reboot' if defined ( $conf ->{ reboot
}) && $conf ->{ reboot
} == 0 ;
2056 my $vga = $conf ->{ vga
};
2058 if ( $conf ->{ ostype
} && ( $conf ->{ ostype
} eq 'win7' || $conf ->{ ostype
} eq 'w2k8' )) {
2065 push @$cmd, '-vga' , $vga if $vga ; # for kvm 77 and later
2068 my $tdf = defined ( $conf ->{ tdf
}) ?
$conf ->{ tdf
} : $defaults ->{ tdf
};
2069 push @$cmd, '-tdf' if $tdf ;
2071 my $nokvm = defined ( $conf ->{ kvm
}) && $conf ->{ kvm
} == 0 ?
1 : 0 ;
2073 if ( my $ost = $conf ->{ ostype
}) {
2074 # other, wxp, w2k, w2k3, w2k8, wvista, win7, l24, l26
2076 if ( $ost =~ m/^w/ ) { # windows
2077 push @$cmd, '-localtime' if ! defined ( $conf ->{ localtime });
2079 # use rtc-td-hack when acpi is enabled
2080 if (!( defined ( $conf ->{ acpi
}) && $conf ->{ acpi
} == 0 )) {
2081 push @$cmd, '-rtc-td-hack' ;
2092 push @$cmd, '-no-kvm' ;
2094 die "No accelerator found! \n " if ! $cpuinfo ->{ hvm
};
2097 push @$cmd, '-localtime' if $conf ->{ localtime };
2099 push @$cmd, '-startdate' , $conf ->{ startdate
} if $conf ->{ startdate
};
2101 push @$cmd, '-S' if $conf ->{ freeze
};
2103 # set keyboard layout
2104 my $kb = $conf ->{ keyboard
} || $defaults ->{ keyboard
};
2105 push @$cmd, '-k' , $kb if $kb ;
2108 #my $soundhw = $conf->{soundhw} || $defaults->{soundhw};
2109 #push @$cmd, '-soundhw', 'es1370';
2110 #push @$cmd, '-soundhw', $soundhw if $soundhw;
2111 $pciaddr = print_pci_addr
( "balloon0" );
2112 push @$cmd, '-device' , "virtio-balloon-pci,id=balloon0 $pciaddr " if $conf ->{ balloon
};
2114 if ( $conf ->{ watchdog
}) {
2115 my $wdopts = parse_watchdog
( $conf ->{ watchdog
});
2116 $pciaddr = print_pci_addr
( "watchdog" );
2117 my $watchdog = $wdopts ->{ model
} || 'i6300esb' ;
2118 push @$cmd, '-device' , " $watchdog$pciaddr " ;
2119 push @$cmd, '-watchdog-action' , $wdopts ->{ action
} if $wdopts ->{ action
};
2123 my $scsicontroller = {};
2125 foreach_drive
( $conf, sub {
2126 my ( $ds, $drive ) = @_ ;
2129 PVE
:: Storage
:: parse_volume_id
( $drive ->{ file
});
2130 push @$vollist, $drive ->{ file
};
2133 $use_virtio = 1 if $ds =~ m/^virtio/ ;
2134 if ( $drive ->{ interface
} eq 'scsi' ) {
2136 my $controller = int ( $drive ->{ index } / $maxdev );
2137 $pciaddr = print_pci_addr
( "scsi $controller " );
2138 push @$cmd, '-device' , "lsi,id=scsi $controller$pciaddr " if ! $scsicontroller ->{ $controller };
2139 my $scsicontroller ->{ $controller }= 1 ;
2141 my $tmp = print_drive_full
( $storecfg, $vmid, $drive );
2142 $tmp .= ",boot=on" if $conf ->{ bootdisk
} && ( $conf ->{ bootdisk
} eq $ds );
2143 push @$cmd, '-drive' , $tmp ;
2144 push @$cmd, '-device' , print_drivedevice_full
( $storecfg,$vmid, $drive );
2147 push @$cmd, '-m' , $conf ->{ memory
} || $defaults ->{ memory
};
2151 foreach my $k ( sort keys %$conf ) {
2152 next if $k !~ m/^net(\d+)$/ ;
2155 die "got strange net id ' $i ' \n " if $i >= ${ MAX_NETS
};
2157 if ( $conf ->{ "net $i " } && ( my $net = parse_net
( $conf ->{ "net $i " }))) {
2161 my $ifname = "tap${vmid}i $i " ;
2163 # kvm uses TUNSETIFF ioctl, and that limits ifname length
2164 die "interface name ' $ifname ' is too long (max 15 character) \n "
2165 if length ( $ifname ) >= 16 ;
2167 my $device = $net ->{ model
};
2168 my $vhostparam = '' ;
2169 if ( $net ->{ model
} eq 'virtio' ) {
2171 $device = 'virtio-net-pci' ;
2172 $vhostparam = ',vhost=on' if $kernel_has_vhost_net ;
2175 if ( $net ->{ bridge
}) {
2176 push @$cmd, '-netdev' , "type=tap,id=${k},ifname=${ifname},script=/var/lib/qemu-server/pve-bridge $vhostparam " ;
2178 push @$cmd, '-netdev' , "type=user,id=${k},hostname= $vmname " ;
2181 # qemu > 0.15 always try to boot from network - we disable that by
2182 # not loading the pxe rom file
2183 my $extra = (! $conf ->{ boot
} || ( $conf ->{ boot
} !~ m/n/ )) ?
2185 $pciaddr = print_pci_addr
( "${k}" );
2186 push @$cmd, '-device' , " $device,$ {extra}mac= $net ->{macaddr},netdev=${k} $pciaddr " ;
2190 push @$cmd, '-net' , 'none' if ! $foundnet ;
2192 # hack: virtio with fairsched is unreliable, so we do not use fairsched
2193 # when the VM uses virtio devices.
2194 if (! $use_virtio && $have_ovz ) {
2196 my $cpuunits = defined ( $conf ->{ cpuunits
}) ?
2197 $conf ->{ cpuunits
} : $defaults ->{ cpuunits
};
2199 push @$cmd, '-cpuunits' , $cpuunits if $cpuunits ;
2201 # fixme: cpulimit is currently ignored
2202 #push @$cmd, '-cpulimit', $conf->{cpulimit} if $conf->{cpulimit};
2206 if ( $conf ->{ args
}) {
2207 my $aa = split_args
( $conf ->{ args
});
2211 return wantarray ?
( $cmd, $vollist ) : $cmd ;
2216 return "${var_run_tmpdir}/ $vmid .vnc" ;
2219 sub monitor_socket
{
2221 return "${var_run_tmpdir}/ $vmid .mon" ;
2226 return "${var_run_tmpdir}/ $vmid .pid" ;
2229 sub next_migrate_port
{
2231 for ( my $p = 60000 ; $p < 60010 ; $p++ ) {
2233 my $sock = IO
:: Socket
:: INET-
> new ( Listen
=> 5 ,
2234 LocalAddr
=> 'localhost' ,
2245 die "unable to find free migration port" ;
2248 sub vm_devices_list
{
2251 my $res = vm_monitor_command
( $vmid, "info pci" , 1 );
2253 my @lines = split ( " \n " , $res );
2258 foreach my $line ( @lines ) {
2260 if ( $line =~ m/^Bus (\d+), device (\d+), function (\d+):$/ ) {
2264 if ( $line =~ m/^id "([a-z][a-z_\-]*\d*)"$/ ) {
2266 $devices ->{ $id }->{ bus
}= $bus ;
2267 $devices ->{ $id }->{ addr
}= $addr ;
2275 my ( $storecfg,$vmid, $deviceid,$device ) = @_ ;
2277 my $cfspath = cfs_config_path
( $vmid );
2278 my $conf = PVE
:: Cluster
:: cfs_read_file
( $cfspath ) || {};
2280 return if ! check_running
( $vmid ) || $conf ->{ hotplug
} != 1 ; # do nothing if vm is running or hotplug option not set to 1
2282 if ( $deviceid =~ m/^(virtio)(\d+)$/ ) {
2284 my $drive = print_drive_full
( $storecfg,$vmid, $device );
2285 vm_monitor_command
( $vmid, "drive_add auto $drive " , 1 );
2286 my $devicefull = print_drivedevice_full
( $storecfg,$vmid, $device );
2287 vm_monitor_command
( $vmid, "device_add $devicefull " , 1 );
2291 sleep 2 ; #give a litlle time to os to add the device
2292 my $devices_list = vm_devices_list
( $vmid );
2293 die "error on hotplug device" if (! defined ( $devices_list ->{ $deviceid }));
2298 my ( $vmid,$deviceid ) = @_ ;
2300 my $cfspath = cfs_config_path
( $vmid );
2301 my $conf = PVE
:: Cluster
:: cfs_read_file
( $cfspath ) || {};
2303 return if ! check_running
( $vmid ) || $conf ->{ hotplug
} != 1 ;
2305 if ( $deviceid =~ m/^(virtio)(\d+)$/ ){
2307 vm_monitor_command
( $vmid, "drive_del drive- $deviceid " , 1 );
2308 vm_monitor_command
( $vmid, "device_del $deviceid " , 1 );
2313 my $devices_list = vm_devices_list
( $vmid );
2314 die "error on hot-unplugging device " if ( defined $devices_list ->{ $deviceid });
2318 my ( $storecfg, $vmid, $statefile, $skiplock ) = @_ ;
2320 lock_config
( $vmid, sub {
2321 my $conf = load_config
( $vmid );
2323 check_lock
( $conf ) if ! $skiplock ;
2325 if ( check_running
( $vmid )) {
2326 my $msg = "VM $vmid already running - start failed \n " ;
2327 syslog
( 'err' , $msg );
2330 syslog
( 'info' , "VM $vmid start" );
2334 my $migrate_port = 0 ;
2337 if ( $statefile eq 'tcp' ) {
2338 $migrate_port = next_migrate_port
();
2339 $migrate_uri = "tcp:localhost:${migrate_port}" ;
2341 if (- f
$statefile ) {
2342 $migrate_uri = "exec:cat $statefile " ;
2344 warn "state file ' $statefile ' does not exist - doing normal startup \n " ;
2349 my $defaults = load_defaults
();
2351 my ( $cmd, $vollist ) = config_to_command
( $storecfg, $vmid, $conf, $defaults, $migrate_uri );
2353 for ( my $i = 0 ; $i < $MAX_HOSTPCI_DEVICES ; $i++ ) {
2354 my $d = parse_hostpci
( $conf ->{ "hostpci $i " });
2356 my $info = pci_device_info
( "0000: $d ->{pciid}" );
2357 die "IOMMU not present \n " if ! check_iommu_support
();
2358 die "no pci device info for device ' $d ->{pciid}' \n " if ! $info ;
2359 die "can't unbind pci device ' $d ->{pciid}' \n " if ! pci_dev_bind_to_stub
( $info );
2360 die "can't reset pci device ' $d ->{pciid}' \n " if ! pci_dev_reset
( $info );
2363 PVE
:: Storage
:: activate_volumes
( $storecfg, $vollist );
2365 eval { run_command
( $cmd, timeout
=> $migrate_uri ?
undef : 30 ); };
2370 my $msg = "start failed: $err " ;
2371 syslog
( 'err' , "VM $vmid $msg " );
2377 if ( $statefile eq 'tcp' ) {
2378 print "migration listens on port $migrate_port\n " ;
2381 # fixme: send resume - is that necessary ?
2382 eval { vm_monitor_command
( $vmid, "cont" , 1 ) };
2386 if ( my $migrate_speed =
2387 $conf ->{ migrate_speed
} || $defaults ->{ migrate_speed
}) {
2388 my $cmd = "migrate_set_speed ${migrate_speed}m" ;
2389 eval { vm_monitor_command
( $vmid, $cmd, 1 ); };
2392 if ( my $migrate_downtime =
2393 $conf ->{ migrate_downtime
} || $defaults ->{ migrate_downtime
}) {
2394 my $cmd = "migrate_set_downtime ${migrate_downtime}" ;
2395 eval { vm_monitor_command
( $vmid, $cmd, 1 ); };
2398 vm_balloonset
( $vmid, $conf ->{ balloon
}) if $conf ->{ balloon
};
2403 my ( $fh, $timeout ) = @_ ;
2405 my $sel = new IO
:: Select
;
2412 while ( scalar ( @ready = $sel -> can_read ( $timeout ))) {
2414 if ( $count = $fh -> sysread ( $buf, 8192 )) {
2415 if ( $buf =~ /^(.*)\(qemu\) $/s ) {
2422 if (! defined ( $count )) {
2429 die "monitor read timeout \n " if ! scalar ( @ready );
2434 sub vm_monitor_command
{
2435 my ( $vmid, $cmdstr, $nolog, $nocheck ) = @_ ;
2439 syslog
( "info" , "VM $vmid monitor command ' $cmdstr '" ) if ! $nolog ;
2442 die "VM not running \n " if ! check_running
( $vmid, $nocheck );
2444 my $sname = monitor_socket
( $vmid );
2446 my $sock = IO
:: Socket
:: UNIX-
> new ( Peer
=> $sname ) ||
2447 die "unable to connect to VM $vmid socket - $!\n " ;
2451 # hack: migrate sometime blocks the monitor (when migrate_downtime
2453 if ( $cmdstr =~ m/^(info\s+migrate|migrate\s)/ ) {
2454 $timeout = 60 * 60 ; # 1 hour
2458 my $data = __read_avail
( $sock, $timeout );
2460 if ( $data !~ m/^QEMU\s+(\S+)\s+monitor\s/ ) {
2461 die "got unexpected qemu monitor banner \n " ;
2464 my $sel = new IO
:: Select
;
2467 if (! scalar ( my @ready = $sel -> can_write ( $timeout ))) {
2468 die "monitor write error - timeout" ;
2471 my $fullcmd = " $cmdstr\r " ;
2474 if (!( $b = $sock -> syswrite ( $fullcmd )) || ( $b != length ( $fullcmd ))) {
2475 die "monitor write error - $! " ;
2478 return if ( $cmdstr eq 'q' ) || ( $cmdstr eq 'quit' );
2482 if ( $cmdstr =~ m/^(info\s+migrate|migrate\s)/ ) {
2483 $timeout = 60 * 60 ; # 1 hour
2484 } elsif ( $cmdstr =~ m/^(eject|change)/ ) {
2485 $timeout = 60 ; # note: cdrom mount command is slow
2487 if ( $res = __read_avail
( $sock, $timeout )) {
2489 my @lines = split ( " \r ? \n " , $res );
2491 shift @lines if $lines [ 0 ] !~ m/^unknown command/ ; # skip echo
2493 $res = join ( " \n " , @lines );
2501 syslog
( "err" , "VM $vmid monitor command failed - $err " );
2508 sub vm_commandline
{
2509 my ( $storecfg, $vmid ) = @_ ;
2511 my $conf = load_config
( $vmid );
2513 my $defaults = load_defaults
();
2515 my $cmd = config_to_command
( $storecfg, $vmid, $conf, $defaults );
2517 return join ( ' ' , @$cmd );
2521 my ( $vmid, $skiplock ) = @_ ;
2523 lock_config
( $vmid, sub {
2525 my $conf = load_config
( $vmid );
2527 check_lock
( $conf ) if ! $skiplock ;
2529 syslog
( "info" , "VM $vmid sending 'reset'" );
2531 vm_monitor_command
( $vmid, "system_reset" , 1 );
2536 my ( $vmid, $skiplock ) = @_ ;
2538 lock_config
( $vmid, sub {
2540 my $conf = load_config
( $vmid );
2542 check_lock
( $conf ) if ! $skiplock ;
2544 syslog
( "info" , "VM $vmid sending 'shutdown'" );
2546 vm_monitor_command
( $vmid, "system_powerdown" , 1 );
2550 # Note: use $nockeck to skip tests if VM configuration file exists.
2551 # We need that when migration VMs to other nodes (files already moved)
2553 my ( $vmid, $skiplock, $nocheck ) = @_ ;
2555 lock_config
( $vmid, sub {
2557 my $pid = check_running
( $vmid, $nocheck );
2560 syslog
( 'info' , "VM $vmid already stopped" );
2565 my $conf = load_config
( $vmid );
2566 check_lock
( $conf ) if ! $skiplock ;
2569 syslog
( "info" , "VM $vmid stopping" );
2571 eval { vm_monitor_command
( $vmid, "quit" , 1 , $nocheck ); };
2577 my $timeout = 50 ; # fixme: how long?
2580 while (( $count < $timeout ) && check_running
( $vmid, $nocheck )) {
2585 if ( $count >= $timeout ) {
2586 syslog
( 'info' , "VM $vmid still running - terminating now with SIGTERM" );
2590 syslog
( 'info' , "VM $vmid quit failed - terminating now with SIGTERM" );
2598 while (( $count < $timeout ) && check_running
( $vmid, $nocheck )) {
2603 if ( $count >= $timeout ) {
2604 syslog
( 'info' , "VM $vmid still running - terminating now with SIGKILL \n " );
2608 fairsched_rmnod
( $vmid ); # try to destroy group
2613 my ( $vmid, $skiplock ) = @_ ;
2615 lock_config
( $vmid, sub {
2617 my $conf = load_config
( $vmid );
2619 check_lock
( $conf ) if ! $skiplock ;
2621 syslog
( "info" , "VM $vmid suspend" );
2623 vm_monitor_command
( $vmid, "stop" , 1 );
2628 my ( $vmid, $skiplock ) = @_ ;
2630 lock_config
( $vmid, sub {
2632 my $conf = load_config
( $vmid );
2634 check_lock
( $conf ) if ! $skiplock ;
2636 syslog
( "info" , "VM $vmid resume" );
2638 vm_monitor_command
( $vmid, "cont" , 1 );
2643 my ( $vmid, $skiplock, $key ) = @_ ;
2645 lock_config
( $vmid, sub {
2647 my $conf = load_config
( $vmid );
2649 check_lock
( $conf ) if ! $skiplock ;
2651 syslog
( "info" , "VM $vmid sending key $key " );
2653 vm_monitor_command
( $vmid, "sendkey $key " , 1 );
2658 my ( $storecfg, $vmid, $skiplock ) = @_ ;
2660 lock_config
( $vmid, sub {
2662 my $conf = load_config
( $vmid );
2664 check_lock
( $conf ) if ! $skiplock ;
2666 syslog
( "info" , "VM $vmid destroy called (removing all data)" );
2669 if (! check_running
( $vmid )) {
2670 fairsched_rmnod
( $vmid ); # try to destroy group
2671 destroy_vm
( $storecfg, $vmid );
2673 die "VM is running \n " ;
2680 syslog
( "err" , "VM $vmid destroy failed - $err " );
2689 $timeout = 3 * 60 if ! $timeout ;
2691 my $vzlist = vzlist
();
2693 foreach my $vmid ( keys %$vzlist ) {
2694 next if ! $vzlist ->{ $vmid }->{ pid
};
2700 my $msg = "Stopping Qemu Server - sending shutdown requests to all VMs \n " ;
2701 syslog
( 'info' , $msg );
2704 foreach my $vmid ( keys %$vzlist ) {
2705 next if ! $vzlist ->{ $vmid }->{ pid
};
2706 eval { vm_shutdown
( $vmid, 1 ); };
2707 print STDERR
$@ if $@ ;
2711 my $maxtries = int (( $timeout + $wt - 1 )/ $wt );
2713 while (( $try < $maxtries ) && $count ) {
2719 foreach my $vmid ( keys %$vzlist ) {
2720 next if ! $vzlist ->{ $vmid }->{ pid
};
2728 foreach my $vmid ( keys %$vzlist ) {
2729 next if ! $vzlist ->{ $vmid }->{ pid
};
2731 $msg = "VM $vmid still running - sending stop now \n " ;
2732 syslog
( 'info' , $msg );
2735 eval { vm_monitor_command
( $vmid, "quit" , 1 ); };
2736 print STDERR
$@ if $@ ;
2741 $maxtries = int (( $timeout + $wt - 1 )/ $wt );
2743 while (( $try < $maxtries ) && $count ) {
2749 foreach my $vmid ( keys %$vzlist ) {
2750 next if ! $vzlist ->{ $vmid }->{ pid
};
2758 foreach my $vmid ( keys %$vzlist ) {
2759 next if ! $vzlist ->{ $vmid }->{ pid
};
2761 $msg = "VM $vmid still running - terminating now with SIGTERM \n " ;
2762 syslog
( 'info' , $msg );
2764 kill 15 , $vzlist ->{ $vmid }->{ pid
};
2767 # this is called by system shotdown scripts, so remaining
2768 # processes gets killed anyways (no need to send kill -9 here)
2770 $msg = "Qemu Server stopped \n " ;
2771 syslog
( 'info' , $msg );
2779 my ( $filename, $buf ) = @_ ;
2781 my $fh = IO
:: File-
> new ( $filename, "w" );
2782 return undef if ! $fh ;
2784 my $res = print $fh $buf ;
2791 sub pci_device_info
{
2796 return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/ ;
2797 my ( $domain, $bus, $slot, $func ) = ( $1, $2, $3, $4 );
2799 my $irq = file_read_firstline
( " $pcisysfs/devices/$name/irq " );
2800 return undef if ! defined ( $irq ) || $irq !~ m/^\d+$/ ;
2802 my $vendor = file_read_firstline
( " $pcisysfs/devices/$name/vendor " );
2803 return undef if ! defined ( $vendor ) || $vendor !~ s/^0x// ;
2805 my $product = file_read_firstline
( " $pcisysfs/devices/$name/device " );
2806 return undef if ! defined ( $product ) || $product !~ s/^0x// ;
2811 product
=> $product,
2817 has_fl_reset
=> - f
" $pcisysfs/devices/$name/reset " || 0 ,
2826 my $name = $dev ->{ name
};
2828 my $fn = " $pcisysfs/devices/$name/reset " ;
2830 return file_write
( $fn, "1" );
2833 sub pci_dev_bind_to_stub
{
2836 my $name = $dev ->{ name
};
2838 my $testdir = " $pcisysfs/drivers/pci -stub/ $name " ;
2839 return 1 if - d
$testdir ;
2841 my $data = " $dev ->{vendor} $dev ->{product}" ;
2842 return undef if ! file_write
( " $pcisysfs/drivers/pci -stub/new_id" , $data );
2844 my $fn = " $pcisysfs/devices/$name/driver/unbind " ;
2845 if (! file_write
( $fn, $name )) {
2846 return undef if - f
$fn ;
2849 $fn = " $pcisysfs/drivers/pci -stub/bind" ;
2850 if (! - d
$testdir ) {
2851 return undef if ! file_write
( $fn, $name );
2857 sub print_pci_addr
{
2862 #addr1 : ide,parallel,serial (motherboard)
2863 #addr2 : first videocard
2864 balloon0
=> { bus
=> 0 , addr
=> 3 },
2865 watchdog
=> { bus
=> 0 , addr
=> 4 },
2866 scsi0
=> { bus
=> 0 , addr
=> 5 },
2867 scsi1
=> { bus
=> 0 , addr
=> 6 },
2868 virtio0
=> { bus
=> 0 , addr
=> 10 },
2869 virtio1
=> { bus
=> 0 , addr
=> 11 },
2870 virtio2
=> { bus
=> 0 , addr
=> 12 },
2871 virtio3
=> { bus
=> 0 , addr
=> 13 },
2872 virtio4
=> { bus
=> 0 , addr
=> 14 },
2873 virtio5
=> { bus
=> 0 , addr
=> 15 },
2874 hostpci0
=> { bus
=> 0 , addr
=> 16 },
2875 hostpci1
=> { bus
=> 0 , addr
=> 17 },
2876 net0
=> { bus
=> 0 , addr
=> 18 },
2877 net1
=> { bus
=> 0 , addr
=> 19 },
2878 net2
=> { bus
=> 0 , addr
=> 20 },
2879 net3
=> { bus
=> 0 , addr
=> 21 },
2880 net4
=> { bus
=> 0 , addr
=> 22 },
2881 net5
=> { bus
=> 0 , addr
=> 23 },
2882 #addr29 : usb-host (pve-usb.cfg)
2885 if ( defined ( $devices ->{ $id }->{ bus
}) && defined ( $devices ->{ $id }->{ addr
})) {
2886 my $addr = sprintf ( "0x %x " , $devices ->{ $id }->{ addr
});
2887 $res = ",bus=pci. $devices ->{ $id }->{bus},addr= $addr " ;
2894 my ( $vmid, $value ) = @_ ;
2896 vm_monitor_command
( $vmid, "balloon $value " , 1 );