diff mbox

[1/6] bootindex: add {del, modify}_boot_device_path function

Message ID 1406191142-16556-2-git-send-email-arei.gonglei@huawei.com
State New
Headers show

Commit Message

Gonglei (Arei) July 24, 2014, 8:38 a.m. UTC
From: Gonglei <arei.gonglei@huawei.com>

When we want to change one device's bootindex, we should do three
things. On the on hand, remove the device from global fw_boot_order list,
regardless attaching suffix or not delete. On the other hand, delete
original object of the assigned bootindex. Finally add the new device's
bootindex into the global fw_boot_order list.

Signed-off-by: Chenliang <chenliang88@huawei.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 include/sysemu/sysemu.h |  4 ++++
 vl.c                    | 57 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)

Comments

Gerd Hoffmann July 24, 2014, 10:08 a.m. UTC | #1
On Do, 2014-07-24 at 16:38 +0800, arei.gonglei@huawei.com wrote:
> From: Gonglei <arei.gonglei@huawei.com>
> 
> When we want to change one device's bootindex, we should do three
> things. On the on hand, remove the device from global fw_boot_order list,
> regardless attaching suffix or not delete. On the other hand, delete
> original object of the assigned bootindex. Finally add the new device's
> bootindex into the global fw_boot_order list.

Hmm.  I think we should simply lookup the device and modify the
bootindex, leaving the entry as-is otherwise.  In case the new bootindex
is already used by another device just throw an error.

> +void del_boot_device_path(int32_t bootindex, DeviceState *dev,
> +                          const char *suffix);

Should be del_boot_device_path(DeviceState *dev) and simply delete all
entries belonging to the device.  Patch #3 can be much simpler then as
we can call the function from generic device cleanup code.

> +void modify_boot_device_path(int32_t bootindex, DeviceState *dev,
> +                             const char *suffix);

No need for suffix here if we just update the existing entry.

cheers,
  Gerd
Gonglei (Arei) July 24, 2014, 12:39 p.m. UTC | #2
Hi, Gerd

> -----Original Message-----

> From: Gerd Hoffmann [mailto:kraxel@redhat.com]

> Sent: Thursday, July 24, 2014 6:09 PM

> To: Gonglei (Arei)

> Cc: qemu-devel@nongnu.org; afaerber@suse.de; agraf@suse.de;

> stefanha@redhat.com; akong@redhat.com; aik@ozlabs.ru;

> alex.williamson@redhat.com; armbru@redhat.com; eblake@redhat.com;

> kwolf@redhat.com; peter.maydell@linaro.org; lcapitulino@redhat.com;

> mst@redhat.com; pbonzini@redhat.com; lersek@redhat.com;

> imammedo@redhat.com; dmitry@daynix.com; marcel.a@redhat.com;

> peter.crosthwaite@xilinx.com; rth@twiddle.net; somlo@cmu.edu;

> Huangweidong (C); Luonengjun; Huangpeng (Peter); chenliang (T)

> Subject: Re: [PATCH 1/6] bootindex: add {del,modify}_boot_device_path

> function

> 

> On Do, 2014-07-24 at 16:38 +0800, arei.gonglei@huawei.com wrote:

> > From: Gonglei <arei.gonglei@huawei.com>

> >

> > When we want to change one device's bootindex, we should do three

> > things. On the on hand, remove the device from global fw_boot_order list,

> > regardless attaching suffix or not delete. On the other hand, delete

> > original object of the assigned bootindex. Finally add the new device's

> > bootindex into the global fw_boot_order list.

> 

> Hmm.  I think we should simply lookup the device and modify the

> bootindex, leaving the entry as-is otherwise.  In case the new bootindex

> is already used by another device just throw an error.

> 

If we just throw an error but not change the bootindex is already used,
we cannot achieve our purpose. For example, we configure a hard disk,
which bootindex=1, a nic which bootindex=2. If we want to boot the guest
from nic firstly, we should must set the nic's bootindex to 1. AFAICT, the 
bootindex=1 always be used.
 
> > +void del_boot_device_path(int32_t bootindex, DeviceState *dev,

> > +                          const char *suffix);

> 

> Should be del_boot_device_path(DeviceState *dev) and simply delete all

> entries belonging to the device.  Patch #3 can be much simpler then as

> we can call the function from generic device cleanup code.

> 

Because the IDE device may configure two kind of disk, HD and CDROM, we
have to distinguish them by suffix.

> > +void modify_boot_device_path(int32_t bootindex, DeviceState *dev,

> > +                             const char *suffix);

> 

> No need for suffix here if we just update the existing entry.

> 

> cheers,

>   Gerd

> 


Best regards,
-Gonglei
Gerd Hoffmann July 24, 2014, 1:25 p.m. UTC | #3
Hi,

> > Hmm.  I think we should simply lookup the device and modify the
> > bootindex, leaving the entry as-is otherwise.  In case the new bootindex
> > is already used by another device just throw an error.
> > 
> If we just throw an error but not change the bootindex is already used,
> we cannot achieve our purpose. For example, we configure a hard disk,
> which bootindex=1, a nic which bootindex=2. If we want to boot the guest
> from nic firstly, we should must set the nic's bootindex to 1. AFAICT, the 
> bootindex=1 always be used.

No.  The devices are simply sorted by bootindex.  You don't have to use
'1'.  And you can have holes in your numbering and use --for example --
3+5.

