]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
hostname: allow to override hardware vendor and model
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 22 Jan 2022 01:44:50 +0000 (10:44 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 23 Jan 2022 03:48:00 +0000 (12:48 +0900)
Sometimes hardware vendor does not set DMI info correctly.
Already there is a way that the dbus properties can be overriden by
using hwdb. But that is not user friendly.

This adds two new fields in /etc/machine-info.

Closes #22207.

man/machine-info.xml
src/hostname/hostnamed.c

index 0f57cbdb88ad850e9123408e2dcf57d039c58fb5..4467c59c94c8735c03af68b190888f34106cf70c 100644 (file)
         <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
         will be used.</para></listitem>
       </varlistentry>
+
+      <varlistentry>
+        <term><varname>VENDOR=</varname></term>
+
+        <listitem><para>Specifies the hardware vendor. If unspecified, the hardware vendor set in DMI
+        or hwdb will be used.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>MODEL=</varname></term>
+
+        <listitem><para>Specifies the hardware model. If unspecified, the hardware model set in DMI or
+        hwdb will be used.</para></listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
index 3e2fa94c61490b5a90ae77b2a6b7e2524655e0f9..8a9a180d635e61de8bde6f18f84581bf7226382d 100644 (file)
@@ -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)));