Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F175221073
D57516.id181761.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D57516.id181761.diff
View Options
diff --git a/usr.sbin/bhyve/bhyve_config.5 b/usr.sbin/bhyve/bhyve_config.5
--- a/usr.sbin/bhyve/bhyve_config.5
+++ b/usr.sbin/bhyve/bhyve_config.5
@@ -226,6 +226,9 @@
Stock keeping unit of the chassis.
It's also called product ID or purchase order number.
This value is used for the guest's System Management BIOS System Information structure.
+.It Va oemstring.N Ta string Ta none Ta
+This value is returned for the guest's Nth System Management BIOS System Information OEM Strings structure.
+Configuration can specify up to 255 strings.
.It Va rundir Ta String Ta Pa /var/run/bhyve/ Ta
Path to the runtime directory for
.Xr bhyve 8
diff --git a/usr.sbin/bhyve/smbiostbl.c b/usr.sbin/bhyve/smbiostbl.c
--- a/usr.sbin/bhyve/smbiostbl.c
+++ b/usr.sbin/bhyve/smbiostbl.c
@@ -29,10 +29,14 @@
#include <sys/param.h>
#include <assert.h>
+#include <ctype.h>
+#include <err.h>
#include <errno.h>
#include <md5.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <sysexits.h>
#include <unistd.h>
#include <uuid.h>
@@ -61,6 +65,7 @@
#define SMBIOS_TYPE_BOARD 2
#define SMBIOS_TYPE_CHASSIS 3
#define SMBIOS_TYPE_PROCESSOR 4
+#define SMBIOS_TYPE_OEM 11
#define SMBIOS_TYPE_MEMARRAY 16
#define SMBIOS_TYPE_MEMDEVICE 17
#define SMBIOS_TYPE_MEMARRAYMAP 19
@@ -250,6 +255,13 @@
uint16_t family2; /* processor family 2 */
} __packed;
+#define SMBIOS_TYPE11_MAX_COUNT 255
+
+struct smbios_table_type11 {
+ struct smbios_structure header;
+ uint8_t nstrings; /* number of oem strings to follow */
+} __packed;
+
/*
* Physical Memory Array
*/
@@ -479,6 +491,15 @@
const struct smbios_string *template_strings, char *curaddr, char **endaddr,
uint16_t *n);
+static const struct smbios_table_type11 smbios_type11_template = {
+ { SMBIOS_TYPE_OEM, sizeof(struct smbios_table_type11), 0 },
+ 0 /* first string */
+};
+
+static int smbios_type11_initializer(const struct smbios_structure *template_entry,
+ const struct smbios_string *template_strings, char *curaddr, char **endaddr,
+ uint16_t *n);
+
static const struct smbios_table_type16 smbios_type16_template = {
{ SMBIOS_TYPE_MEMARRAY, sizeof (struct smbios_table_type16), 0 },
SMBIOS_MAL_SYSMB,
@@ -582,6 +603,9 @@
{ (const struct smbios_structure *)&smbios_type4_template,
smbios_type4_strings,
smbios_type4_initializer },
+ { (const struct smbios_structure *)&smbios_type11_template,
+ NULL,
+ smbios_type11_initializer },
{ (const struct smbios_structure *)&smbios_type16_template,
NULL,
smbios_type16_initializer },
@@ -750,6 +774,171 @@
return (0);
}
+/*
+ * Gather oemstring values from oemstring node of config kvlist
+ *
+ * 1) Create a new kvlist, valid, to save off valid keys and values
+ * 2) Determine storage for any numerically missing keys
+ * 3) Create storage, make pointer array
+ *
+ * Returns: pointer to a char ** array of strings
+ * name, and value pointers
+ *
+ * Notes: The keys must be numeric and greater than zero. if not,
+ * they are ignored
+ *
+ * Any missing number keys will be added with a value
+ * of "N/A"
+ *
+ * There is a storage after the pointers in strings for
+ * all of the keys and values.
+ *
+ * The maximum number of strings allowed is 255
+ */
+
+static struct smbios_string *
+smbios_gather_type11_strings(void)
+{
+ char value[256], numberkey[6];
+ const char *na = "N/A";
+ char *np, *sp;
+ struct smbios_string* strings;
+ const char *name;
+ void *cookie = NULL;
+ nvlist_t *node;
+ nvlist_t *valid = NULL;
+ long maxnumber = 0;
+ long number;
+ int stringtotal = 0;
+ int fromconfig = 0;
+ int i, type;
+
+ /* find any oemstrings */
+ node = find_config_node("oemstring");
+ /* nothing to do if none */
+ if (!node)
+ return NULL;
+
+ /* add valid keys to nvlist: valid */
+ while ((name = nvlist_next(node, &type, &cookie)) != NULL) {
+ bool numbersonly = 1;
+ if (valid == NULL) {
+ valid = nvlist_create(0);
+ if (valid == NULL)
+ err(4, "Failed to create valid oemstring nvlist");
+ }
+
+ /* verify name is all numbers */
+ for (i = 0; name[i]; i++) {
+ if (!isdigit((int)name[i])) {
+ numbersonly = 0;
+ break;
+ }
+ }
+ if (!numbersonly)
+ errx(EX_USAGE, "Invalid format: %s should only contain digits", name);
+
+ /* get integer value of current name */
+ number = strtol(name, &np, 0);
+ if (number == 0 || number > SMBIOS_TYPE11_MAX_COUNT)
+ errx(EX_USAGE, "Invalid range: %s should be in 0-%d", name, SMBIOS_TYPE11_MAX_COUNT);
+
+ snprintf(numberkey, sizeof(numberkey), "%05d", (int)number);
+ if (number > maxnumber)
+ maxnumber = number;
+
+ /* add this string */
+ switch (type) {
+ case NV_TYPE_NUMBER:
+ snprintf(value, sizeof(value), "%ju", (uintmax_t)nvlist_get_number(node, name));
+ break;
+ case NV_TYPE_STRING:
+ snprintf(value, sizeof(value), "%s", nvlist_get_string(node, name));
+ break;
+ default:
+ /* errx(1, "Unexpected type '%d'", type); */
+ strcpy(value, na);
+ break;
+ }
+ nvlist_add_string(valid, numberkey, value);
+ /* add strings lengths plus trailing nulls */
+ stringtotal += (strlen(numberkey) + strlen(value) + 2);
+ fromconfig++;
+ }
+
+ /* add any storage required for missing values */
+ stringtotal += ((strlen(numberkey) + strlen(na) + 2) * (maxnumber - fromconfig));
+
+ /*
+ * create storage for the number of pairs plus NULL pair at end
+ * we also will store the key and value strings after the pointers
+ *
+ * storage layout is:
+ *
+ * j<node/value> pair(s) including a null pair
+ * followed by all strings
+ */
+ i = (sizeof(struct smbios_string) * (maxnumber + 1)) + stringtotal;
+ strings = malloc(i);
+ if (strings == NULL)
+ err(4, "oemstring allocation failed");
+
+ memset(strings, 0, i);
+ /* initialize sp to the first byte past the string descriptors */
+ sp = (char *)(strings + (maxnumber + 1));
+ maxnumber++;
+
+ /* populate the descriptors and save off the strings */
+ for (i=1; i < maxnumber; i++) {
+ const char *vp;
+ /* store number */
+ snprintf(numberkey, sizeof(numberkey), "%05d", i);
+ strcpy(sp, numberkey);
+ strings[i - 1].node = sp;
+ sp += strlen(numberkey) + 1;
+ /* store value or "N/A" */
+ if (nvlist_exists(valid, numberkey))
+ vp = nvlist_get_string(valid, numberkey);
+ else
+ vp = na;
+ strcpy(sp, vp);
+ strings[i - 1].value = sp;
+ sp += strlen(vp) + 1;
+ }
+
+ /* remove nvlist */
+ nvlist_destroy(valid);
+
+ /* return data */
+ return (strings);
+}
+
+static int
+smbios_type11_initializer(const struct smbios_structure *template_entry,
+ const struct smbios_string *template_strings, char *curaddr, char **endaddr,
+ uint16_t *n)
+{
+ struct smbios_table_type11 *type11;
+ struct smbios_string *type11_strings;
+ int i = 0;
+
+ type11_strings = smbios_gather_type11_strings();
+ template_strings = type11_strings;
+
+ smbios_generic_initializer(template_entry, template_strings,
+ curaddr, endaddr, n);
+
+ if (template_strings != NULL) {
+ /* count up strings */
+ type11 = (struct smbios_table_type11 *)curaddr;
+ for (i = 0; template_strings[i].node != NULL; i++)
+ ;
+ type11->nstrings = i;
+ }
+ free(type11_strings);
+ return (0);
+}
+
static int
smbios_type16_initializer(const struct smbios_structure *template_entry,
const struct smbios_string *template_strings, char *curaddr, char **endaddr,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 10, 5:23 AM (3 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40526590
Default Alt Text
D57516.id181761.diff (7 KB)
Attached To
Mode
D57516: bhyve: add configurable SMBIOS OEM Strings
Attached
Detach File
Event Timeline
Log In to Comment