So you can start qemu with hd=2,cdrom=3,nic=4, then set nic=1 or cdrom=1
for a guest install, change it back when done.

> > Should be del_boot_device_path(DeviceState *dev) and simply delete all
> > entries belonging to the device.  Patch #3 can be much simpler then as
> > we can call the function from generic device cleanup code.
> > 
> Because the IDE device may configure two kind of disk, HD and CDROM, we
> have to distinguish them by suffix.

Yes, the suffix indicated whenever the device is a disk or cdrom.  But
you'll never have both cdrom+disk paths attached to a single device.
Therefore the device is enough to identify the bootpath entry, you don't
need the suffix for that.

cheers,
  Gerd
Gonglei (Arei) July 25, 2014, 3:31 a.m. UTC | #4
> -----Original Message-----

> From: Gerd Hoffmann [mailto:kraxel@redhat.com]

> Sent: Thursday, July 24, 2014 9:25 PM

> Subject: Re: [PATCH 1/6] bootindex: add {del,modify}_boot_device_path

> function

> 

>   Hi,

> 

> > > Hmm.  I think we should simply lookup the device and modify the

> > > bootindex, leaving the entry as-is otherwise.  In case the new bootindex

> > > is already used by another device just throw an error.

> > >

> > If we just throw an error but not change the bootindex is already used,

> > we cannot achieve our purpose. For example, we configure a hard disk,

> > which bootindex=1, a nic which bootindex=2. If we want to boot the guest

> > from nic firstly, we should must set the nic's bootindex to 1. AFAICT, the

> > bootindex=1 always be used.

> 

> No.  The devices are simply sorted by bootindex.  You don't have to use

> '1'.  And you can have holes in your numbering and use --for example --

> 3+5.

> 

Yes, you are right. I make a mistake because libvirt will default assign the first 
disk as bootindex=1.

> So you can start qemu with hd=2,cdrom=3,nic=4, then set nic=1 or cdrom=1

> for a guest install, change it back when done.

>

Yes.
 
> > > Should be del_boot_device_path(DeviceState *dev) and simply delete all

> > > entries belonging to the device.  Patch #3 can be much simpler then as

> > > we can call the function from generic device cleanup code.

> > >

> > Because the IDE device may configure two kind of disk, HD and CDROM, we

> > have to distinguish them by suffix.

> 

> Yes, the suffix indicated whenever the device is a disk or cdrom.  But

> you'll never have both cdrom+disk paths attached to a single device.

> Therefore the device is enough to identify the bootpath entry, you don't

> need the suffix for that.

> 

Agreed. Thank you so much, Gerd. 
A new version will be posted later.

Best regards,
-Gonglei
diff mbox

Patch

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d8539fd..e368627 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -209,6 +209,10 @@  void usb_info(Monitor *mon, const QDict *qdict);
 
 void add_boot_device_path(int32_t bootindex, DeviceState *dev,
                           const char *suffix);
+void del_boot_device_path(int32_t bootindex, DeviceState *dev,
+                          const char *suffix);
+void modify_boot_device_path(int32_t bootindex, DeviceState *dev,
+                             const char *suffix);
 char *get_boot_devices_list(size_t *size, bool ignore_suffixes);
 
 DeviceState *get_boot_device(uint32_t position);
diff --git a/vl.c b/vl.c
index fe451aa..e304a93 100644
--- a/vl.c
+++ b/vl.c
@@ -1248,6 +1248,63 @@  void add_boot_device_path(int32_t bootindex, DeviceState *dev,
     QTAILQ_INSERT_TAIL(&fw_boot_order, node, link);
 }
 
+static bool is_same_fw_dev_path(DeviceState *src, DeviceState *target)
+{
+    bool ret = false;
+    char *devpath_src = qdev_get_fw_dev_path(src);
+    char *devpath_target = qdev_get_fw_dev_path(target);
+
+    if (!strcmp(devpath_src, devpath_target)) {
+        ret = true;
+    }
+
+    g_free(devpath_src);
+    g_free(devpath_target);
+    return ret;
+}
+
+void del_boot_device_path(int32_t bootindex, DeviceState *dev,
+                          const char *suffix)
+{
+    FWBootEntry *i;
+
+    assert(dev != NULL);
+    assert(bootindex >= 0 || suffix != NULL);
+
+    QTAILQ_FOREACH(i, &fw_boot_order, link) {
+        if (is_same_fw_dev_path(i->dev, dev)) {
+            if (suffix && i->suffix && strcmp(i->suffix, suffix)) {
+                continue;
+            }
+            /* if suffix is NULL, remove all entries of the assigend dev */
+            QTAILQ_REMOVE(&fw_boot_order, i, link);
+            g_free(i->suffix);
+            g_free(i);
+            break;
+        }
+    }
+
+    if (bootindex < 0) {
+        return;
+    }
+    /* find the object of assigned bootindex, and then remove it */
+    QTAILQ_FOREACH(i, &fw_boot_order, link) {
+        if (i->bootindex == bootindex) {
+            QTAILQ_REMOVE(&fw_boot_order, i, link);
+            g_free(i->suffix);
+            g_free(i);
+            break;
+        }
+    }
+}
+
+void modify_boot_device_path(int32_t bootindex, DeviceState *dev,
+                             const char *suffix)
+{
+    del_boot_device_path(bootindex, dev, suffix);
+    add_boot_device_path(bootindex, dev, suffix);
+}
+
 DeviceState *get_boot_device(uint32_t position)
 {
     uint32_t counter = 0;