[pve-devel] virtiodisk ordering bug in current implementation + proposal for new qemu device syntax

Alexandre DERUMIER aderumier at odiso.com
Mon Aug 29 12:52:10 CEST 2011


ok, for hotplug, it will be very small code.

I just send some command to qemu monitor (like to add a cd to cdrom drive).

basicly i use 4 new subs

1 to add device, 1 to remove device, 1 to parse pci devices to verify is add/delete had correctly work, 1 for generated disk device command line







sub vm_deviceadd {
    my ($self, $vmid,$type, $device) = @_;

    my $filename = PVE::QemuServer::config_file ($vmid);
    my $device_id=0;
    return unless -f $filename;

    lock_config ($vmid, sub {

        return if !check_running ($vmid); # do nothing

        my $conf = $self->load_config ($vmid);

        check_lock ($conf);

        if($type eq "disk"){
                unless($device->{interface} eq 'ide'){
                    $device_id="disk-$device->{interface}$device->{index}";
                    my $drive = $self->print_drive_full ($vmid, $device);

                    $self->vm_monitor_command ($vmid, "drive_add auto $drive", 1);
                    my $device = $self->print_diskdevice_full ($vmid, $device);
                    $self->vm_monitor_command ($vmid, "device_add $device", 1);

            }
        }
        elsif($type eq "nic") {

            my $defaults = load_defaults();
            my $key="nic$device->{id}";
            my $addr=$defaults->{pci}->{$key}->{addr} if defined $defaults->{pci}->{$key}->{addr};
            my $bus=$defaults->{pci}->{$key}->{bus} if defined $defaults->{pci}->{$key}->{bus};
            die ('missing addr for '.$key) if !defined ($addr);
            die ('missing bus for '.$key) if !defined ($bus);
            $addr = sprintf("0x%x", $addr);

            if ($device->{model} eq 'virtio') {
              $device->{model}='virtio-net-pci';
            }
            my $vhostparam='';
            $vhostparam = ',vhost=on' if $kernel_has_vhost_net;
            my $ifname = "tap${vmid}i$device->{vlanid}";

            $device_id="nic$device->{id}";

            $self->vm_monitor_command ($vmid, "netdev_add type=tap,id=netdev$device->{id},ifname=${ifname}d$device->{id},script=/var/lib/qemu-server/bridge-vlan$vhostparam",1);
            $self->vm_monitor_command ($vmid, "device_add $device->{model},netdev=netdev".$device->{id}.",id=$device_id,mac=".$device->{macaddr}.",bus=pci.$bus,addr=$addr", 1);
        }

        #verification
        sleep 1;
        my $devices_list=$self->vm_devices_list($vmid);
        die() if(! defined($devices_list->{$device_id}));

    });

    die $@ if $@;
}



sub vm_devicedel {
    my ($self, $vmid,$type,$device) = @_;


    my $filename = PVE::QemuServer::config_file ($vmid);
    my $device_id=0;

    return unless -f $filename;

    lock_config ($vmid, sub {

        return if !check_running ($vmid); # do nothing

        my $conf = $self->load_config ($vmid);

        check_lock ($conf);

        if($type eq "disk") {

            $device_id="disk-$device->{interface}$device->{index}";
            $self->vm_monitor_command ($vmid, " device_del $device_id",1);
            print " device_del $device_id";

        }
        elsif($type eq "nic") {

            $device_id="nic$device->{id}";
            $self->vm_monitor_command ($vmid, " device_del $device_id",1);
            $self->vm_monitor_command ($vmid, " netdev_del netdev$device->{id}",1);

        }
        sleep 2;
        my $devices_list=$self->vm_devices_list($vmid);
        die() if(defined $devices_list->{$device_id});
    });

    die $@ if $@;
}


