qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] virtio-blk-pci: how to tell if it is CD or HDD?


From: Alexey Kardashevskiy
Subject: Re: [Qemu-devel] virtio-blk-pci: how to tell if it is CD or HDD?
Date: Thu, 17 Oct 2013 23:38:31 +1100
User-agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.0

On 10/16/2013 06:59 PM, Alexey Kardashevskiy wrote:
> On 10/16/2013 05:36 PM, Paolo Bonzini wrote:
>> Il 16/10/2013 07:04, Alexey Kardashevskiy ha scritto:
>>> Hi!
>>>
>>> Normally on sPAPR platform the IBMVSCSI host bus adapter is used which is
>>> SCSI. So when we want some image to appear as a DVD to the guest
>>> (particularly SLOF - our firmware), we use "-device scsi-cd". Or QEMU
>>> extracts this automatically from the "media=cdrom" property of "-drive"
>>> (correct?). And then the SCSI bus tells the guest what is what. SLOF
>>> firmware uses this to create "disk" and "cdrom" aliases to correcly apply
>>> the boot order. So far so good.
>>>
>>> Now we are trying (via libvirt) to add both HDD and DVD as "virtio-blk-pci"
>>> devices:
>>>
>>> -drive file=virtimg/rhel6-root.img,if=none,format=raw,\
>>> id=drive-virtio-disk1,cache=none \
>>> -device virtio-blk-pci,bus=pci,addr=0x4,\
>>> drive=drive-virtio-disk1,id=virtio-disk1,bootindex=2 \
>>> \
>>> -drive file=virtimg/SLES-11-SP3-DVD-ppc64-GM-DVD1.iso,\
>>> if=none,media=cdrom,id=drive-virtio-disk2,readonly=on,\
>>> format=raw\
>>> -device virtio-blk-pci,bus=pci,addr=0x5,\
>>> drive=drive-virtio-disk2,id=virtio-disk2,bootindex=1
>>>
>>> No SCSI bus is created in this case. Both devices appear to SLOF as HDDs so
>>> it creates just one "disk" alias and no "cdrom" alias and if we are not
>>> lucky and DVD got bigger PCI slot#, we will never be able to boot from DVD.
>>>
>>> Is there any way to distinguish HDD from DVD via virtio protocol from the
>>> guest (i.e. SLOF)? Thanks!
>>
>> No, virtio-blk is always a HDD.
> 
> Thanks, good to know.
> 
>> Does bootindex work with pSeries?
> 
> Nope. Seems the time to support this has come :)

I need some help to understand how to do that properly. There are 2 sets of
callbacks - get_dev_path() and get_fw_dev_path(). And we also have
device-tree which SLOF parses and creates aliases from so it is a good hint
what SLOF can boot from.


So I added some debug output and run a test. The parameters below create
virtio-scsi bus with 2 DVDs, ibmvscsi bus with 2 DVDs (same ones but this
is not the point), virtio-net-pci.


 -device virtio-scsi-pci,id=v11 \
 -drive file=virtimg/SLES-11-SP3-DVD-ppc64-GM-DVD1.iso,if=none,id=vi11,\
readonly=on,format=raw \
 -device scsi-cd,bus=v11.0,channel=0,scsi-id=3,lun=1,\
drive=vi11,bootindex=13 \
 -drive file=virtimg/Fedora-18-ppc64-DVD.iso,if=none,id=vi12,\
readonly=on,format=raw \
 -device scsi-cd,bus=v11.0,channel=0,scsi-id=3,lun=2,\
drive=vi12,bootindex=12 \
 -netdev tap,id=netdev5000,ifname=tap5000,script=ifup.sh,\
downscript=ifdown.sh \
 -device virtio-net-pci,netdev=netdev5000,bus=pci,addr=1.0,\
mac=C0:41:49:4b:00:00,bootindex=11 \
 -device spapr-vscsi,id=s11 \
 -drive file=virtimg/SLES-11-SP3-DVD-ppc64-GM-DVD1.iso,if=none,id=i11,\
readonly=on,format=raw \
 -device scsi-cd,bus=s11.0,channel=0,scsi-id=3,lun=1,\
drive=i11,bootindex=3 \
 -drive file=virtimg/Fedora-18-ppc64-DVD.iso,if=none,id=i12,\
readonly=on,format=raw \
 -device scsi-cd,bus=s11.0,channel=0,scsi-id=3,lun=2,\
drive=i12,bootindex=2 \


I did few changes in QEMU (diffs are below) to replace default
"/spapr-pci-host-bridge/" with "/address@hidden/" in what
qdev_get_dev_path/qdev_get_fw_dev_path return, this is to distinguish PHBs.

I added some printfs to see what qdev_*dev_path() do:

qdev_get_dev_path:
address@hidden/0:3:2 suffix=(null)
address@hidden/0:3:1 suffix=(null)
address@hidden:01.0 suffix=/address@hidden
address@hidden:00.0/0:3:2 suffix=(null)
address@hidden:00.0/0:3:1 suffix=(null)

qdev_get_fw_dev_path:
/spapr-vio-bridge/spapr-vscsi/address@hidden/address@hidden,2 suffix=(null)
/spapr-vio-bridge/spapr-vscsi/address@hidden/address@hidden,1 suffix=(null)
/address@hidden/address@hidden suffix=/address@hidden
/address@hidden/address@hidden/address@hidden/address@hidden,2 suffix=(null)
/address@hidden/address@hidden/address@hidden/address@hidden,1 suffix=(null)

SLOF:
0 > devalias
cdrom123 : /address@hidden/address@hidden/address@hidden
cdrom12 : /address@hidden/address@hidden/address@hidden
hvterm : /vdevice/address@hidden
net : /address@hidden/address@hidden
scsi : /vdevice/address@hidden
cdrom1 : /vdevice/address@hidden/address@hidden
cdrom : /vdevice/address@hidden/address@hidden
nvram : /vdevice/address@hidden ok


In ideal world I would want to get in QEMU what SLOF can understand and
pass this to SLOF. But QEMU APIs return something which cannot be converted
straight away.

Or I could simply put bootindex to the device tree nodes (as
"qemu,bootindex") but in this case "wildcard" nodes support fails as there
is just a single node "/vdevice/address@hidden/disk" in the device tree
for all LUNs. And we definitely do not want to create nodes for all disk
devices.

Or I can implement a "smart" converter from QEMU strings to OF pathnames.

Or I can implement third set of callbacks, something like qdev_OF_dev_path().

Or not support "bootindex" at all.

All possibilities suck but which one sucks less? :) Thanks!


btw what format does qdev_get_fw_dev_path() use? This is not OF1275 so what
is it?




diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index b84cd4a..232ed2c 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -224,6 +224,10 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev)
     char path[40];
     int off;

+    if (dev->id) {
+        return g_strdup(dev->id);
+    }
+
     off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev));

     if (s->num_mmio) {


diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 8c75adb..d55177e 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -604,6 +604,10 @@ static void spapr_phb_realize(DeviceState *dev, Error
**errp)
     } else {
         busname = sphb->dtbusname;
     }
+    if (!dev->id) {
+        dev->id = g_strdup(sphb->dtbusname);
+    }
+
     bus = pci_register_bus(dev, busname,
                            pci_spapr_set_irq, pci_spapr_map_irq, sphb,
                            &sphb->memspace, &sphb->iospace,





-- 
Alexey



reply via email to

[Prev in Thread] Current Thread [Next in Thread]