Message ID | 1284479215-24679-1-git-send-email-bernhard.kohl@nsn.com |
---|---|
State | New |
Headers | show |
On Tue, Sep 14, 2010 at 05:46:55PM +0200, Bernhard Kohl wrote: > This patch was motivated by the following use case: In our system > the VMs usually have 4 NICs, any combination of virtio-net-pci and > pci-assign NIC devices. The VMs boot via gPXE preferably over the > pci-assign devices. > > There is no way to make this working with a combination of the > current options -net -pcidevice -device -optionrom -boot. > > With the parameter boot=off it is possible to avoid loading > and using gPXE option ROMs either for old style "-net nic" or > for "-device" NIC devices. So we can select which NIC is used > for booting. > > A side effect of the boot=off parameter is that unneeded ROMs > which might waste memory are not longer loaded. E.g. if you have > 2 virtio-net-pci and 2 pci-assign NICs in sum 4 option ROMs are > loaded and the virtio ROMs take precedence over the pci-assign > ROMs. The BIOS uses the first gPXE ROM which it finds and only > needs one of them even if there are more NICs of the same type. > > Without using the boot=on|off parameter the current behaviour > does not change. > > Signed-off-by: Thomas Ostler <thomas.ostler@nsn.com> > Signed-off-by: Bernhard Kohl <bernhard.kohl@nsn.com> I think this is useful, however: - We have bit properties which handle parsing on/off and other formats automatically. Please don't use string. - boot is not a great property name for PCI: what you actually do is disable option rom. So maybe call it 'rom' or something like that? - given you have added a property, it can now be changed with -device. and visible in -device ? This also has an advantage of only applying to pci devices (-net option would appear to apply to non-pci but have no effect). Please do not add more flag parsing in qdemu-options, net and vl.c To summarize, just add a qdev bit option and check the bit. > --- > hw/pci.c | 8 +++++++- > hw/pci.h | 1 + > hw/qdev.c | 6 ++++++ > hw/qdev.h | 1 + > net.c | 8 ++++++++ > net.h | 1 + > qemu-options.hx | 8 ++++++-- > vl.c | 27 +++++++++++++++++++++++++++ > 8 files changed, 57 insertions(+), 3 deletions(-) > > diff --git a/hw/pci.c b/hw/pci.c > index a98d6f3..055a2be 100644 > --- a/hw/pci.c > +++ b/hw/pci.c > @@ -71,6 +71,7 @@ static struct BusInfo pci_bus_info = { > DEFINE_PROP_UINT32("rombar", PCIDevice, rom_bar, 1), > DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present, > QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false), > + DEFINE_PROP_STRING("boot", PCIDevice, boot), > DEFINE_PROP_END_OF_LIST() > } > }; > @@ -1513,6 +1514,10 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, > > pci_dev = pci_create(bus, devfn, pci_nic_names[i]); > dev = &pci_dev->qdev; > + if (nd->name) > + dev->id = qemu_strdup(nd->name); > + if (nd->no_boot) > + dev->no_boot = 1; > qdev_set_nic_properties(dev, nd); > if (qdev_init(dev) < 0) > return NULL; > @@ -1693,7 +1698,8 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base) > /* rom loading */ > if (pci_dev->romfile == NULL && info->romfile != NULL) > pci_dev->romfile = qemu_strdup(info->romfile); > - pci_add_option_rom(pci_dev); > + if (!qdev->no_boot) > + pci_add_option_rom(pci_dev); > > if (qdev->hotplugged) { > rc = bus->hotplug(bus->hotplug_qdev, pci_dev, 1); > diff --git a/hw/pci.h b/hw/pci.h > index 1eab7e7..20aa038 100644 > --- a/hw/pci.h > +++ b/hw/pci.h > @@ -172,6 +172,7 @@ struct PCIDevice { > char *romfile; > ram_addr_t rom_offset; > uint32_t rom_bar; > + char *boot; > }; > > PCIDevice *pci_register_device(PCIBus *bus, const char *name, > diff --git a/hw/qdev.c b/hw/qdev.c > index 35858cb..8445bc9 100644 > --- a/hw/qdev.c > +++ b/hw/qdev.c > @@ -249,6 +249,10 @@ DeviceState *qdev_device_add(QemuOpts *opts) > qdev_free(qdev); > return NULL; > } > + if (qemu_opt_get(opts, "boot")) { > + if (!strcmp("off", qemu_strdup(qemu_opt_get(opts, "boot")))) > + qdev->no_boot = 1; > + } > if (qdev_init(qdev) < 0) { > qerror_report(QERR_DEVICE_INIT_FAILED, driver); > return NULL; > @@ -421,6 +425,8 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) > qdev_prop_exists(dev, "vectors")) { > qdev_prop_set_uint32(dev, "vectors", nd->nvectors); > } > + if (nd->no_boot) > + qdev_prop_parse(dev, "boot", "off"); > } > > static int next_block_unit[IF_COUNT]; > diff --git a/hw/qdev.h b/hw/qdev.h > index 579328a..e7df371 100644 > --- a/hw/qdev.h > +++ b/hw/qdev.h > @@ -45,6 +45,7 @@ struct DeviceState { > QLIST_ENTRY(DeviceState) sibling; > int instance_id_alias; > int alias_required_for_version; > + int no_boot; > }; > > typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent); > diff --git a/net.c b/net.c > index 3d0fde7..2370aca 100644 > --- a/net.c > +++ b/net.c > @@ -792,6 +792,10 @@ static int net_init_nic(QemuOpts *opts, > if (qemu_opt_get(opts, "addr")) { > nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr")); > } > + if (qemu_opt_get(opts, "boot")) { > + if (!strcmp("off", qemu_strdup(qemu_opt_get(opts, "boot")))) > + nd->no_boot = 1; > + } > > nd->macaddr[0] = 0x52; > nd->macaddr[1] = 0x54; > @@ -877,6 +881,10 @@ static const struct { > .type = QEMU_OPT_STRING, > .help = "PCI device address", > }, { > + .name = "boot", > + .type = QEMU_OPT_STRING, > + .help = "gPXE boot (on (default), off)", > + }, { > .name = "vectors", > .type = QEMU_OPT_NUMBER, > .help = "number of MSI-x vectors, 0 to disable MSI-X", > diff --git a/net.h b/net.h > index 518cf9c..288059b 100644 > --- a/net.h > +++ b/net.h > @@ -132,6 +132,7 @@ struct NICInfo { > VLANClientState *netdev; > int used; > int nvectors; > + int no_boot; > }; > > extern int nb_nics; > diff --git a/qemu-options.hx b/qemu-options.hx > index a0b5ae9..6084aa9 100644 > --- a/qemu-options.hx > +++ b/qemu-options.hx > @@ -959,8 +959,10 @@ DEF("smb", HAS_ARG, QEMU_OPTION_smb, "", QEMU_ARCH_ALL) > #endif > > DEF("net", HAS_ARG, QEMU_OPTION_net, > - "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n" > + "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v][,boot=on|off]\n" > " create a new Network Interface Card and connect it to VLAN 'n'\n" > + " use 'boot=on|off' to enable/disable loading of an option rom;\n" > + " loading enabled is the default\n" > #ifdef CONFIG_SLIRP > "-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=y|n]\n" > " [,hostname=host][,dhcpstart=addr][,dns=addr][,tftp=dir][,bootfile=f]\n" > @@ -1014,13 +1016,15 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, > #endif > "socket],id=str[,option][,option][,...]\n", QEMU_ARCH_ALL) > STEXI > -@item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}] > +@item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}][,boot=on|off] > @findex -net > Create a new Network Interface Card and connect it to VLAN @var{n} (@var{n} > = 0 is the default). The NIC is an e1000 by default on the PC > target. Optionally, the MAC address can be changed to @var{mac}, the > device address set to @var{addr} (PCI cards only), > and a @var{name} can be assigned for use in monitor commands. > +Optionally, with @option{boot=on|off}, you can enable/disable the loading of an option > +rom; by default, loading is enabled. > Optionally, for PCI cards, you can specify the number @var{v} of MSI-X vectors > that the card should have; this option currently only affects virtio cards; set > @var{v} = 0 to disable MSI-X. If no @option{-net} option is specified, a single > diff --git a/vl.c b/vl.c > index 3f45aa9..2aad6b1 100644 > --- a/vl.c > +++ b/vl.c > @@ -2459,6 +2459,33 @@ int main(int argc, char **argv, char **envp) > if (!qemu_opts_parse(qemu_find_opts("device"), optarg, 1)) { > exit(1); > } > + > + /* check whether option "boot" is present in the cmd string */ > + /* for this a modified string is created that does not */ > + /* contain the driver */ > + /* if "boot" is present and set to "on", the relevant */ > + /* variables are set in a way that net boot is possible and */ > + /* that a present "romfile" is loaded for the given device */ > + /* note that "default_net" is set to zero in order to avoid */ > + /* creation of a default device if option "-net" is not */ > + /* present in the complete command line */ > + { > + char mod_optarg[128]; > + char *mod_optarg_p; > + > + if ((mod_optarg_p = strchr(optarg, ','))) > + strcpy(mod_optarg, ++mod_optarg_p); > + else > + strcpy(mod_optarg, optarg); > + > + if (get_param_value(mod_optarg, 128, "boot", mod_optarg) != 0) { > + if (!strcmp("on", mod_optarg)) { > + char buf[8]="n"; > + pstrcpy(boot_devices, sizeof(boot_devices), buf); > + default_net = 0; > + } > + } > + } > break; > case QEMU_OPTION_smp: > smp_parse(optarg); > -- > 1.7.2.2 >
Am 19.09.2010 18:07, schrieb ext Michael S. Tsirkin: > On Tue, Sep 14, 2010 at 05:46:55PM +0200, Bernhard Kohl wrote: > >> > This patch was motivated by the following use case: In our system >> > the VMs usually have 4 NICs, any combination of virtio-net-pci and >> > pci-assign NIC devices. The VMs boot via gPXE preferably over the >> > pci-assign devices. >> > >> > There is no way to make this working with a combination of the >> > current options -net -pcidevice -device -optionrom -boot. >> > >> > With the parameter boot=off it is possible to avoid loading >> > and using gPXE option ROMs either for old style "-net nic" or >> > for "-device" NIC devices. So we can select which NIC is used >> > for booting. >> > >> > A side effect of the boot=off parameter is that unneeded ROMs >> > which might waste memory are not longer loaded. E.g. if you have >> > 2 virtio-net-pci and 2 pci-assign NICs in sum 4 option ROMs are >> > loaded and the virtio ROMs take precedence over the pci-assign >> > ROMs. The BIOS uses the first gPXE ROM which it finds and only >> > needs one of them even if there are more NICs of the same type. >> > >> > Without using the boot=on|off parameter the current behaviour >> > does not change. >> > >> > Signed-off-by: Thomas Ostler<thomas.ostler@nsn.com> >> > Signed-off-by: Bernhard Kohl<bernhard.kohl@nsn.com> >> > I think this is useful, however: > > - We have bit properties which handle parsing on/off > and other formats automatically. Please don't use string. > - boot is not a great property name for PCI: what > you actually do is disable option rom. > So maybe call it 'rom' or something like that? > Our main goal is to select a certain NIC's option rom for booting. So the other roms are not needed and not loaded. We used 'boot' as the property name as it is similar as in the '-drive' option to select a certain disk for booting. What's about to call it 'bootrom'? > - given you have added a property, it can now > be changed with -device. and visible in -device ? > This also has an advantage of only applying to pci devices > (-net option would appear to apply to non-pci but have no effect). > Please do not add more flag parsing in qdemu-options, net and vl.c > I think it is OK that we don't support this new feature for the old style '-net' option and only implement it for qdev / -device? > To summarize, just add a qdev bit option and check > the bit. > > In general, we will rework the patch and use all new qdev features. There are also some memory leaks as Chris told us, because of the usage of strdup. This rework might take 2 weeks because of vacation. Thanks Bernhard
On Tue, Sep 21, 2010 at 04:18:56PM +0200, Bernhard Kohl wrote: > Am 19.09.2010 18:07, schrieb ext Michael S. Tsirkin: > >On Tue, Sep 14, 2010 at 05:46:55PM +0200, Bernhard Kohl wrote: > >>> This patch was motivated by the following use case: In our system > >>> the VMs usually have 4 NICs, any combination of virtio-net-pci and > >>> pci-assign NIC devices. The VMs boot via gPXE preferably over the > >>> pci-assign devices. > >>> > There is no way to make this working with a combination of > >>the > >>> current options -net -pcidevice -device -optionrom -boot. > >>> > With the parameter boot=off it is possible to avoid > >>loading > >>> and using gPXE option ROMs either for old style "-net nic" or > >>> for "-device" NIC devices. So we can select which NIC is used > >>> for booting. > >>> > A side effect of the boot=off parameter is that unneeded > >>ROMs > >>> which might waste memory are not longer loaded. E.g. if you have > >>> 2 virtio-net-pci and 2 pci-assign NICs in sum 4 option ROMs are > >>> loaded and the virtio ROMs take precedence over the pci-assign > >>> ROMs. The BIOS uses the first gPXE ROM which it finds and only > >>> needs one of them even if there are more NICs of the same type. > >>> > Without using the boot=on|off parameter the current > >>behaviour > >>> does not change. > >>> > Signed-off-by: Thomas Ostler<thomas.ostler@nsn.com> > >>> Signed-off-by: Bernhard Kohl<bernhard.kohl@nsn.com> > >I think this is useful, however: > > > >- We have bit properties which handle parsing on/off > > and other formats automatically. Please don't use string. > >- boot is not a great property name for PCI: what > > you actually do is disable option rom. > > So maybe call it 'rom' or something like that? > Our main goal is to select a certain NIC's option rom for booting. > So the other roms are not needed and not loaded. We used 'boot' > as the property name as it is similar as in the '-drive' option to > select a certain disk for booting. What's about to call it 'bootrom'? Sounds good. > >- given you have added a property, it can now > > be changed with -device. and visible in -device ? > > This also has an advantage of only applying to pci devices > > (-net option would appear to apply to non-pci but have no effect). > > Please do not add more flag parsing in qdemu-options, net and vl.c > I think it is OK that we don't support this new feature for the old > style '-net' option and only implement it for qdev / -device? I think so, too. > >To summarize, just add a qdev bit option and check > >the bit. > > > In general, we will rework the patch and use all new qdev features. > There are also some memory leaks as Chris told us, because of the > usage of strdup. > > This rework might take 2 weeks because of vacation. > > Thanks > Bernhard Sounds good.
On 09/19/2010 11:07 AM, Michael S. Tsirkin wrote: > On Tue, Sep 14, 2010 at 05:46:55PM +0200, Bernhard Kohl wrote: > >> This patch was motivated by the following use case: In our system >> the VMs usually have 4 NICs, any combination of virtio-net-pci and >> pci-assign NIC devices. The VMs boot via gPXE preferably over the >> pci-assign devices. >> >> There is no way to make this working with a combination of the >> current options -net -pcidevice -device -optionrom -boot. >> >> With the parameter boot=off it is possible to avoid loading >> and using gPXE option ROMs either for old style "-net nic" or >> for "-device" NIC devices. So we can select which NIC is used >> for booting. >> >> A side effect of the boot=off parameter is that unneeded ROMs >> which might waste memory are not longer loaded. E.g. if you have >> 2 virtio-net-pci and 2 pci-assign NICs in sum 4 option ROMs are >> loaded and the virtio ROMs take precedence over the pci-assign >> ROMs. The BIOS uses the first gPXE ROM which it finds and only >> needs one of them even if there are more NICs of the same type. >> >> Without using the boot=on|off parameter the current behaviour >> does not change. >> >> Signed-off-by: Thomas Ostler<thomas.ostler@nsn.com> >> Signed-off-by: Bernhard Kohl<bernhard.kohl@nsn.com> >> > I think this is useful, however: > > - We have bit properties which handle parsing on/off > and other formats automatically. Please don't use string. > This is unneeded. Just do romfile= with -device and it will suppress the option rom loading. IOW: -device virtio-net-pci,romfile= -pcidevice ... But BTW, you should be able to select the pci device by doing: -boot cdn,menu=on And then hitting F12. We need to come up with a better way to let particular BEV or BCV devices to be chosen from the command line. Regards, Anthony Liguori > - boot is not a great property name for PCI: what > you actually do is disable option rom. > So maybe call it 'rom' or something like that? > - given you have added a property, it can now > be changed with -device. and visible in -device ? > This also has an advantage of only applying to pci devices > (-net option would appear to apply to non-pci but have no effect). > Please do not add more flag parsing in qdemu-options, net and vl.c > > To summarize, just add a qdev bit option and check > the bit. > > >> --- >> hw/pci.c | 8 +++++++- >> hw/pci.h | 1 + >> hw/qdev.c | 6 ++++++ >> hw/qdev.h | 1 + >> net.c | 8 ++++++++ >> net.h | 1 + >> qemu-options.hx | 8 ++++++-- >> vl.c | 27 +++++++++++++++++++++++++++ >> 8 files changed, 57 insertions(+), 3 deletions(-) >> >> diff --git a/hw/pci.c b/hw/pci.c >> index a98d6f3..055a2be 100644 >> --- a/hw/pci.c >> +++ b/hw/pci.c >> @@ -71,6 +71,7 @@ static struct BusInfo pci_bus_info = { >> DEFINE_PROP_UINT32("rombar", PCIDevice, rom_bar, 1), >> DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present, >> QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false), >> + DEFINE_PROP_STRING("boot", PCIDevice, boot), >> DEFINE_PROP_END_OF_LIST() >> } >> }; >> @@ -1513,6 +1514,10 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, >> >> pci_dev = pci_create(bus, devfn, pci_nic_names[i]); >> dev =&pci_dev->qdev; >> + if (nd->name) >> + dev->id = qemu_strdup(nd->name); >> + if (nd->no_boot) >> + dev->no_boot = 1; >> qdev_set_nic_properties(dev, nd); >> if (qdev_init(dev)< 0) >> return NULL; >> @@ -1693,7 +1698,8 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base) >> /* rom loading */ >> if (pci_dev->romfile == NULL&& info->romfile != NULL) >> pci_dev->romfile = qemu_strdup(info->romfile); >> - pci_add_option_rom(pci_dev); >> + if (!qdev->no_boot) >> + pci_add_option_rom(pci_dev); >> >> if (qdev->hotplugged) { >> rc = bus->hotplug(bus->hotplug_qdev, pci_dev, 1); >> diff --git a/hw/pci.h b/hw/pci.h >> index 1eab7e7..20aa038 100644 >> --- a/hw/pci.h >> +++ b/hw/pci.h >> @@ -172,6 +172,7 @@ struct PCIDevice { >> char *romfile; >> ram_addr_t rom_offset; >> uint32_t rom_bar; >> + char *boot; >> }; >> >> PCIDevice *pci_register_device(PCIBus *bus, const char *name, >> diff --git a/hw/qdev.c b/hw/qdev.c >> index 35858cb..8445bc9 100644 >> --- a/hw/qdev.c >> +++ b/hw/qdev.c >> @@ -249,6 +249,10 @@ DeviceState *qdev_device_add(QemuOpts *opts) >> qdev_free(qdev); >> return NULL; >> } >> + if (qemu_opt_get(opts, "boot")) { >> + if (!strcmp("off", qemu_strdup(qemu_opt_get(opts, "boot")))) >> + qdev->no_boot = 1; >> + } >> if (qdev_init(qdev)< 0) { >> qerror_report(QERR_DEVICE_INIT_FAILED, driver); >> return NULL; >> @@ -421,6 +425,8 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) >> qdev_prop_exists(dev, "vectors")) { >> qdev_prop_set_uint32(dev, "vectors", nd->nvectors); >> } >> + if (nd->no_boot) >> + qdev_prop_parse(dev, "boot", "off"); >> } >> >> static int next_block_unit[IF_COUNT]; >> diff --git a/hw/qdev.h b/hw/qdev.h >> index 579328a..e7df371 100644 >> --- a/hw/qdev.h >> +++ b/hw/qdev.h >> @@ -45,6 +45,7 @@ struct DeviceState { >> QLIST_ENTRY(DeviceState) sibling; >> int instance_id_alias; >> int alias_required_for_version; >> + int no_boot; >> }; >> >> typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent); >> diff --git a/net.c b/net.c >> index 3d0fde7..2370aca 100644 >> --- a/net.c >> +++ b/net.c >> @@ -792,6 +792,10 @@ static int net_init_nic(QemuOpts *opts, >> if (qemu_opt_get(opts, "addr")) { >> nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr")); >> } >> + if (qemu_opt_get(opts, "boot")) { >> + if (!strcmp("off", qemu_strdup(qemu_opt_get(opts, "boot")))) >> + nd->no_boot = 1; >> + } >> >> nd->macaddr[0] = 0x52; >> nd->macaddr[1] = 0x54; >> @@ -877,6 +881,10 @@ static const struct { >> .type = QEMU_OPT_STRING, >> .help = "PCI device address", >> }, { >> + .name = "boot", >> + .type = QEMU_OPT_STRING, >> + .help = "gPXE boot (on (default), off)", >> + }, { >> .name = "vectors", >> .type = QEMU_OPT_NUMBER, >> .help = "number of MSI-x vectors, 0 to disable MSI-X", >> diff --git a/net.h b/net.h >> index 518cf9c..288059b 100644 >> --- a/net.h >> +++ b/net.h >> @@ -132,6 +132,7 @@ struct NICInfo { >> VLANClientState *netdev; >> int used; >> int nvectors; >> + int no_boot; >> }; >> >> extern int nb_nics; >> diff --git a/qemu-options.hx b/qemu-options.hx >> index a0b5ae9..6084aa9 100644 >> --- a/qemu-options.hx >> +++ b/qemu-options.hx >> @@ -959,8 +959,10 @@ DEF("smb", HAS_ARG, QEMU_OPTION_smb, "", QEMU_ARCH_ALL) >> #endif >> >> DEF("net", HAS_ARG, QEMU_OPTION_net, >> - "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n" >> + "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v][,boot=on|off]\n" >> " create a new Network Interface Card and connect it to VLAN 'n'\n" >> + " use 'boot=on|off' to enable/disable loading of an option rom;\n" >> + " loading enabled is the default\n" >> #ifdef CONFIG_SLIRP >> "-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=y|n]\n" >> " [,hostname=host][,dhcpstart=addr][,dns=addr][,tftp=dir][,bootfile=f]\n" >> @@ -1014,13 +1016,15 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, >> #endif >> "socket],id=str[,option][,option][,...]\n", QEMU_ARCH_ALL) >> STEXI >> -@item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}] >> +@item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}][,boot=on|off] >> @findex -net >> Create a new Network Interface Card and connect it to VLAN @var{n} (@var{n} >> = 0 is the default). The NIC is an e1000 by default on the PC >> target. Optionally, the MAC address can be changed to @var{mac}, the >> device address set to @var{addr} (PCI cards only), >> and a @var{name} can be assigned for use in monitor commands. >> +Optionally, with @option{boot=on|off}, you can enable/disable the loading of an option >> +rom; by default, loading is enabled. >> Optionally, for PCI cards, you can specify the number @var{v} of MSI-X vectors >> that the card should have; this option currently only affects virtio cards; set >> @var{v} = 0 to disable MSI-X. If no @option{-net} option is specified, a single >> diff --git a/vl.c b/vl.c >> index 3f45aa9..2aad6b1 100644 >> --- a/vl.c >> +++ b/vl.c >> @@ -2459,6 +2459,33 @@ int main(int argc, char **argv, char **envp) >> if (!qemu_opts_parse(qemu_find_opts("device"), optarg, 1)) { >> exit(1); >> } >> + >> + /* check whether option "boot" is present in the cmd string */ >> + /* for this a modified string is created that does not */ >> + /* contain the driver */ >> + /* if "boot" is present and set to "on", the relevant */ >> + /* variables are set in a way that net boot is possible and */ >> + /* that a present "romfile" is loaded for the given device */ >> + /* note that "default_net" is set to zero in order to avoid */ >> + /* creation of a default device if option "-net" is not */ >> + /* present in the complete command line */ >> + { >> + char mod_optarg[128]; >> + char *mod_optarg_p; >> + >> + if ((mod_optarg_p = strchr(optarg, ','))) >> + strcpy(mod_optarg, ++mod_optarg_p); >> + else >> + strcpy(mod_optarg, optarg); >> + >> + if (get_param_value(mod_optarg, 128, "boot", mod_optarg) != 0) { >> + if (!strcmp("on", mod_optarg)) { >> + char buf[8]="n"; >> + pstrcpy(boot_devices, sizeof(boot_devices), buf); >> + default_net = 0; >> + } >> + } >> + } >> break; >> case QEMU_OPTION_smp: >> smp_parse(optarg); >> -- >> 1.7.2.2 >> >> >
On 09/21/2010 09:18 AM, Bernhard Kohl wrote: > Am 19.09.2010 18:07, schrieb ext Michael S. Tsirkin: >> On Tue, Sep 14, 2010 at 05:46:55PM +0200, Bernhard Kohl wrote: >>> > This patch was motivated by the following use case: In our system >>> > the VMs usually have 4 NICs, any combination of virtio-net-pci and >>> > pci-assign NIC devices. The VMs boot via gPXE preferably over the >>> > pci-assign devices. >>> > > There is no way to make this working with a combination of the >>> > current options -net -pcidevice -device -optionrom -boot. >>> > > With the parameter boot=off it is possible to avoid loading >>> > and using gPXE option ROMs either for old style "-net nic" or >>> > for "-device" NIC devices. So we can select which NIC is used >>> > for booting. >>> > > A side effect of the boot=off parameter is that unneeded ROMs >>> > which might waste memory are not longer loaded. E.g. if you have >>> > 2 virtio-net-pci and 2 pci-assign NICs in sum 4 option ROMs are >>> > loaded and the virtio ROMs take precedence over the pci-assign >>> > ROMs. The BIOS uses the first gPXE ROM which it finds and only >>> > needs one of them even if there are more NICs of the same type. >>> > > Without using the boot=on|off parameter the current behaviour >>> > does not change. >>> > > Signed-off-by: Thomas Ostler<thomas.ostler@nsn.com> >>> > Signed-off-by: Bernhard Kohl<bernhard.kohl@nsn.com> >> I think this is useful, however: >> >> - We have bit properties which handle parsing on/off >> and other formats automatically. Please don't use string. >> - boot is not a great property name for PCI: what >> you actually do is disable option rom. >> So maybe call it 'rom' or something like that? > Our main goal is to select a certain NIC's option rom for booting. > So the other roms are not needed and not loaded. We used 'boot' > as the property name as it is similar as in the '-drive' option to > select a certain disk for booting. What's about to call it 'bootrom'? This is the wrong approach. A rom doesn't have to be BEV and if it's not BEV or PnP, it may search for any device it can understand. So even if you did boot=on to the third NIC, the first NIC may be booted from. So just suppressing ROM loading does not imply that any specific device will be chosen to boot from. The correct approach is to communicate to the BIOS which of the boot entries you would like to be chosen by default. That means QEMU and SeaBIOS need to agree on a mechanism to map QEMU visible devices to a boot entry. Regards, Anthony Liguori
On Tue, Sep 21, 2010 at 10:16:29AM -0500, Anthony Liguori wrote: > On 09/19/2010 11:07 AM, Michael S. Tsirkin wrote: > >On Tue, Sep 14, 2010 at 05:46:55PM +0200, Bernhard Kohl wrote: > >>This patch was motivated by the following use case: In our system > >>the VMs usually have 4 NICs, any combination of virtio-net-pci and > >>pci-assign NIC devices. The VMs boot via gPXE preferably over the > >>pci-assign devices. > >> > >>There is no way to make this working with a combination of the > >>current options -net -pcidevice -device -optionrom -boot. > >> > >>With the parameter boot=off it is possible to avoid loading > >>and using gPXE option ROMs either for old style "-net nic" or > >>for "-device" NIC devices. So we can select which NIC is used > >>for booting. > >> > >>A side effect of the boot=off parameter is that unneeded ROMs > >>which might waste memory are not longer loaded. E.g. if you have > >>2 virtio-net-pci and 2 pci-assign NICs in sum 4 option ROMs are > >>loaded and the virtio ROMs take precedence over the pci-assign > >>ROMs. The BIOS uses the first gPXE ROM which it finds and only > >>needs one of them even if there are more NICs of the same type. > >> > >>Without using the boot=on|off parameter the current behaviour > >>does not change. > >> > >>Signed-off-by: Thomas Ostler<thomas.ostler@nsn.com> > >>Signed-off-by: Bernhard Kohl<bernhard.kohl@nsn.com> > >I think this is useful, however: > > > >- We have bit properties which handle parsing on/off > > and other formats automatically. Please don't use string. > > This is unneeded. Just do romfile= with -device and it will > suppress the option rom loading. > > IOW: > > -device virtio-net-pci,romfile= -pcidevice ... Cool, but needs to be documented. > But BTW, you should be able to select the pci device by doing: > > -boot cdn,menu=on > > And then hitting F12. We need to come up with a better way to let > particular BEV or BCV devices to be chosen from the command line. > > Regards, > > Anthony Liguori > > >- boot is not a great property name for PCI: what > > you actually do is disable option rom. > > So maybe call it 'rom' or something like that? > >- given you have added a property, it can now > > be changed with -device. and visible in -device ? > > This also has an advantage of only applying to pci devices > > (-net option would appear to apply to non-pci but have no effect). > > Please do not add more flag parsing in qdemu-options, net and vl.c > > > >To summarize, just add a qdev bit option and check > >the bit. > > > >>--- > >> hw/pci.c | 8 +++++++- > >> hw/pci.h | 1 + > >> hw/qdev.c | 6 ++++++ > >> hw/qdev.h | 1 + > >> net.c | 8 ++++++++ > >> net.h | 1 + > >> qemu-options.hx | 8 ++++++-- > >> vl.c | 27 +++++++++++++++++++++++++++ > >> 8 files changed, 57 insertions(+), 3 deletions(-) > >> > >>diff --git a/hw/pci.c b/hw/pci.c > >>index a98d6f3..055a2be 100644 > >>--- a/hw/pci.c > >>+++ b/hw/pci.c > >>@@ -71,6 +71,7 @@ static struct BusInfo pci_bus_info = { > >> DEFINE_PROP_UINT32("rombar", PCIDevice, rom_bar, 1), > >> DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present, > >> QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false), > >>+ DEFINE_PROP_STRING("boot", PCIDevice, boot), > >> DEFINE_PROP_END_OF_LIST() > >> } > >> }; > >>@@ -1513,6 +1514,10 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, > >> > >> pci_dev = pci_create(bus, devfn, pci_nic_names[i]); > >> dev =&pci_dev->qdev; > >>+ if (nd->name) > >>+ dev->id = qemu_strdup(nd->name); > >>+ if (nd->no_boot) > >>+ dev->no_boot = 1; > >> qdev_set_nic_properties(dev, nd); > >> if (qdev_init(dev)< 0) > >> return NULL; > >>@@ -1693,7 +1698,8 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base) > >> /* rom loading */ > >> if (pci_dev->romfile == NULL&& info->romfile != NULL) > >> pci_dev->romfile = qemu_strdup(info->romfile); > >>- pci_add_option_rom(pci_dev); > >>+ if (!qdev->no_boot) > >>+ pci_add_option_rom(pci_dev); > >> > >> if (qdev->hotplugged) { > >> rc = bus->hotplug(bus->hotplug_qdev, pci_dev, 1); > >>diff --git a/hw/pci.h b/hw/pci.h > >>index 1eab7e7..20aa038 100644 > >>--- a/hw/pci.h > >>+++ b/hw/pci.h > >>@@ -172,6 +172,7 @@ struct PCIDevice { > >> char *romfile; > >> ram_addr_t rom_offset; > >> uint32_t rom_bar; > >>+ char *boot; > >> }; > >> > >> PCIDevice *pci_register_device(PCIBus *bus, const char *name, > >>diff --git a/hw/qdev.c b/hw/qdev.c > >>index 35858cb..8445bc9 100644 > >>--- a/hw/qdev.c > >>+++ b/hw/qdev.c > >>@@ -249,6 +249,10 @@ DeviceState *qdev_device_add(QemuOpts *opts) > >> qdev_free(qdev); > >> return NULL; > >> } > >>+ if (qemu_opt_get(opts, "boot")) { > >>+ if (!strcmp("off", qemu_strdup(qemu_opt_get(opts, "boot")))) > >>+ qdev->no_boot = 1; > >>+ } > >> if (qdev_init(qdev)< 0) { > >> qerror_report(QERR_DEVICE_INIT_FAILED, driver); > >> return NULL; > >>@@ -421,6 +425,8 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) > >> qdev_prop_exists(dev, "vectors")) { > >> qdev_prop_set_uint32(dev, "vectors", nd->nvectors); > >> } > >>+ if (nd->no_boot) > >>+ qdev_prop_parse(dev, "boot", "off"); > >> } > >> > >> static int next_block_unit[IF_COUNT]; > >>diff --git a/hw/qdev.h b/hw/qdev.h > >>index 579328a..e7df371 100644 > >>--- a/hw/qdev.h > >>+++ b/hw/qdev.h > >>@@ -45,6 +45,7 @@ struct DeviceState { > >> QLIST_ENTRY(DeviceState) sibling; > >> int instance_id_alias; > >> int alias_required_for_version; > >>+ int no_boot; > >> }; > >> > >> typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent); > >>diff --git a/net.c b/net.c > >>index 3d0fde7..2370aca 100644 > >>--- a/net.c > >>+++ b/net.c > >>@@ -792,6 +792,10 @@ static int net_init_nic(QemuOpts *opts, > >> if (qemu_opt_get(opts, "addr")) { > >> nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr")); > >> } > >>+ if (qemu_opt_get(opts, "boot")) { > >>+ if (!strcmp("off", qemu_strdup(qemu_opt_get(opts, "boot")))) > >>+ nd->no_boot = 1; > >>+ } > >> > >> nd->macaddr[0] = 0x52; > >> nd->macaddr[1] = 0x54; > >>@@ -877,6 +881,10 @@ static const struct { > >> .type = QEMU_OPT_STRING, > >> .help = "PCI device address", > >> }, { > >>+ .name = "boot", > >>+ .type = QEMU_OPT_STRING, > >>+ .help = "gPXE boot (on (default), off)", > >>+ }, { > >> .name = "vectors", > >> .type = QEMU_OPT_NUMBER, > >> .help = "number of MSI-x vectors, 0 to disable MSI-X", > >>diff --git a/net.h b/net.h > >>index 518cf9c..288059b 100644 > >>--- a/net.h > >>+++ b/net.h > >>@@ -132,6 +132,7 @@ struct NICInfo { > >> VLANClientState *netdev; > >> int used; > >> int nvectors; > >>+ int no_boot; > >> }; > >> > >> extern int nb_nics; > >>diff --git a/qemu-options.hx b/qemu-options.hx > >>index a0b5ae9..6084aa9 100644 > >>--- a/qemu-options.hx > >>+++ b/qemu-options.hx > >>@@ -959,8 +959,10 @@ DEF("smb", HAS_ARG, QEMU_OPTION_smb, "", QEMU_ARCH_ALL) > >> #endif > >> > >> DEF("net", HAS_ARG, QEMU_OPTION_net, > >>- "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n" > >>+ "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v][,boot=on|off]\n" > >> " create a new Network Interface Card and connect it to VLAN 'n'\n" > >>+ " use 'boot=on|off' to enable/disable loading of an option rom;\n" > >>+ " loading enabled is the default\n" > >> #ifdef CONFIG_SLIRP > >> "-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=y|n]\n" > >> " [,hostname=host][,dhcpstart=addr][,dns=addr][,tftp=dir][,bootfile=f]\n" > >>@@ -1014,13 +1016,15 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, > >> #endif > >> "socket],id=str[,option][,option][,...]\n", QEMU_ARCH_ALL) > >> STEXI > >>-@item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}] > >>+@item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}][,boot=on|off] > >> @findex -net > >> Create a new Network Interface Card and connect it to VLAN @var{n} (@var{n} > >> = 0 is the default). The NIC is an e1000 by default on the PC > >> target. Optionally, the MAC address can be changed to @var{mac}, the > >> device address set to @var{addr} (PCI cards only), > >> and a @var{name} can be assigned for use in monitor commands. > >>+Optionally, with @option{boot=on|off}, you can enable/disable the loading of an option > >>+rom; by default, loading is enabled. > >> Optionally, for PCI cards, you can specify the number @var{v} of MSI-X vectors > >> that the card should have; this option currently only affects virtio cards; set > >> @var{v} = 0 to disable MSI-X. If no @option{-net} option is specified, a single > >>diff --git a/vl.c b/vl.c > >>index 3f45aa9..2aad6b1 100644 > >>--- a/vl.c > >>+++ b/vl.c > >>@@ -2459,6 +2459,33 @@ int main(int argc, char **argv, char **envp) > >> if (!qemu_opts_parse(qemu_find_opts("device"), optarg, 1)) { > >> exit(1); > >> } > >>+ > >>+ /* check whether option "boot" is present in the cmd string */ > >>+ /* for this a modified string is created that does not */ > >>+ /* contain the driver */ > >>+ /* if "boot" is present and set to "on", the relevant */ > >>+ /* variables are set in a way that net boot is possible and */ > >>+ /* that a present "romfile" is loaded for the given device */ > >>+ /* note that "default_net" is set to zero in order to avoid */ > >>+ /* creation of a default device if option "-net" is not */ > >>+ /* present in the complete command line */ > >>+ { > >>+ char mod_optarg[128]; > >>+ char *mod_optarg_p; > >>+ > >>+ if ((mod_optarg_p = strchr(optarg, ','))) > >>+ strcpy(mod_optarg, ++mod_optarg_p); > >>+ else > >>+ strcpy(mod_optarg, optarg); > >>+ > >>+ if (get_param_value(mod_optarg, 128, "boot", mod_optarg) != 0) { > >>+ if (!strcmp("on", mod_optarg)) { > >>+ char buf[8]="n"; > >>+ pstrcpy(boot_devices, sizeof(boot_devices), buf); > >>+ default_net = 0; > >>+ } > >>+ } > >>+ } > >> break; > >> case QEMU_OPTION_smp: > >> smp_parse(optarg); > >>-- > >>1.7.2.2 > >>
diff --git a/hw/pci.c b/hw/pci.c index a98d6f3..055a2be 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -71,6 +71,7 @@ static struct BusInfo pci_bus_info = { DEFINE_PROP_UINT32("rombar", PCIDevice, rom_bar, 1), DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present, QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false), + DEFINE_PROP_STRING("boot", PCIDevice, boot), DEFINE_PROP_END_OF_LIST() } }; @@ -1513,6 +1514,10 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, pci_dev = pci_create(bus, devfn, pci_nic_names[i]); dev = &pci_dev->qdev; + if (nd->name) + dev->id = qemu_strdup(nd->name); + if (nd->no_boot) + dev->no_boot = 1; qdev_set_nic_properties(dev, nd); if (qdev_init(dev) < 0) return NULL; @@ -1693,7 +1698,8 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base) /* rom loading */ if (pci_dev->romfile == NULL && info->romfile != NULL) pci_dev->romfile = qemu_strdup(info->romfile); - pci_add_option_rom(pci_dev); + if (!qdev->no_boot) + pci_add_option_rom(pci_dev); if (qdev->hotplugged) { rc = bus->hotplug(bus->hotplug_qdev, pci_dev, 1); diff --git a/hw/pci.h b/hw/pci.h index 1eab7e7..20aa038 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -172,6 +172,7 @@ struct PCIDevice { char *romfile; ram_addr_t rom_offset; uint32_t rom_bar; + char *boot; }; PCIDevice *pci_register_device(PCIBus *bus, const char *name, diff --git a/hw/qdev.c b/hw/qdev.c index 35858cb..8445bc9 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -249,6 +249,10 @@ DeviceState *qdev_device_add(QemuOpts *opts) qdev_free(qdev); return NULL; } + if (qemu_opt_get(opts, "boot")) { + if (!strcmp("off", qemu_strdup(qemu_opt_get(opts, "boot")))) + qdev->no_boot = 1; + } if (qdev_init(qdev) < 0) { qerror_report(QERR_DEVICE_INIT_FAILED, driver); return NULL; @@ -421,6 +425,8 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) qdev_prop_exists(dev, "vectors")) { qdev_prop_set_uint32(dev, "vectors", nd->nvectors); } + if (nd->no_boot) + qdev_prop_parse(dev, "boot", "off"); } static int next_block_unit[IF_COUNT]; diff --git a/hw/qdev.h b/hw/qdev.h index 579328a..e7df371 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -45,6 +45,7 @@ struct DeviceState { QLIST_ENTRY(DeviceState) sibling; int instance_id_alias; int alias_required_for_version; + int no_boot; }; typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent); diff --git a/net.c b/net.c index 3d0fde7..2370aca 100644 --- a/net.c +++ b/net.c @@ -792,6 +792,10 @@ static int net_init_nic(QemuOpts *opts, if (qemu_opt_get(opts, "addr")) { nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr")); } + if (qemu_opt_get(opts, "boot")) { + if (!strcmp("off", qemu_strdup(qemu_opt_get(opts, "boot")))) + nd->no_boot = 1; + } nd->macaddr[0] = 0x52; nd->macaddr[1] = 0x54; @@ -877,6 +881,10 @@ static const struct { .type = QEMU_OPT_STRING, .help = "PCI device address", }, { + .name = "boot", + .type = QEMU_OPT_STRING, + .help = "gPXE boot (on (default), off)", + }, { .name = "vectors", .type = QEMU_OPT_NUMBER, .help = "number of MSI-x vectors, 0 to disable MSI-X", diff --git a/net.h b/net.h index 518cf9c..288059b 100644 --- a/net.h +++ b/net.h @@ -132,6 +132,7 @@ struct NICInfo { VLANClientState *netdev; int used; int nvectors; + int no_boot; }; extern int nb_nics; diff --git a/qemu-options.hx b/qemu-options.hx index a0b5ae9..6084aa9 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -959,8 +959,10 @@ DEF("smb", HAS_ARG, QEMU_OPTION_smb, "", QEMU_ARCH_ALL) #endif DEF("net", HAS_ARG, QEMU_OPTION_net, - "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n" + "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v][,boot=on|off]\n" " create a new Network Interface Card and connect it to VLAN 'n'\n" + " use 'boot=on|off' to enable/disable loading of an option rom;\n" + " loading enabled is the default\n" #ifdef CONFIG_SLIRP "-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=y|n]\n" " [,hostname=host][,dhcpstart=addr][,dns=addr][,tftp=dir][,bootfile=f]\n" @@ -1014,13 +1016,15 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, #endif "socket],id=str[,option][,option][,...]\n", QEMU_ARCH_ALL) STEXI -@item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}] +@item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}][,boot=on|off] @findex -net Create a new Network Interface Card and connect it to VLAN @var{n} (@var{n} = 0 is the default). The NIC is an e1000 by default on the PC target. Optionally, the MAC address can be changed to @var{mac}, the device address set to @var{addr} (PCI cards only), and a @var{name} can be assigned for use in monitor commands. +Optionally, with @option{boot=on|off}, you can enable/disable the loading of an option +rom; by default, loading is enabled. Optionally, for PCI cards, you can specify the number @var{v} of MSI-X vectors that the card should have; this option currently only affects virtio cards; set @var{v} = 0 to disable MSI-X. If no @option{-net} option is specified, a single diff --git a/vl.c b/vl.c index 3f45aa9..2aad6b1 100644 --- a/vl.c +++ b/vl.c @@ -2459,6 +2459,33 @@ int main(int argc, char **argv, char **envp) if (!qemu_opts_parse(qemu_find_opts("device"), optarg, 1)) { exit(1); } + + /* check whether option "boot" is present in the cmd string */ + /* for this a modified string is created that does not */ + /* contain the driver */ + /* if "boot" is present and set to "on", the relevant */ + /* variables are set in a way that net boot is possible and */ + /* that a present "romfile" is loaded for the given device */ + /* note that "default_net" is set to zero in order to avoid */ + /* creation of a default device if option "-net" is not */ + /* present in the complete command line */ + { + char mod_optarg[128]; + char *mod_optarg_p; + + if ((mod_optarg_p = strchr(optarg, ','))) + strcpy(mod_optarg, ++mod_optarg_p); + else + strcpy(mod_optarg, optarg); + + if (get_param_value(mod_optarg, 128, "boot", mod_optarg) != 0) { + if (!strcmp("on", mod_optarg)) { + char buf[8]="n"; + pstrcpy(boot_devices, sizeof(boot_devices), buf); + default_net = 0; + } + } + } break; case QEMU_OPTION_smp: smp_parse(optarg);