mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
hostname: add hardware Stock-Keeping Unit
Add support for the hardware Stock-Keeping Unit (SKU). The SKU describes a distinct type of hardware for sale, purchase or inventory management. The value is read from the file /etc/machine-info or DMI as fallback. The integration provides an unified interface to collect detail hardware information. The /etc/machine-info entry enables embedded devices without UEFI support to read the information from a custom store.
This commit is contained in:
@@ -23,6 +23,16 @@ dmi:*:pnTobefilledbyO.E.M.:*
|
||||
dmi:*:pnToBeFilledByO.E.M.:*
|
||||
ID_PRODUCT_NAME_IS_RUBBISH=1
|
||||
|
||||
dmi:*:skuDefaultstring:*
|
||||
dmi:*:skuDefault string:*
|
||||
dmi:*:skuN/A:*
|
||||
dmi:*:skuO.E.M.:*
|
||||
dmi:*:skuOEM:*
|
||||
dmi:*:skuTobefilledbyO.E.M.:*
|
||||
dmi:*:skuToBeFilledByO.E.M.:*
|
||||
dmi:*:skuTo Be Filled By O.E.M.:*
|
||||
ID_PRODUCT_SKU_IS_RUBBISH=1
|
||||
|
||||
dmi:*:catDefaultstring:*
|
||||
dmi:*:catDefault string:*
|
||||
dmi:*:catN/A:*
|
||||
|
||||
@@ -154,6 +154,15 @@
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v251"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>HARDWARE_SKU=</varname></term>
|
||||
|
||||
<listitem><para>Specifies the hardware SKU (Stock-Keeping Unit). If unspecified, the hardware
|
||||
SKU set in DMI will be used.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -94,6 +94,8 @@ node /org/freedesktop/hostname1 {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s HardwareModel = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s HardwareSKU = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s FirmwareVersion = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s FirmwareVendor = '...';
|
||||
@@ -180,6 +182,8 @@ node /org/freedesktop/hostname1 {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="HardwareModel"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="HardwareSKU"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="FirmwareVersion"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="FirmwareVendor"/>
|
||||
@@ -306,9 +310,11 @@ node /org/freedesktop/hostname1 {
|
||||
to the <varname>IMAGE_ID=</varname> and <varname>IMAGE_VERSION=</varname> fields of the
|
||||
<filename>os-release</filename> file.</para>
|
||||
|
||||
<para><varname>HardwareVendor</varname> and <varname>HardwareModel</varname> expose information about the
|
||||
vendor of the hardware of the system. If no such information can be determined these properties are set
|
||||
to empty strings.</para>
|
||||
<para><varname>HardwareVendor</varname>, <varname>HardwareModel</varname>, and <varname>HardwareSKU</varname>
|
||||
expose vendor information about the hardware of the system. The stock keeping unit (SKU) describes a
|
||||
distinct type of hardware for sale, purchase or inventory management. The SKU is only available if it
|
||||
deviates from the model. If no such information can be determined these properties are set to empty
|
||||
strings.</para>
|
||||
|
||||
<para><varname>FirmwareVersion</varname> and <varname>FirmwareVendor</varname> expose information about
|
||||
the system's firmware, i.e. a version string and a vendor name. If no such information can be determined
|
||||
@@ -473,8 +479,9 @@ node /org/freedesktop/hostname1 {
|
||||
<varname>FirmwareDate</varname> were added in version 253.</para>
|
||||
<para><varname>MachineID</varname>, <varname>BootID</varname> and
|
||||
<varname>VSockCID</varname> were added in version 256.</para>
|
||||
<para><varname>ChassisAssetTag</varname>, <varname>OperatingSystemImageID</varname> and
|
||||
<varname>OperatingSystemImageVersion</varname> were added in version 258.</para>
|
||||
<para><varname>ChassisAssetTag</varname>, <varname>OperatingSystemImageID</varname>,
|
||||
<varname>OperatingSystemImageVersion</varname>, and <varname>HardwareSKU</varname>
|
||||
were added in version 258.</para>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@ ENV{ID_SYSFS_ATTRIBUTE_MODEL}=="product_version", ENV{ID_MODEL}="$attr{product_v
|
||||
ENV{ID_VENDOR}=="", ENV{ID_VENDOR}="$attr{board_vendor}"
|
||||
ENV{ID_MODEL}=="", ENV{ID_MODEL}="$attr{board_name}"
|
||||
|
||||
# stock keeping unit
|
||||
ENV{ID_PRODUCT_SKU_IS_RUBBISH}!="1", ENV{ID_SKU}="$attr{product_sku}"
|
||||
|
||||
# chassis asset tag
|
||||
ENV{MODALIAS}!="", ATTR{chassis_asset_tag}!="", IMPORT{builtin}="hwdb '$attr{modalias}cat$attr{chassis_asset_tag}:'"
|
||||
ENV{ID_CHASSIS_ASSET_TAG_IS_RUBBISH}!="1", ENV{ID_CHASSIS_ASSET_TAG}="$attr{chassis_asset_tag}"
|
||||
|
||||
@@ -66,6 +66,7 @@ typedef struct StatusInfo {
|
||||
const char *hardware_serial;
|
||||
sd_id128_t product_uuid;
|
||||
uint32_t vsock_cid;
|
||||
const char *hardware_sku;
|
||||
} StatusInfo;
|
||||
|
||||
static const char* chassis_string_to_glyph(const char *chassis) {
|
||||
@@ -320,6 +321,14 @@ static int print_status_info(StatusInfo *i) {
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
|
||||
if (!isempty(i->hardware_sku)) {
|
||||
r = table_add_many(table,
|
||||
TABLE_FIELD, "Hardware SKU",
|
||||
TABLE_STRING, i->hardware_sku);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
|
||||
if (!isempty(i->firmware_version)) {
|
||||
r = table_add_many(table,
|
||||
TABLE_FIELD, "Firmware Version",
|
||||
@@ -413,6 +422,7 @@ static int show_all_names(sd_bus *bus) {
|
||||
{ "HomeURL", "s", NULL, offsetof(StatusInfo, home_url) },
|
||||
{ "HardwareVendor", "s", NULL, offsetof(StatusInfo, hardware_vendor) },
|
||||
{ "HardwareModel", "s", NULL, offsetof(StatusInfo, hardware_model) },
|
||||
{ "HardwareSKU", "s", NULL, offsetof(StatusInfo, hardware_sku) },
|
||||
{ "FirmwareVersion", "s", NULL, offsetof(StatusInfo, firmware_version) },
|
||||
{ "FirmwareDate", "t", NULL, offsetof(StatusInfo, firmware_date) },
|
||||
{ "MachineID", "ay", bus_map_id128, offsetof(StatusInfo, machine_id) },
|
||||
|
||||
@@ -66,6 +66,7 @@ typedef enum {
|
||||
PROP_LOCATION,
|
||||
PROP_HARDWARE_VENDOR,
|
||||
PROP_HARDWARE_MODEL,
|
||||
PROP_HARDWARE_SKU,
|
||||
|
||||
/* Read from /etc/os-release (or /usr/lib/os-release) */
|
||||
PROP_OS_PRETTY_NAME,
|
||||
@@ -170,7 +171,8 @@ static void context_read_machine_info(Context *c) {
|
||||
(UINT64_C(1) << PROP_DEPLOYMENT) |
|
||||
(UINT64_C(1) << PROP_LOCATION) |
|
||||
(UINT64_C(1) << PROP_HARDWARE_VENDOR) |
|
||||
(UINT64_C(1) << PROP_HARDWARE_MODEL));
|
||||
(UINT64_C(1) << PROP_HARDWARE_MODEL) |
|
||||
(UINT64_C(1) << PROP_HARDWARE_SKU));
|
||||
|
||||
r = parse_env_file(NULL, "/etc/machine-info",
|
||||
"PRETTY_HOSTNAME", &c->data[PROP_PRETTY_HOSTNAME],
|
||||
@@ -179,7 +181,8 @@ static void context_read_machine_info(Context *c) {
|
||||
"DEPLOYMENT", &c->data[PROP_DEPLOYMENT],
|
||||
"LOCATION", &c->data[PROP_LOCATION],
|
||||
"HARDWARE_VENDOR", &c->data[PROP_HARDWARE_VENDOR],
|
||||
"HARDWARE_MODEL", &c->data[PROP_HARDWARE_MODEL]);
|
||||
"HARDWARE_MODEL", &c->data[PROP_HARDWARE_MODEL],
|
||||
"HARDWARE_SKU", &c->data[PROP_HARDWARE_SKU]);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
log_warning_errno(r, "Failed to read /etc/machine-info, ignoring: %m");
|
||||
|
||||
@@ -356,6 +359,27 @@ static int get_hardware_model(Context *c, char **ret) {
|
||||
return get_dmi_properties(c, STRV_MAKE_CONST("ID_MODEL_FROM_DATABASE", "ID_MODEL"), ret);
|
||||
}
|
||||
|
||||
static int get_hardware_sku(Context *c, char **ret) {
|
||||
_cleanup_free_ char *model = NULL, *sku = NULL;
|
||||
int r;
|
||||
|
||||
r = get_dmi_property(c, "ID_SKU", &sku);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Suppress reporting the SKU field, if it's the same string as the
|
||||
* model field, which it appears to be on various systems */
|
||||
r = get_hardware_model(c, &model);
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT)
|
||||
return r;
|
||||
} else if (streq_ptr(sku, model))
|
||||
return -ENOENT;
|
||||
|
||||
*ret = TAKE_PTR(sku);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_sysattr(sd_device *device, const char *key, char **ret) {
|
||||
const char *s;
|
||||
int r;
|
||||
@@ -824,7 +848,8 @@ static int property_get_hardware_property(
|
||||
|
||||
assert(reply);
|
||||
assert(c);
|
||||
assert(IN_SET(prop, PROP_HARDWARE_VENDOR, PROP_HARDWARE_MODEL));
|
||||
assert(IN_SET(prop, PROP_HARDWARE_VENDOR, PROP_HARDWARE_MODEL,
|
||||
PROP_HARDWARE_SKU));
|
||||
assert(getter);
|
||||
|
||||
context_read_machine_info(c);
|
||||
@@ -859,6 +884,18 @@ static int property_get_hardware_model(
|
||||
return property_get_hardware_property(reply, userdata, PROP_HARDWARE_MODEL, get_hardware_model);
|
||||
}
|
||||
|
||||
static int property_get_hardware_sku(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
return property_get_hardware_property(reply, userdata, PROP_HARDWARE_SKU, get_hardware_sku);
|
||||
}
|
||||
|
||||
static int property_get_firmware_version(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
@@ -1539,7 +1576,7 @@ static int method_get_hardware_serial(sd_bus_message *m, void *userdata, sd_bus_
|
||||
static int build_describe_response(Context *c, bool privileged, sd_json_variant **ret) {
|
||||
_cleanup_free_ char *hn = NULL, *dhn = NULL, *in = NULL,
|
||||
*chassis = NULL, *vendor = NULL, *model = NULL, *serial = NULL, *firmware_version = NULL,
|
||||
*firmware_vendor = NULL, *chassis_asset_tag = NULL;
|
||||
*firmware_vendor = NULL, *chassis_asset_tag = NULL, *sku = NULL;
|
||||
_cleanup_strv_free_ char **os_release_pairs = NULL, **machine_info_pairs = NULL;
|
||||
usec_t firmware_date = USEC_INFINITY, eol = USEC_INFINITY;
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
@@ -1575,6 +1612,8 @@ static int build_describe_response(Context *c, bool privileged, sd_json_variant
|
||||
(void) get_hardware_vendor(c, &vendor);
|
||||
if (isempty(c->data[PROP_HARDWARE_MODEL]))
|
||||
(void) get_hardware_model(c, &model);
|
||||
if (isempty(c->data[PROP_HARDWARE_SKU]))
|
||||
(void) get_hardware_sku(c, &sku);
|
||||
|
||||
if (privileged) {
|
||||
/* The product UUID and hardware serial is only available to privileged clients */
|
||||
@@ -1628,6 +1667,7 @@ static int build_describe_response(Context *c, bool privileged, sd_json_variant
|
||||
SD_JSON_BUILD_PAIR_STRING("HardwareVendor", vendor ?: c->data[PROP_HARDWARE_VENDOR]),
|
||||
SD_JSON_BUILD_PAIR_STRING("HardwareModel", model ?: c->data[PROP_HARDWARE_MODEL]),
|
||||
SD_JSON_BUILD_PAIR_STRING("HardwareSerial", serial),
|
||||
SD_JSON_BUILD_PAIR_STRING("HardwareSKU", sku ?: c->data[PROP_HARDWARE_SKU]),
|
||||
SD_JSON_BUILD_PAIR_STRING("FirmwareVersion", firmware_version),
|
||||
SD_JSON_BUILD_PAIR_STRING("FirmwareVendor", firmware_vendor),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("FirmwareDate", firmware_date),
|
||||
@@ -1699,6 +1739,7 @@ static const sd_bus_vtable hostname_vtable[] = {
|
||||
SD_BUS_PROPERTY("OperatingSystemImageVersion", "s", property_get_os_release_field, offsetof(Context, data[PROP_OS_IMAGE_VERSION]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("HardwareVendor", "s", property_get_hardware_vendor, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("HardwareModel", "s", property_get_hardware_model, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("HardwareSKU", "s", property_get_hardware_sku, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("FirmwareVersion", "s", property_get_firmware_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("FirmwareVendor", "s", property_get_firmware_vendor, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("FirmwareDate", "t", property_get_firmware_date, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
||||
@@ -27,6 +27,7 @@ static SD_VARLINK_DEFINE_METHOD(
|
||||
SD_VARLINK_DEFINE_OUTPUT(HardwareVendor, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_OUTPUT(HardwareModel, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_OUTPUT(HardwareSerial, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_OUTPUT(HardwareSKU, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_OUTPUT(FirmwareVersion, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_OUTPUT(FirmwareVendor, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_OUTPUT(FirmwareDate, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
|
||||
Reference in New Issue
Block a user