qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] smbios: support setting OEM strings table


From: Michael S. Tsirkin
Subject: Re: [Qemu-devel] [PATCH] smbios: support setting OEM strings table
Date: Thu, 9 Nov 2017 21:49:46 +0200

On Thu, Nov 09, 2017 at 02:40:05PM +0000, Daniel P. Berrange wrote:
> Ping, any thoughts on this ? (not expecting it in this 2.11 release of course)

I queued this up.

> On Sat, Oct 28, 2017 at 09:51:36PM +0100, Daniel P. Berrange wrote:
> > The cloud-init program currently allows fetching of its data by repurposing 
> > of
> > the 'system' type 'serial' field. This is a clear abuse of the serial field 
> > that
> > would clash with other valid usage a virt management app might have for that
> > field.
> > 
> > Fortunately the SMBIOS defines an "OEM Strings" table whose puporse is to 
> > allow
> > exposing of arbitrary vendor specific strings to the operating system. This 
> > is
> > perfect for use with cloud-init, or as a way to pass arguments to OS 
> > installers
> > such as anaconda.
> > 
> > This patch makes it easier to support this with QEMU. e.g.
> > 
> >   $QEMU -smbios type=11,value=Hello,value=World,value=Tricky,,value=test
> > 
> > Which results in the guest seeing dmidecode data
> > 
> >   Handle 0x0E00, DMI type 11, 5 bytes
> >   OEM Strings
> >           String 1: Hello
> >           String 2: World
> >           String 3: Tricky,value=test
> > 
> > It is suggested that any app wanting to make use of this OEM strings 
> > capability
> > for accepting data from the host mgmt layer should use its name as a string
> > prefix. e.g. to expose OEM strings targetting both cloud init and anaconda 
> > in
> > parallel the mgmt app could set
> > 
> >   $QEMU -smbios 
> > type=11,value=cloud-init:ds=nocloud-net;s=http://10.10.0.1:8000/,\
> >         
> > value=anaconda:method=http://dl.fedoraproject.org/pub/fedora/linux/releases/25/x86_64/os
> > 
> > which would appear as
> > 
> >   Handle 0x0E00, DMI type 11, 5 bytes
> >   OEM Strings
> >           String 1: cloud-init:ds=nocloud-net;s=http://10.10.0.1:8000/
> >           String 2: 
> > anaconda:method=http://dl.fedoraproject.org/pub/fedora/linux/releases/25/x86_64/os
> > 
> > Use of such string prefixes means the app won't have to care which string 
> > slot
> > its data appears in.
> > 
> > Signed-off-by: Daniel P. Berrange <address@hidden>
> > ---
> >  hw/smbios/smbios.c         | 72 
> > ++++++++++++++++++++++++++++++++++++++++++++++
> >  hw/smbios/smbios_build.h   | 12 ++++++++
> >  include/hw/smbios/smbios.h |  6 ++++
> >  3 files changed, 90 insertions(+)
> > 
> > diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> > index 1a5437a07d..5d11f01874 100644
> > --- a/hw/smbios/smbios.c
> > +++ b/hw/smbios/smbios.c
> > @@ -96,6 +96,11 @@ static struct {
> >  } type4;
> >  
> >  static struct {
> > +    size_t nvalues;
> > +    const char **values;
> > +} type11;
> > +
> > +static struct {
> >      const char *loc_pfx, *bank, *manufacturer, *serial, *asset, *part;
> >      uint16_t speed;
> >  } type17;
> > @@ -282,6 +287,14 @@ static const QemuOptDesc qemu_smbios_type4_opts[] = {
> >      { /* end of list */ }
> >  };
> >  
> > +static const QemuOptDesc qemu_smbios_type11_opts[] = {
> > +    {
> > +        .name = "value",
> > +        .type = QEMU_OPT_STRING,
> > +        .help = "OEM string data",
> > +    },
> > +};
> > +
> >  static const QemuOptDesc qemu_smbios_type17_opts[] = {
> >      {
> >          .name = "type",
> > @@ -590,6 +603,27 @@ static void smbios_build_type_4_table(unsigned 
> > instance)
> >      smbios_type4_count++;
> >  }
> >  
> > +static void smbios_build_type_11_table(void)
> > +{
> > +    char count_str[128];
> > +    size_t i;
> > +
> > +    if (type11.nvalues == 0) {
> > +        return;
> > +    }
> > +
> > +    SMBIOS_BUILD_TABLE_PRE(11, 0xe00, true); /* required */
> > +
> > +    snprintf(count_str, sizeof(count_str), "%zu", type11.nvalues);
> > +    t->count = type11.nvalues;
> > +
> > +    for (i = 0; i < type11.nvalues; i++) {
> > +        SMBIOS_TABLE_SET_STR_LIST(11, type11.values[i]);
> > +    }
> > +
> > +    SMBIOS_BUILD_TABLE_POST;
> > +}
> > +
> >  #define ONE_KB ((ram_addr_t)1 << 10)
> >  #define ONE_MB ((ram_addr_t)1 << 20)
> >  #define ONE_GB ((ram_addr_t)1 << 30)
> > @@ -832,6 +866,8 @@ void smbios_get_tables(const struct 
> > smbios_phys_mem_area *mem_array,
> >              smbios_build_type_4_table(i);
> >          }
> >  
> > +        smbios_build_type_11_table();
> > +
> >  #define MAX_DIMM_SZ (16ll * ONE_GB)
> >  #define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
> >                                          : ((ram_size - 1) % MAX_DIMM_SZ) + 
> > 1)
> > @@ -882,6 +918,38 @@ static void save_opt(const char **dest, QemuOpts 
> > *opts, const char *name)
> >      }
> >  }
> >  
> > +
> > +struct opt_list {
> > +    const char *name;
> > +    size_t *ndest;
> > +    const char ***dest;
> > +};
> > +
> > +static int save_opt_one(void *opaque,
> > +                        const char *name, const char *value,
> > +                        Error **errp)
> > +{
> > +    struct opt_list *opt = opaque;
> > +
> > +    if (!g_str_equal(name, opt->name)) {
> > +        return 0;
> > +    }
> > +
> > +    *opt->dest = g_renew(const char *, *opt->dest, (*opt->ndest) + 1);
> > +    (*opt->dest)[*opt->ndest] = value;
> > +    (*opt->ndest)++;
> > +    return 0;
> > +}
> > +
> > +static void save_opt_list(size_t *ndest, const char ***dest,
> > +                          QemuOpts *opts, const char *name)
> > +{
> > +    struct opt_list opt = {
> > +        name, ndest, dest,
> > +    };
> > +    qemu_opt_foreach(opts, save_opt_one, &opt, NULL);
> > +}
> > +
> >  void smbios_entry_add(QemuOpts *opts, Error **errp)
> >  {
> >      const char *val;
> > @@ -1035,6 +1103,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
> >              save_opt(&type4.asset, opts, "asset");
> >              save_opt(&type4.part, opts, "part");
> >              return;
> > +        case 11:
> > +            qemu_opts_validate(opts, qemu_smbios_type11_opts, 
> > &error_fatal);
> > +            save_opt_list(&type11.nvalues, &type11.values, opts, "value");
> > +            return;
> >          case 17:
> >              qemu_opts_validate(opts, qemu_smbios_type17_opts, 
> > &error_fatal);
> >              save_opt(&type17.loc_pfx, opts, "loc_pfx");
> > diff --git a/hw/smbios/smbios_build.h b/hw/smbios/smbios_build.h
> > index 68b8b72e09..93b360d520 100644
> > --- a/hw/smbios/smbios_build.h
> > +++ b/hw/smbios/smbios_build.h
> > @@ -63,6 +63,18 @@ extern unsigned smbios_table_cnt;
> >          }                                                                 \
> >      } while (0)
> >  
> > +#define SMBIOS_TABLE_SET_STR_LIST(tbl_type, value)                        \
> > +    do {                                                                  \
> > +        int len = (value != NULL) ? strlen(value) + 1 : 0;                \
> > +        if (len > 1) {                                                    \
> > +            smbios_tables = g_realloc(smbios_tables,                      \
> > +                                      smbios_tables_len + len);           \
> > +            memcpy(smbios_tables + smbios_tables_len, value, len);        \
> > +            smbios_tables_len += len;                                     \
> > +            ++str_index;                                                  \
> > +        }                                                                 \
> > +    } while (0)
> > +
> >  #define SMBIOS_BUILD_TABLE_POST                                           \
> >      do {                                                                  \
> >          size_t term_cnt, t_size;                                          \
> > diff --git a/include/hw/smbios/smbios.h b/include/hw/smbios/smbios.h
> > index 31e8d5f47e..a83adb93d7 100644
> > --- a/include/hw/smbios/smbios.h
> > +++ b/include/hw/smbios/smbios.h
> > @@ -195,6 +195,12 @@ struct smbios_type_4 {
> >      uint16_t processor_family2;
> >  } QEMU_PACKED;
> >  
> > +/* SMBIOS type 11 - OEM strings */
> > +struct smbios_type_11 {
> > +    struct smbios_structure_header header;
> > +    uint8_t count;
> > +} QEMU_PACKED;
> > +
> >  /* SMBIOS type 16 - Physical Memory Array (v2.7) */
> >  struct smbios_type_16 {
> >      struct smbios_structure_header header;
> > -- 
> > 2.13.6
> > 
> 
> Regards,
> Daniel
> -- 
> |: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-            https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



reply via email to

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