[Settings] Expose SMBIOS via settings API
authorMichael Brown <mcb30@etherboot.org>
Fri, 28 Mar 2008 15:35:06 +0000 (15:35 +0000)
committerMichael Brown <mcb30@etherboot.org>
Fri, 28 Mar 2008 15:35:06 +0000 (15:35 +0000)
In particular, expose the system UUID as a setting ("smbios/uuid").

src/arch/i386/firmware/pcbios/smbios.c
src/arch/i386/firmware/pcbios/smbios_settings.c [new file with mode: 0644]
src/arch/i386/include/bits/errfile.h
src/arch/i386/include/bits/uuid.h [deleted file]
src/arch/i386/include/smbios.h
src/core/settings.c
src/include/gpxe/settings.h
src/include/gpxe/uuid.h
src/net/udp/dhcp.c

index 4d710d6..aa4f3f3 100644 (file)
 
 #include <stdint.h>
 #include <string.h>
-#include <stdio.h>
 #include <errno.h>
+#include <assert.h>
 #include <gpxe/uaccess.h>
-#include <gpxe/uuid.h>
 #include <realmode.h>
 #include <pnpbios.h>
 #include <smbios.h>
@@ -51,7 +50,7 @@ struct smbios_entry {
        /** Checksum */
        uint8_t checksum;
        /** Length */
-       uint8_t length;
+       uint8_t len;
        /** Major version */
        uint8_t major;
        /** Minor version */
@@ -67,7 +66,7 @@ struct smbios_entry {
        /** DMI checksum */
        uint8_t dmi_checksum;
        /** Structure table length */
-       uint16_t smbios_length;
+       uint16_t smbios_len;
        /** Structure table address */
        physaddr_t smbios_address;
        /** Number of SMBIOS structures */
@@ -86,49 +85,37 @@ struct smbios {
        /** Start of SMBIOS structures */
        userptr_t address;
        /** Length of SMBIOS structures */ 
-       size_t length;
+       size_t len;
        /** Number of SMBIOS structures */
        unsigned int count;
 };
 
-/**
- * SMBIOS strings descriptor
- *
- * This is returned as part of the search for an SMBIOS structure, and
- * contains the information needed for extracting the strings within
- * the "unformatted" portion of the structure.
- */
-struct smbios_strings {
-       /** Start of strings data */
-       userptr_t data;
-       /** Length of strings data */
-       size_t length;
+/** SMBIOS entry point descriptor */
+static struct smbios smbios = {
+       .address = UNULL,
 };
 
 /**
  * Find SMBIOS
  *
- * @ret smbios         SMBIOS entry point descriptor, or NULL if not found
+ * @ret rc             Return status code
  */
-static struct smbios * find_smbios ( void ) {
-       static struct smbios smbios = {
-               .address = UNULL,
-       };
+static int find_smbios ( void ) {
        union {
                struct smbios_entry entry;
                uint8_t bytes[256]; /* 256 is maximum length possible */
        } u;
-       unsigned int offset;
+       static unsigned int offset = 0;
        size_t len;
        unsigned int i;
        uint8_t sum;
 
-       /* Return cached result if available */
+       /* Return cached result if avaiable */
        if ( smbios.address != UNULL )
-               return &smbios;
+               return 0;
 
        /* Try to find SMBIOS */
-       for ( offset = 0 ; offset < 0x10000 ; offset += 0x10 ) {
+       for ( ; offset < 0x10000 ; offset += 0x10 ) {
 
                /* Read start of header and verify signature */
                copy_from_real ( &u.entry, BIOS_SEG, offset,
@@ -137,7 +124,7 @@ static struct smbios * find_smbios ( void ) {
                        continue;
 
                /* Read whole header and verify checksum */
-               len = u.entry.length;
+               len = u.entry.len;
                copy_from_real ( &u.bytes, BIOS_SEG, offset, len );
                for ( i = 0 , sum = 0 ; i < len ; i++ ) {
                        sum += u.bytes[i];
@@ -152,29 +139,27 @@ static struct smbios * find_smbios ( void ) {
                DBG ( "Found SMBIOS entry point at %04x:%04x\n",
                      BIOS_SEG, offset );
                smbios.address = phys_to_user ( u.entry.smbios_address );
-               smbios.length = u.entry.smbios_length;
+               smbios.len = u.entry.smbios_len;
                smbios.count = u.entry.smbios_count;
-               return &smbios;
+               return 0;
        }
 
        DBG ( "No SMBIOS found\n" );
-       return NULL;
+       return -ENODEV;
 }
 
 /**
  * Find SMBIOS strings terminator
  *
- * @v smbios           SMBIOS entry point descriptor
  * @v offset           Offset to start of strings
  * @ret offset         Offset to strings terminator, or 0 if not found
  */
-static size_t find_strings_terminator ( struct smbios *smbios,
-                                       size_t offset ) {
-       size_t max_offset = ( smbios->length - 2 );
+static size_t find_strings_terminator ( size_t offset ) {
+       size_t max_offset = ( smbios.len - 2 );
        uint16_t nulnul;
 
        for ( ; offset <= max_offset ; offset++ ) {
-               copy_from_user ( &nulnul, smbios->address, offset, 2 );
+               copy_from_user ( &nulnul, smbios.address, offset, 2 );
                if ( nulnul == 0 )
                        return ( offset + 1 );
        }
@@ -185,66 +170,52 @@ static size_t find_strings_terminator ( struct smbios *smbios,
  * Find specific structure type within SMBIOS
  *
  * @v type             Structure type to search for
- * @v structure                Buffer to fill in with structure
- * @v length           Length of buffer
- * @v strings          Strings descriptor to fill in, or NULL
+ * @v structure                SMBIOS structure descriptor to fill in
  * @ret rc             Return status code
  */
-int find_smbios_structure ( unsigned int type, void *structure,
-                           size_t length, struct smbios_strings *strings ) {
-       struct smbios *smbios;
-       struct smbios_header header;
-       struct smbios_strings temp_strings;
+int find_smbios_structure ( unsigned int type,
+                           struct smbios_structure *structure ) {
        unsigned int count = 0;
        size_t offset = 0;
        size_t strings_offset;
        size_t terminator_offset;
+       int rc;
 
-       /* Locate SMBIOS entry point */
-       if ( ! ( smbios = find_smbios() ) )
-               return -ENOENT;
-
-       /* Ensure that we have a usable strings descriptor buffer */
-       if ( ! strings )
-               strings = &temp_strings;
+       /* Find SMBIOS */
+       if ( ( rc = find_smbios() ) != 0 )
+               return rc;
 
        /* Scan through list of structures */
-       while ( ( ( offset + sizeof ( header ) ) < smbios->length ) &&
-               ( count < smbios->count ) ) {
+       while ( ( ( offset + sizeof ( structure->header ) ) < smbios.len )
+               && ( count < smbios.count ) ) {
 
                /* Read next SMBIOS structure header */
-               copy_from_user ( &header, smbios->address, offset,
-                                sizeof ( header ) );
+               copy_from_user ( &structure->header, smbios.address, offset,
+                                sizeof ( structure->header ) );
 
                /* Determine start and extent of strings block */
-               strings_offset = ( offset + header.length );
-               if ( strings_offset > smbios->length ) {
+               strings_offset = ( offset + structure->header.len );
+               if ( strings_offset > smbios.len ) {
                        DBG ( "SMBIOS structure at offset %zx with length "
                              "%x extends beyond SMBIOS\n", offset,
-                             header.length );
+                             structure->header.len );
                        return -ENOENT;
                }
-               terminator_offset =
-                       find_strings_terminator ( smbios, strings_offset );
+               terminator_offset = find_strings_terminator ( strings_offset );
                if ( ! terminator_offset ) {
                        DBG ( "SMBIOS structure at offset %zx has "
                              "unterminated strings section\n", offset );
                        return -ENOENT;
                }
-               strings->data = userptr_add ( smbios->address,
-                                             strings_offset );
-               strings->length = ( terminator_offset - strings_offset );
+               structure->strings_len = ( terminator_offset - strings_offset);
 
-               DBG ( "SMBIOS structure at offset %zx has type %d, "
-                     "length %x, strings length %zx\n",
-                     offset, header.type, header.length, strings->length );
+               DBG ( "SMBIOS structure at offset %zx has type %d, length %x, "
+                     "strings length %zx\n", offset, structure->header.type,
+                     structure->header.len, structure->strings_len );
 
                /* If this is the structure we want, return */
-               if ( header.type == type ) {
-                       if ( length > header.length )
-                               length = header.length;
-                       copy_from_user ( structure, smbios->address,
-                                        offset, length );
+               if ( structure->header.type == type ) {
+                       structure->offset = offset;
                        return 0;
                }
 
@@ -257,67 +228,65 @@ int find_smbios_structure ( unsigned int type, void *structure,
        return -ENOENT;
 }
 
+/**
+ * Copy SMBIOS structure
+ *
+ * @v structure                SMBIOS structure descriptor
+ * @v data             Buffer to hold SMBIOS structure
+ * @v len              Length of buffer
+ * @ret rc             Return status code
+ */
+int read_smbios_structure ( struct smbios_structure *structure,
+                           void *data, size_t len ) {
+
+       assert ( smbios.address != UNULL );
+
+       if ( len > structure->header.len )
+               len = structure->header.len;
+       copy_from_user ( data, smbios.address, structure->offset, len );
+       return 0;
+}
+
 /**
  * Find indexed string within SMBIOS structure
  *
- * @v strings          SMBIOS strings descriptor
+ * @v structure                SMBIOS structure descriptor
  * @v index            String index
- * @v buffer           Buffer for string
- * @v length           Length of string buffer
- * @ret rc             Return status code
+ * @v data             Buffer for string
+ * @v len              Length of string buffer
+ * @ret rc             Length of string, or negative error
  */
-int find_smbios_string ( struct smbios_strings *strings, unsigned int index,
-                        char *buffer, size_t length ) {
-       size_t offset = 0;
+int read_smbios_string ( struct smbios_structure *structure,
+                        unsigned int index, void *data, size_t len ) {
+       size_t strings_start = ( structure->offset + structure->header.len );
+       size_t strings_end = ( strings_start + structure->strings_len );
+       size_t offset;
        size_t string_len;
 
-       /* Zero buffer.  This ensures that a valid NUL terminator is
-        * always present (unless length==0).
-        */
-       memset ( buffer, 0, length );
-          
+       assert ( smbios.address != UNULL );
+
        /* String numbers start at 1 (0 is used to indicate "no string") */
        if ( ! index )
-               return 0;
+               return -ENOENT;
 
-       while ( offset < strings->length ) {
+       for ( offset = strings_start ; offset < strings_end ;
+             offset += ( string_len + 1 ) ) {
                /* Get string length.  This is known safe, since the
                 * smbios_strings struct is constructed so as to
                 * always end on a string boundary.
                 */
-               string_len = strlen_user ( strings->data, offset );
+               string_len = strlen_user ( smbios.address,
+                                          ( structure->offset + offset ) );
                if ( --index == 0 ) {
                        /* Copy string, truncating as necessary. */
-                       if ( string_len >= length )
-                               string_len = ( length - 1 );
-                       copy_from_user ( buffer, strings->data,
-                                        offset, string_len );
-                       return 0;
+                       if ( len > string_len )
+                               len = string_len;
+                       copy_from_user ( data, smbios.address,
+                                        ( structure->offset + offset ), len );
+                       return string_len;
                }
-               offset += ( string_len + 1 );
        }
 
        DBG ( "SMBIOS string index %d not found\n", index );
        return -ENOENT;
 }
-
-/**
- * Get UUID from SMBIOS
- *
- * @v uuid             UUID to fill in
- * @ret rc             Return status code
- */
-int smbios_get_uuid ( union uuid *uuid ) {
-       struct smbios_system_information sysinfo;
-       int rc;
-
-       if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_SYSTEM_INFORMATION,
-                                           &sysinfo, sizeof ( sysinfo ),
-                                           NULL ) ) != 0 )
-               return rc;
-
-       memcpy ( uuid, sysinfo.uuid, sizeof ( *uuid ) );
-       DBG ( "SMBIOS found UUID %s\n", uuid_ntoa ( uuid ) );
-
-       return 0;
-}
diff --git a/src/arch/i386/firmware/pcbios/smbios_settings.c b/src/arch/i386/firmware/pcbios/smbios_settings.c
new file mode 100644 (file)
index 0000000..de08ec5
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <gpxe/settings.h>
+#include <gpxe/init.h>
+#include <gpxe/uuid.h>
+#include <smbios.h>
+
+/**
+ * Construct SMBIOS raw-data tag
+ *
+ * @v _type            SMBIOS structure type number
+ * @v _structure       SMBIOS structure data type
+ * @v _field           Field within SMBIOS structure data type
+ * @ret tag            SMBIOS setting tag
+ */
+#define SMBIOS_RAW_TAG( _type, _structure, _field )            \
+       ( ( (_type) << 16 ) |                                   \
+         ( offsetof ( _structure, _field ) << 8 ) |            \
+         ( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
+
+/**
+ * Construct SMBIOS string tag
+ *
+ * @v _type            SMBIOS structure type number
+ * @v _structure       SMBIOS structure data type
+ * @v _field           Field within SMBIOS structure data type
+ * @ret tag            SMBIOS setting tag
+ */
+#define SMBIOS_STRING_TAG( _type, _structure, _field )         \
+       ( ( (_type) << 16 ) |                                   \
+         ( offsetof ( _structure, _field ) << 8 ) )
+
+/**
+ * Store value of SMBIOS setting
+ *
+ * @v settings         Settings block
+ * @v setting          Setting to store
+ * @v data             Setting data, or NULL to clear setting
+ * @v len              Length of setting data
+ * @ret rc             Return status code
+ */
+static int smbios_store ( struct settings *settings __unused,
+                         struct setting *setting __unused,
+                         const void *data __unused, size_t len __unused ) {
+       /* Cannot write data into SMBIOS */
+       return -ENOTSUP;
+}
+
+/**
+ * Fetch value of SMBIOS setting
+ *
+ * @v settings         Settings block, or NULL to search all blocks
+ * @v setting          Setting to fetch
+ * @v data             Buffer to fill with setting data
+ * @v len              Length of buffer
+ * @ret len            Length of setting data, or negative error
+ */
+static int smbios_fetch ( struct settings *settings __unused,
+                         struct setting *setting,
+                         void *data, size_t len ) {
+       struct smbios_structure structure;
+       unsigned int tag_type;
+       unsigned int tag_offset;
+       unsigned int tag_len;
+       int rc;
+
+       /* Split tag into type, offset and length */
+       tag_type = ( setting->tag >> 16 );
+       tag_offset = ( ( setting->tag >> 8 ) & 0xff );
+       tag_len = ( setting->tag & 0xff );
+       if ( ! tag_type )
+               return -ENOENT;
+
+       /* Find SMBIOS structure */
+       if ( ( rc = find_smbios_structure ( tag_type, &structure ) ) != 0 )
+               return rc;
+
+       {
+               uint8_t buf[structure.header.len];
+
+               /* Read SMBIOS structure */
+               if ( ( rc = read_smbios_structure ( &structure, buf,
+                                                   sizeof ( buf ) ) ) != 0 )
+                       return rc;
+
+               if ( tag_len == 0 ) {
+                       /* String */
+                       return read_smbios_string ( &structure,
+                                                   buf[tag_offset],
+                                                   data, len );
+               } else {
+                       /* Raw data */
+                       if ( len > tag_len )
+                               len = tag_len;
+                       memcpy ( data, &buf[tag_offset], len );
+                       return tag_len;
+               }
+       }
+}
+
+/** SMBIOS settings operations */
+static struct settings_operations smbios_settings_operations = {
+       .store = smbios_store,
+       .fetch = smbios_fetch,
+};
+
+/** SMBIOS settings */
+static struct settings smbios_settings = {
+       .refcnt = NULL,
+       .name = "smbios",
+       .siblings = LIST_HEAD_INIT ( smbios_settings.siblings ),
+       .children = LIST_HEAD_INIT ( smbios_settings.children ),
+       .op = &smbios_settings_operations,
+};
+
+/** Initialise SMBIOS settings */
+static void smbios_init ( void ) {
+       int rc;
+
+       if ( ( rc = register_settings ( &smbios_settings, NULL ) ) != 0 ) {
+               DBG ( "SMBIOS could not register settings: %s\n",
+                     strerror ( rc ) );
+               return;
+       }
+}
+
+/** SMBIOS settings initialiser */
+struct init_fn smbios_init_fn __init_fn ( INIT_NORMAL ) = {
+       .initialise = smbios_init,
+};
+
+/** UUID setting obtained via SMBIOS */
+struct setting uuid_setting __setting = {
+       .name = "uuid",
+       .description = "UUID",
+       .tag = SMBIOS_RAW_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
+                               struct smbios_system_information, uuid ),
+       .type = &setting_type_uuid,
+};
index 0f14021..678be04 100644 (file)
@@ -12,6 +12,7 @@
 #define ERRFILE_smbios         ( ERRFILE_ARCH | ERRFILE_CORE | 0x00030000 )
 #define ERRFILE_biosint                ( ERRFILE_ARCH | ERRFILE_CORE | 0x00040000 )
 #define ERRFILE_int13          ( ERRFILE_ARCH | ERRFILE_CORE | 0x00050000 )
+#define ERRFILE_smbios_settings        ( ERRFILE_ARCH | ERRFILE_CORE | 0x00060000 )
 
 #define ERRFILE_bootsector     ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00000000 )
 #define ERRFILE_bzimage               ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00010000 )
diff --git a/src/arch/i386/include/bits/uuid.h b/src/arch/i386/include/bits/uuid.h
deleted file mode 100644 (file)
index 0cbd320..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _I386_UUID_H
-#define _I386_UUID_H
-
-#include <smbios.h>
-
-static inline int get_uuid ( union uuid *uuid ) {
-       return smbios_get_uuid ( uuid );
-}
-
-#endif /* _I386_UUID_H */
index 821eda1..f2736dc 100644 (file)
@@ -13,11 +13,21 @@ struct smbios_header {
        /** Type */
        uint8_t type;
        /** Length */
-       uint8_t length;
+       uint8_t len;
        /** Handle */
        uint16_t handle;
 } __attribute__ (( packed ));
 
+/** SMBIOS structure descriptor */
+struct smbios_structure {
+       /** Copy of SMBIOS structure header */
+       struct smbios_header header;
+       /** Offset of structure within SMBIOS */
+       size_t offset;
+       /** Length of strings section */
+       size_t strings_len;
+};
+
 /** SMBIOS system information structure */
 struct smbios_system_information {
        /** SMBIOS structure header */
@@ -39,13 +49,12 @@ struct smbios_system_information {
 /** SMBIOS system information structure type */
 #define SMBIOS_TYPE_SYSTEM_INFORMATION 1
 
-struct smbios_strings;
 extern int find_smbios_structure ( unsigned int type,
-                                  void *structure, size_t length,
-                                  struct smbios_strings *strings );
-extern int find_smbios_string ( struct smbios_strings *strings,
+                                  struct smbios_structure *structure );
+extern int read_smbios_structure ( struct smbios_structure *structure,
+                                  void *data, size_t len );
+extern int read_smbios_string ( struct smbios_structure *structure,
                                unsigned int index,
-                               char *buffer, size_t length );
-extern int smbios_get_uuid ( union uuid *uuid );
+                               void *data, size_t len );
 
 #endif /* _SMBIOS_H */
index e7001d6..7525318 100644 (file)
@@ -27,6 +27,7 @@
 #include <gpxe/in.h>
 #include <gpxe/vsprintf.h>
 #include <gpxe/dhcp.h>
+#include <gpxe/uuid.h>
 #include <gpxe/settings.h>
 
 /** @file
@@ -487,6 +488,26 @@ unsigned long fetch_uintz_setting ( struct settings *settings,
        return value;
 }
 
+/**
+ * Fetch value of UUID setting
+ *
+ * @v settings         Settings block, or NULL to search all blocks
+ * @v setting          Setting to fetch
+ * @v uuid             UUID to fill in
+ * @ret len            Length of setting, or negative error
+ */
+int fetch_uuid_setting ( struct settings *settings, struct setting *setting,
+                        union uuid *uuid ) {
+       int len;
+
+       len = fetch_setting ( settings, setting, uuid, sizeof ( *uuid ) );
+       if ( len < 0 )
+               return len;
+       if ( len != sizeof ( *uuid ) )
+               return -ERANGE;
+       return len;
+}
+
 /**
  * Compare two settings
  *
@@ -752,11 +773,11 @@ static int storef_ipv4 ( struct settings *settings, struct setting *setting,
 static int fetchf_ipv4 ( struct settings *settings, struct setting *setting,
                         char *buf, size_t len ) {
        struct in_addr ipv4;
-       int rc;
+       int raw_len;
 
-       if ( ( rc = fetch_ipv4_setting ( settings, setting, &ipv4 ) ) < 0 )
-               return rc;
-       return snprintf ( buf, len, inet_ntoa ( ipv4 ) );
+       if ( ( raw_len = fetch_ipv4_setting ( settings, setting, &ipv4 ) ) < 0)
+               return raw_len;
+       return snprintf ( buf, len, "%s", inet_ntoa ( ipv4 ) );
 }
 
 /** An IPv4 address setting type */
@@ -985,6 +1006,46 @@ struct setting_type setting_type_hex __setting_type = {
        .fetchf = fetchf_hex,
 };
 
+/**
+ * Parse and store value of UUID setting
+ *
+ * @v settings         Settings block
+ * @v setting          Setting to store
+ * @v value            Formatted setting data
+ * @ret rc             Return status code
+ */
+static int storef_uuid ( struct settings *settings __unused,
+                        struct setting *setting __unused,
+                        const char *value __unused ) {
+       return -ENOTSUP;
+}
+
+/**
+ * Fetch and format value of UUID setting
+ *
+ * @v settings         Settings block, or NULL to search all blocks
+ * @v setting          Setting to fetch
+ * @v buf              Buffer to contain formatted value
+ * @v len              Length of buffer
+ * @ret len            Length of formatted value, or negative error
+ */
+static int fetchf_uuid ( struct settings *settings, struct setting *setting,
+                        char *buf, size_t len ) {
+       union uuid uuid;
+       int raw_len;
+
+       if ( ( raw_len = fetch_uuid_setting ( settings, setting, &uuid ) ) < 0)
+               return raw_len;
+       return snprintf ( buf, len, "%s", uuid_ntoa ( &uuid ) );
+}
+
+/** UUID setting type */
+struct setting_type setting_type_uuid __setting_type = {
+       .name = "uuid",
+       .storef = storef_uuid,
+       .fetchf = fetchf_uuid,
+};
+
 /******************************************************************************
  *
  * Settings
index 4082569..ae5a259 100644 (file)
@@ -15,6 +15,7 @@
 
 struct settings;
 struct in_addr;
+union uuid;
 
 /** A setting */
 struct setting {
@@ -177,6 +178,8 @@ extern long fetch_intz_setting ( struct settings *settings,
                                 struct setting *setting );
 extern unsigned long fetch_uintz_setting ( struct settings *settings,
                                           struct setting *setting );
+extern int fetch_uuid_setting ( struct settings *settings,
+                               struct setting *setting, union uuid *uuid );
 extern int setting_cmp ( struct setting *a, struct setting *b );
 
 extern struct settings * find_child_settings ( struct settings *parent,
@@ -198,6 +201,7 @@ extern struct setting_type setting_type_uint8 __setting_type;
 extern struct setting_type setting_type_uint16 __setting_type;
 extern struct setting_type setting_type_uint32 __setting_type;
 extern struct setting_type setting_type_hex __setting_type;
+extern struct setting_type setting_type_uuid __setting_type;
 
 extern struct setting ip_setting __setting;
 extern struct setting netmask_setting __setting;
@@ -210,6 +214,7 @@ extern struct setting username_setting __setting;
 extern struct setting password_setting __setting;
 extern struct setting priority_setting __setting;
 extern struct setting bios_drive_setting __setting;
+extern struct setting uuid_setting __setting;
 
 /**
  * Initialise a settings block
index a62735c..4f89be5 100644 (file)
@@ -8,9 +8,6 @@
 
 #include <stdint.h>
 
-union uuid;
-#include <bits/uuid.h>
-
 /** A universally unique ID */
 union uuid {
        /** Canonical form (00000000-0000-0000-0000-000000000000) */
index a793591..ecb7378 100644 (file)
@@ -214,7 +214,7 @@ static int dhcpset_store ( struct settings *settings, struct setting *setting,
 }
 
 /**
- * Fetch value of setting
+ * Fetch value of DHCP setting
  *
  * @v settings         Settings block, or NULL to search all blocks
  * @v setting          Setting to fetch
@@ -517,7 +517,8 @@ int dhcp_create_request ( struct dhcp_packet *dhcppkt,
 
        /* Add client UUID, if we have one.  Required for PXE. */
        client_uuid.type = DHCP_CLIENT_UUID_TYPE;
-       if ( ( rc = get_uuid ( &client_uuid.uuid ) ) == 0 ) {
+       if ( ( rc = fetch_uuid_setting ( NULL, &uuid_setting,
+                                        &client_uuid.uuid ) ) >= 0 ) {
                if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_CLIENT_UUID,
                                            &client_uuid,
                                            sizeof ( client_uuid ) ) ) != 0 ) {