sub vm_devices_list {
    my ($self, $vmid) = @_;

        my $res=$self->vm_monitor_command ($vmid, "info pci", 1);

        my @lines = split ("\n", $res);
        my $devices;
        my $bus;
        my $addr;
        my $id;
        foreach my $line (@lines) {
            $line =~ s/^\s+//;
          if ($line =~ m/^Bus  (\d+), device   (\d+), function (\d+):$/) {
           $bus=$1;
           $addr=$2;
          }
          if ($line =~ m/^id "([a-z][a-z_\-]*\d*)"$/) {
            $id=$1;
            $devices->{$id}->{bus}=$bus;
            $devices->{$id}->{addr}=$addr;
          }
        }

return $devices;
}


sub print_diskdevice_full {
    my ($self, $vmid, $drive) = @_;

    my $opts = '';
    my $device = '';
    my $maxdev = 1024;
    foreach my $o (@qemu_drive_options) {
        $opts .= ",$o=$drive->{$o}" if $drive->{$o};
    }

 

    if ($drive->{interface} eq 'virtio') {

      my $defaults = load_defaults();
      my $key=$drive->{interface}.$drive->{index};
      my $addr=$defaults->{pci}->{$key}->{addr} if defined $defaults->{pci}->{$key}->{addr};
      my $bus=$defaults->{pci}->{$key}->{bus} if defined $defaults->{pci}->{$key}->{bus};
      die ('missing addr for '.$key) if !defined ($addr);
      die ('missing bus for '.$key) if !defined ($bus);
      $addr = sprintf("0x%x", $addr);

      $device="virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=disk-$drive->{interface}$drive->{index},bus=pci.$bus,addr=$addr";
    }

    elsif ($drive->{interface} eq 'scsi') {

      $maxdev = 7;
      my $controller = int ($drive->{index} / $maxdev);
      my $unit = $drive->{index} % $maxdev;

      $device="scsi-disk,bus=scsi$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=disk-$drive->{interface}$drive->{index}";
    }

    elsif ($drive->{interface} eq 'ide'){

      $maxdev = 2;
      my $controller = int ($drive->{index} / $maxdev);
      my $unit = $drive->{index} % $maxdev;

      $device="ide-drive,bus=ide.$controller,unit=$unit,drive=drive-$drive->{interface}$drive->{index},id=disk-$drive->{interface}$drive->{index}";
    }

    if ($drive->{interface} eq 'usb'){
      #  -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
    }

    return $device;
}



----- Mail original ----- 

De: "Dietmar Maurer" <dietmar at proxmox.com> 
À: "Alexandre DERUMIER" <aderumier at odiso.com> 
Cc: pve-devel at pve.proxmox.com 
Envoyé: Lundi 29 Août 2011 12:16:16 
Objet: RE: virtiodisk ordering bug in current implementation + proposal for new qemu device syntax 

> ok, I understand your point of view. 

we can still add that later if it is required. 

> I think 6 virtio and 6 nics is a good value. 
> 
> 
> Do you want I start write code on this basis ? 

yes 

> I can do code for new device syntax + hotplug, if it can help you. 

I guess I can include code for new device syntax and fixed pci addr now. 

> (i'm sure you are very busy with all other parts of proxmox2 ;) 

yes, so I am not sure if we can include hotplug now - depends on how complex those patches are. 

Anyways, we now have git, so it should be easy to maintain a 'hotplug' branch until we 
are ready to include it. 

- Dietmar 




-- 

-- 




	
	Alexandre Derumier 
Ingénieur système 
e-mail : aderumier at odiso.com 
Tél : +33 (0)3 20 68 88 90 
Fax : +33 (0)3 20 68 90 81 
45 Bvd du Général Leclerc 
59100 ROUBAIX - FRANCE 













-------------- next part --------------
A non-text attachment was scrubbed...
Name: aderumier.vcf
Type: text/x-vcard
Size: 183 bytes
Desc: not available
URL: <http://lists.proxmox.com/pipermail/pve-devel/attachments/20110829/03930d17/attachment.vcf>


More information about the pve-devel mailing list