diff --git a/man/machine-info.xml b/man/machine-info.xml index 0f57cbdb88a..4467c59c94c 100644 --- a/man/machine-info.xml +++ b/man/machine-info.xml @@ -139,6 +139,20 @@ machine-id5 will be used. + + + VENDOR= + + Specifies the hardware vendor. If unspecified, the hardware vendor set in DMI + or hwdb will be used. + + + + MODEL= + + Specifies the hardware model. If unspecified, the hardware model set in DMI or + hwdb will be used. + diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 3e2fa94c614..8a9a180d635 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -43,7 +43,7 @@ /* Properties we cache are indexed by an enum, to make invalidation easy and systematic (as we can iterate * through them all, and they are uniformly strings). */ -enum { +typedef enum { /* Read from /etc/hostname */ PROP_STATIC_HOSTNAME, @@ -53,6 +53,8 @@ enum { PROP_CHASSIS, PROP_DEPLOYMENT, PROP_LOCATION, + PROP_VENDOR, + PROP_MODEL, /* Read from /etc/os-release (or /usr/lib/os-release) */ PROP_OS_PRETTY_NAME, @@ -60,7 +62,7 @@ enum { PROP_OS_HOME_URL, _PROP_MAX, _PROP_INVALID = -EINVAL, -}; +} HostProperty; typedef struct Context { char *data[_PROP_MAX]; @@ -133,7 +135,9 @@ static void context_read_machine_info(Context *c) { "ICON_NAME", &c->data[PROP_ICON_NAME], "CHASSIS", &c->data[PROP_CHASSIS], "DEPLOYMENT", &c->data[PROP_DEPLOYMENT], - "LOCATION", &c->data[PROP_LOCATION]); + "LOCATION", &c->data[PROP_LOCATION], + "VENDOR", &c->data[PROP_VENDOR], + "MODEL", &c->data[PROP_MODEL]); if (r < 0 && r != -ENOENT) log_warning_errno(r, "Failed to read /etc/machine-info, ignoring: %m"); @@ -515,6 +519,27 @@ static int context_write_data_machine_info(Context *c) { return 0; } +static int property_get_hardware_property( + sd_bus_message *reply, + Context *c, + HostProperty prop, + int (*getter)(char **)) { + + _cleanup_free_ char *from_dmi = NULL; + + assert(reply); + assert(c); + assert(IN_SET(prop, PROP_VENDOR, PROP_MODEL)); + assert(getter); + + context_read_machine_info(c); + + if (isempty(c->data[prop])) + (void) getter(&from_dmi); + + return sd_bus_message_append(reply, "s", from_dmi ?: c->data[prop]); +} + static int property_get_hardware_vendor( sd_bus *bus, const char *path, @@ -524,10 +549,7 @@ static int property_get_hardware_vendor( void *userdata, sd_bus_error *error) { - _cleanup_free_ char *vendor = NULL; - - (void) get_hardware_vendor(&vendor); - return sd_bus_message_append(reply, "s", vendor); + return property_get_hardware_property(reply, userdata, PROP_VENDOR, get_hardware_vendor); } static int property_get_hardware_model( @@ -539,10 +561,7 @@ static int property_get_hardware_model( void *userdata, sd_bus_error *error) { - _cleanup_free_ char *model = NULL; - - (void) get_hardware_model(&model); - return sd_bus_message_append(reply, "s", model); + return property_get_hardware_property(reply, userdata, PROP_MODEL, get_hardware_model); } static int property_get_hostname( @@ -1087,8 +1106,10 @@ static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *erro assert_se(uname(&u) >= 0); - (void) get_hardware_vendor(&vendor); - (void) get_hardware_model(&model); + if (isempty(c->data[PROP_VENDOR])) + (void) get_hardware_vendor(&vendor); + if (isempty(c->data[PROP_MODEL])) + (void) get_hardware_model(&model); if (privileged) /* The product UUID is only available to privileged clients */ id128_get_product(&product_uuid); @@ -1109,8 +1130,8 @@ static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *erro JSON_BUILD_PAIR("OperatingSystemPrettyName", JSON_BUILD_STRING(c->data[PROP_OS_PRETTY_NAME])), JSON_BUILD_PAIR("OperatingSystemCPEName", JSON_BUILD_STRING(c->data[PROP_OS_CPE_NAME])), JSON_BUILD_PAIR("OperatingSystemHomeURL", JSON_BUILD_STRING(c->data[PROP_OS_HOME_URL])), - JSON_BUILD_PAIR("HardwareVendor", JSON_BUILD_STRING(vendor)), - JSON_BUILD_PAIR("HardwareModel", JSON_BUILD_STRING(model)), + JSON_BUILD_PAIR("HardwareVendor", JSON_BUILD_STRING(vendor ?: c->data[PROP_VENDOR])), + JSON_BUILD_PAIR("HardwareModel", JSON_BUILD_STRING(model ?: c->data[PROP_MODEL])), JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(product_uuid), "ProductUUID", JSON_BUILD_ID128(product_uuid)), JSON_BUILD_PAIR_CONDITION(sd_id128_is_null(product_uuid), "ProductUUID", JSON_BUILD_NULL)));