From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gleb Natapov Subject: [PATCHv2 8/8] Add bootindex parameter to net/block/fd device Date: Sun, 31 Oct 2010 13:40:09 +0200 Message-ID: <1288525209-3303-9-git-send-email-gleb@redhat.com> References: <1288525209-3303-1-git-send-email-gleb@redhat.com> Cc: kvm@vger.kernel.org, blauwirbel@gmail.com, armbru@redhat.com, alex.williamson@redhat.com To: qemu-devel@nongnu.org Return-path: Received: from mx1.redhat.com ([209.132.183.28]:45526 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755028Ab0JaLkT (ORCPT ); Sun, 31 Oct 2010 07:40:19 -0400 In-Reply-To: <1288525209-3303-1-git-send-email-gleb@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: If bootindex is specified on command line a string that describes device in firmware readable way is added into sorted list. Later this list will be passed into firmware to control boot order. Signed-off-by: Gleb Natapov --- block_int.h | 4 +++- hw/e1000.c | 7 +++++++ hw/fdc.c | 13 +++++++++++++ hw/ide/qdev.c | 6 ++++++ hw/qdev.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ hw/virtio-blk.c | 4 ++++ hw/virtio-net.c | 4 ++++ net.h | 4 +++- sysemu.h | 9 +++++++++ vl.c | 24 ++++++++++++++++++++++++ 11 files changed, 128 insertions(+), 2 deletions(-) diff --git a/block_int.h b/block_int.h index e8e7156..60e7be2 100644 --- a/block_int.h +++ b/block_int.h @@ -225,6 +225,7 @@ typedef struct BlockConf { uint16_t logical_block_size; uint16_t min_io_size; uint32_t opt_io_size; + int32_t bootindex; } BlockConf; static inline unsigned int get_physical_block_exp(BlockConf *conf) @@ -247,6 +248,7 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) DEFINE_PROP_UINT16("physical_block_size", _state, \ _conf.physical_block_size, 512), \ DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \ - DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0) + DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0), \ + DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1) \ #endif /* BLOCK_INT_H */ diff --git a/hw/e1000.c b/hw/e1000.c index 532efdc..55f6f15 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -1148,6 +1148,12 @@ static int pci_e1000_init(PCIDevice *pci_dev) d->dev.qdev.info->name, d->dev.qdev.id, d); qemu_format_nic_info_str(&d->nic->nc, macaddr); + + if (d->conf.bootindex >= 0) { + qdev_add_boot_device_path(d->conf.bootindex, &pci_dev->qdev, + "ethernet-phy@0"); + } + return 0; } @@ -1159,6 +1165,7 @@ static void qdev_e1000_reset(DeviceState *dev) static PCIDeviceInfo e1000_info = { .qdev.name = "e1000", + .qdev.driver_name = "ethernet", .qdev.desc = "Intel Gigabit Ethernet", .qdev.size = sizeof(E1000State), .qdev.reset = qdev_e1000_reset, diff --git a/hw/fdc.c b/hw/fdc.c index 51ca404..e7a1399 100644 --- a/hw/fdc.c +++ b/hw/fdc.c @@ -35,6 +35,7 @@ #include "sysbus.h" #include "qdev-addr.h" #include "blockdev.h" +#include "sysemu.h" /********************************************************/ /* debug Floppy devices */ @@ -523,6 +524,8 @@ typedef struct FDCtrlSysBus { typedef struct FDCtrlISABus { ISADevice busdev; struct FDCtrl state; + int32_t bootindexA; + int32_t bootindexB; } FDCtrlISABus; static uint32_t fdctrl_read (void *opaque, uint32_t reg) @@ -1992,6 +1995,14 @@ static int isabus_fdc_init1(ISADevice *dev) qdev_set_legacy_instance_id(&dev->qdev, iobase, 2); ret = fdctrl_init_common(fdctrl); + if (isa->bootindexA >= 0) { + qdev_add_boot_device_path(isa->bootindexA, &dev->qdev, "floppy@0"); + } + + if (isa->bootindexB >= 0) { + qdev_add_boot_device_path(isa->bootindexB, &dev->qdev, "floppy@1"); + } + return ret; } @@ -2051,6 +2062,8 @@ static ISADeviceInfo isa_fdc_info = { .qdev.props = (Property[]) { DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs), DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].bs), + DEFINE_PROP_INT32("bootindexA", FDCtrlISABus, bootindexA, -1), + DEFINE_PROP_INT32("bootindexB", FDCtrlISABus, bootindexB, -1), DEFINE_PROP_END_OF_LIST(), }, }; diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index 7db2f19..49d2ac1 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -21,6 +21,7 @@ #include "qemu-error.h" #include #include "blockdev.h" +#include "sysemu.h" /* --------------------------------- */ @@ -144,6 +145,11 @@ static int ide_drive_initfn(IDEDevice *dev) if (!dev->serial) { dev->serial = qemu_strdup(s->drive_serial_str); } + + if (dev->conf.bootindex >= 0) { + qdev_add_boot_device_path(dev->conf.bootindex, &dev->qdev, NULL); + } + return 0; } diff --git a/hw/qdev.c b/hw/qdev.c index 35858cb..2306b06 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -820,3 +820,55 @@ int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data) } return qdev_unplug(dev); } + +static int qdev_get_dev_path_helper(DeviceState *dev, char *p, int size) +{ + int l = 0; + + if (dev && dev->parent_bus) { + char *d; + l = qdev_get_dev_path_helper(dev->parent_bus->parent, p, size); + if (dev->parent_bus->info->get_dev_path) { + d = dev->parent_bus->info->get_dev_path(dev); + l += snprintf(p + l, size - l, "%s", d); + qemu_free(d); + } else { + l += snprintf(p + l, size - l, "%s", dev->info->name); + } + } + l += snprintf(p + l , size - l, "/"); + + return l; +} + +char* qdev_get_dev_path(DeviceState *dev) +{ + char path[128]; + int l; + + l = qdev_get_dev_path_helper(dev, path, 128); + + path[l-1] = '\0'; + + return strdup(path); +} + +void qdev_add_boot_device_path(int32_t bootindex, DeviceState *dev, + const char *name) +{ + char *devpath, *bootpath; + + devpath = qdev_get_dev_path(dev); + + if (name) { + bootpath = qemu_malloc(strlen(devpath) + strlen(name) + 2); + sprintf(bootpath, "%s/%s", devpath, name); + qemu_free(devpath); + } else { + bootpath = devpath; + } + + add_boot_device_path(bootindex, bootpath); + + qemu_free(bootpath); +} diff --git a/hw/qdev.h b/hw/qdev.h index a9a98f8..6d8a543 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -294,6 +294,9 @@ static inline const char *qdev_driver_name(DeviceState *dev) return dev->info->driver_name ? : dev->info->name; } +void qdev_add_boot_device_path(int32_t bootindex, DeviceState *dev, + const char *name); +char *qdev_get_dev_path(DeviceState *dev); /* This is a nasty hack to allow passing a NULL bus to qdev_create. */ extern struct BusInfo system_bus_info; diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index a1df26d..c3175fb 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -542,6 +542,10 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf) bdrv_set_removable(s->bs, 0); s->bs->buffer_alignment = conf->logical_block_size; + if (conf->bootindex >= 0) { + qdev_add_boot_device_path(conf->bootindex, dev, "virtio-disk@0"); + } + return &s->vdev; } diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 7e1688c..75a4407 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -1018,6 +1018,10 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf, virtio_net_save, virtio_net_load, n); n->vmstate = qemu_add_vm_change_state_handler(virtio_net_vmstate_change, n); + if (conf->bootindex >= 0) { + qdev_add_boot_device_path(conf->bootindex, dev, "ethernet-phy@0"); + } + return &n->vdev; } diff --git a/net.h b/net.h index 44c31a9..6ceca50 100644 --- a/net.h +++ b/net.h @@ -17,12 +17,14 @@ typedef struct NICConf { MACAddr macaddr; VLANState *vlan; VLANClientState *peer; + int32_t bootindex; } NICConf; #define DEFINE_NIC_PROPERTIES(_state, _conf) \ DEFINE_PROP_MACADDR("mac", _state, _conf.macaddr), \ DEFINE_PROP_VLAN("vlan", _state, _conf.vlan), \ - DEFINE_PROP_NETDEV("netdev", _state, _conf.peer) + DEFINE_PROP_NETDEV("netdev", _state, _conf.peer), \ + DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1) /* VLANs support */ diff --git a/sysemu.h b/sysemu.h index 849dc8c..cc35731 100644 --- a/sysemu.h +++ b/sysemu.h @@ -193,4 +193,13 @@ void rtc_change_mon_event(struct tm *tm); void register_devices(void); +typedef struct FWBootEntry FWBootEntry; + +struct FWBootEntry { + QTAILQ_ENTRY(FWBootEntry) link; + int32_t bootindex; + char *fw_device_path; +}; + +void add_boot_device_path(int32_t bootindex, char *fw_device_path); #endif diff --git a/vl.c b/vl.c index 42617c2..25d5767 100644 --- a/vl.c +++ b/vl.c @@ -234,6 +234,8 @@ const char *prom_envs[MAX_PROM_ENVS]; const char *nvram = NULL; int boot_menu; +QTAILQ_HEAD(, FWBootEntry) fw_boot_order = QTAILQ_HEAD_INITIALIZER(fw_boot_order); + int nb_numa_nodes; uint64_t node_mem[MAX_NODES]; uint64_t node_cpumask[MAX_NODES]; @@ -722,6 +724,28 @@ static void restore_boot_devices(void *opaque) qemu_free(standard_boot_devices); } +void add_boot_device_path(int32_t bootindex, char *fw_device_path) +{ + FWBootEntry *node = qemu_mallocz(sizeof(FWBootEntry)), *i; + + node->bootindex = bootindex; + node->fw_device_path = fw_device_path; + + printf("adding '%s' at index %d\n", fw_device_path, bootindex); + QTAILQ_FOREACH(i, &fw_boot_order, link) { + if (i->bootindex == bootindex) { + fprintf(stderr, "Two devices with same boot index %d (%s %s)\n", + bootindex, i->fw_device_path, fw_device_path); + exit(1); + } else if (i->bootindex < bootindex) { + continue; + } + QTAILQ_INSERT_BEFORE(i, node, link); + return; + } + QTAILQ_INSERT_TAIL(&fw_boot_order, node, link); +} + static void numa_add(const char *optarg) { char option[128]; -- 1.7.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=55479 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PCWGs-0007on-Hp for qemu-devel@nongnu.org; Sun, 31 Oct 2010 07:40:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PCWGp-0008FU-Lm for qemu-devel@nongnu.org; Sun, 31 Oct 2010 07:40:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47696) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PCWGp-0008F7-5j for qemu-devel@nongnu.org; Sun, 31 Oct 2010 07:40:19 -0400 From: Gleb Natapov Date: Sun, 31 Oct 2010 13:40:09 +0200 Message-Id: <1288525209-3303-9-git-send-email-gleb@redhat.com> In-Reply-To: <1288525209-3303-1-git-send-email-gleb@redhat.com> References: <1288525209-3303-1-git-send-email-gleb@redhat.com> Subject: [Qemu-devel] [PATCHv2 8/8] Add bootindex parameter to net/block/fd device List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: blauwirbel@gmail.com, alex.williamson@redhat.com, armbru@redhat.com, kvm@vger.kernel.org If bootindex is specified on command line a string that describes device in firmware readable way is added into sorted list. Later this list will be passed into firmware to control boot order. Signed-off-by: Gleb Natapov --- block_int.h | 4 +++- hw/e1000.c | 7 +++++++ hw/fdc.c | 13 +++++++++++++ hw/ide/qdev.c | 6 ++++++ hw/qdev.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ hw/virtio-blk.c | 4 ++++ hw/virtio-net.c | 4 ++++ net.h | 4 +++- sysemu.h | 9 +++++++++ vl.c | 24 ++++++++++++++++++++++++ 11 files changed, 128 insertions(+), 2 deletions(-) diff --git a/block_int.h b/block_int.h index e8e7156..60e7be2 100644 --- a/block_int.h +++ b/block_int.h @@ -225,6 +225,7 @@ typedef struct BlockConf { uint16_t logical_block_size; uint16_t min_io_size; uint32_t opt_io_size; + int32_t bootindex; } BlockConf; static inline unsigned int get_physical_block_exp(BlockConf *conf) @@ -247,6 +248,7 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) DEFINE_PROP_UINT16("physical_block_size", _state, \ _conf.physical_block_size, 512), \ DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \ - DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0) + DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0), \ + DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1) \ #endif /* BLOCK_INT_H */ diff --git a/hw/e1000.c b/hw/e1000.c index 532efdc..55f6f15 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -1148,6 +1148,12 @@ static int pci_e1000_init(PCIDevice *pci_dev) d->dev.qdev.info->name, d->dev.qdev.id, d); qemu_format_nic_info_str(&d->nic->nc, macaddr); + + if (d->conf.bootindex >= 0) { + qdev_add_boot_device_path(d->conf.bootindex, &pci_dev->qdev, + "ethernet-phy@0"); + } + return 0; } @@ -1159,6 +1165,7 @@ static void qdev_e1000_reset(DeviceState *dev) static PCIDeviceInfo e1000_info = { .qdev.name = "e1000", + .qdev.driver_name = "ethernet", .qdev.desc = "Intel Gigabit Ethernet", .qdev.size = sizeof(E1000State), .qdev.reset = qdev_e1000_reset, diff --git a/hw/fdc.c b/hw/fdc.c index 51ca404..e7a1399 100644 --- a/hw/fdc.c +++ b/hw/fdc.c @@ -35,6 +35,7 @@ #include "sysbus.h" #include "qdev-addr.h" #include "blockdev.h" +#include "sysemu.h" /********************************************************/ /* debug Floppy devices */ @@ -523,6 +524,8 @@ typedef struct FDCtrlSysBus { typedef struct FDCtrlISABus { ISADevice busdev; struct FDCtrl state; + int32_t bootindexA; + int32_t bootindexB; } FDCtrlISABus; static uint32_t fdctrl_read (void *opaque, uint32_t reg) @@ -1992,6 +1995,14 @@ static int isabus_fdc_init1(ISADevice *dev) qdev_set_legacy_instance_id(&dev->qdev, iobase, 2); ret = fdctrl_init_common(fdctrl); + if (isa->bootindexA >= 0) { + qdev_add_boot_device_path(isa->bootindexA, &dev->qdev, "floppy@0"); + } + + if (isa->bootindexB >= 0) { + qdev_add_boot_device_path(isa->bootindexB, &dev->qdev, "floppy@1"); + } + return ret; } @@ -2051,6 +2062,8 @@ static ISADeviceInfo isa_fdc_info = { .qdev.props = (Property[]) { DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs), DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].bs), + DEFINE_PROP_INT32("bootindexA", FDCtrlISABus, bootindexA, -1), + DEFINE_PROP_INT32("bootindexB", FDCtrlISABus, bootindexB, -1), DEFINE_PROP_END_OF_LIST(), }, }; diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index 7db2f19..49d2ac1 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -21,6 +21,7 @@ #include "qemu-error.h" #include #include "blockdev.h" +#include "sysemu.h" /* --------------------------------- */ @@ -144,6 +145,11 @@ static int ide_drive_initfn(IDEDevice *dev) if (!dev->serial) { dev->serial = qemu_strdup(s->drive_serial_str); } + + if (dev->conf.bootindex >= 0) { + qdev_add_boot_device_path(dev->conf.bootindex, &dev->qdev, NULL); + } + return 0; } diff --git a/hw/qdev.c b/hw/qdev.c index 35858cb..2306b06 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -820,3 +820,55 @@ int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data) } return qdev_unplug(dev); } + +static int qdev_get_dev_path_helper(DeviceState *dev, char *p, int size) +{ + int l = 0; + + if (dev && dev->parent_bus) { + char *d; + l = qdev_get_dev_path_helper(dev->parent_bus->parent, p, size); + if (dev->parent_bus->info->get_dev_path) { + d = dev->parent_bus->info->get_dev_path(dev); + l += snprintf(p + l, size - l, "%s", d); + qemu_free(d); + } else { + l += snprintf(p + l, size - l, "%s", dev->info->name); + } + } + l += snprintf(p + l , size - l, "/"); + + return l; +} + +char* qdev_get_dev_path(DeviceState *dev) +{ + char path[128]; + int l; + + l = qdev_get_dev_path_helper(dev, path, 128); + + path[l-1] = '\0'; + + return strdup(path); +} + +void qdev_add_boot_device_path(int32_t bootindex, DeviceState *dev, + const char *name) +{ + char *devpath, *bootpath; + + devpath = qdev_get_dev_path(dev); + + if (name) { + bootpath = qemu_malloc(strlen(devpath) + strlen(name) + 2); + sprintf(bootpath, "%s/%s", devpath, name); + qemu_free(devpath); + } else { + bootpath = devpath; + } + + add_boot_device_path(bootindex, bootpath); + + qemu_free(bootpath); +} diff --git a/hw/qdev.h b/hw/qdev.h index a9a98f8..6d8a543 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -294,6 +294,9 @@ static inline const char *qdev_driver_name(DeviceState *dev) return dev->info->driver_name ? : dev->info->name; } +void qdev_add_boot_device_path(int32_t bootindex, DeviceState *dev, + const char *name); +char *qdev_get_dev_path(DeviceState *dev); /* This is a nasty hack to allow passing a NULL bus to qdev_create. */ extern struct BusInfo system_bus_info; diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index a1df26d..c3175fb 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -542,6 +542,10 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf) bdrv_set_removable(s->bs, 0); s->bs->buffer_alignment = conf->logical_block_size; + if (conf->bootindex >= 0) { + qdev_add_boot_device_path(conf->bootindex, dev, "virtio-disk@0"); + } + return &s->vdev; } diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 7e1688c..75a4407 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -1018,6 +1018,10 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf, virtio_net_save, virtio_net_load, n); n->vmstate = qemu_add_vm_change_state_handler(virtio_net_vmstate_change, n); + if (conf->bootindex >= 0) { + qdev_add_boot_device_path(conf->bootindex, dev, "ethernet-phy@0"); + } + return &n->vdev; } diff --git a/net.h b/net.h index 44c31a9..6ceca50 100644 --- a/net.h +++ b/net.h @@ -17,12 +17,14 @@ typedef struct NICConf { MACAddr macaddr; VLANState *vlan; VLANClientState *peer; + int32_t bootindex; } NICConf; #define DEFINE_NIC_PROPERTIES(_state, _conf) \ DEFINE_PROP_MACADDR("mac", _state, _conf.macaddr), \ DEFINE_PROP_VLAN("vlan", _state, _conf.vlan), \ - DEFINE_PROP_NETDEV("netdev", _state, _conf.peer) + DEFINE_PROP_NETDEV("netdev", _state, _conf.peer), \ + DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1) /* VLANs support */ diff --git a/sysemu.h b/sysemu.h index 849dc8c..cc35731 100644 --- a/sysemu.h +++ b/sysemu.h @@ -193,4 +193,13 @@ void rtc_change_mon_event(struct tm *tm); void register_devices(void); +typedef struct FWBootEntry FWBootEntry; + +struct FWBootEntry { + QTAILQ_ENTRY(FWBootEntry) link; + int32_t bootindex; + char *fw_device_path; +}; + +void add_boot_device_path(int32_t bootindex, char *fw_device_path); #endif diff --git a/vl.c b/vl.c index 42617c2..25d5767 100644 --- a/vl.c +++ b/vl.c @@ -234,6 +234,8 @@ const char *prom_envs[MAX_PROM_ENVS]; const char *nvram = NULL; int boot_menu; +QTAILQ_HEAD(, FWBootEntry) fw_boot_order = QTAILQ_HEAD_INITIALIZER(fw_boot_order); + int nb_numa_nodes; uint64_t node_mem[MAX_NODES]; uint64_t node_cpumask[MAX_NODES]; @@ -722,6 +724,28 @@ static void restore_boot_devices(void *opaque) qemu_free(standard_boot_devices); } +void add_boot_device_path(int32_t bootindex, char *fw_device_path) +{ + FWBootEntry *node = qemu_mallocz(sizeof(FWBootEntry)), *i; + + node->bootindex = bootindex; + node->fw_device_path = fw_device_path; + + printf("adding '%s' at index %d\n", fw_device_path, bootindex); + QTAILQ_FOREACH(i, &fw_boot_order, link) { + if (i->bootindex == bootindex) { + fprintf(stderr, "Two devices with same boot index %d (%s %s)\n", + bootindex, i->fw_device_path, fw_device_path); + exit(1); + } else if (i->bootindex < bootindex) { + continue; + } + QTAILQ_INSERT_BEFORE(i, node, link); + return; + } + QTAILQ_INSERT_TAIL(&fw_boot_order, node, link); +} + static void numa_add(const char *optarg) { char option[128]; -- 1.7.1