]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: add Manager::honor_device_enumeration flag
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 15 Mar 2019 10:37:43 +0000 (19:37 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 15 Mar 2019 10:47:43 +0000 (19:47 +0900)
When system manager is started first time or after switching root,
then the udev's device tag data do not exist yet.
So, let's not honor the enumeration results.

Fixes #11997.

src/core/device.c
src/core/manager.c
src/core/manager.h

index 506bf744788a2538902ded2e0f582097a989f353..382c38049805e789c6c9923d86bcc392f41193e6 100644 (file)
@@ -666,9 +666,13 @@ static void device_found_changed(Device *d, DeviceFound previous, DeviceFound no
 }
 
 static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask) {
+        Manager *m;
+
         assert(d);
 
-        if (MANAGER_IS_RUNNING(UNIT(d)->manager)) {
+        m = UNIT(d)->manager;
+
+        if (MANAGER_IS_RUNNING(m) && (m->honor_device_enumeration || MANAGER_IS_USER(m))) {
                 DeviceFound n, previous;
 
                 /* When we are already running, then apply the new mask right-away, and trigger state changes
index eecf48dea53bfa4e74050acee3ff82330dea3243..3f4dbe64e301aeeef6ed5180ce37af414ada83e1 100644 (file)
@@ -1619,6 +1619,8 @@ static void manager_ready(Manager *m) {
 
         /* Let's finally catch up with any changes that took place while we were reloading/reexecing */
         manager_catchup(m);
+
+        m->honor_device_enumeration = true;
 }
 
 static Manager* manager_reloading_start(Manager *m) {
@@ -3131,6 +3133,9 @@ int manager_serialize(
         (void) serialize_bool(f, "taint-logged", m->taint_logged);
         (void) serialize_bool(f, "service-watchdogs", m->service_watchdogs);
 
+        /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
+        (void) serialize_bool(f, "honor-device-enumeration", !switching_root);
+
         t = show_status_to_string(m->show_status);
         if (t)
                 (void) serialize_item(f, "show-status", t);
@@ -3359,6 +3364,15 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                         else
                                 m->service_watchdogs = b;
 
+                } else if ((val = startswith(l, "honor-device-enumeration="))) {
+                        int b;
+
+                        b = parse_boolean(val);
+                        if (b < 0)
+                                log_notice("Failed to parse honor-device-enumeration flag '%s', ignoring.", val);
+                        else
+                                m->honor_device_enumeration = b;
+
                 } else if ((val = startswith(l, "show-status="))) {
                         ShowStatus s;
 
@@ -3549,6 +3563,11 @@ int manager_reload(Manager *m) {
         assert(m->n_reloading > 0);
         m->n_reloading--;
 
+        /* On manager reloading, device tag data should exists, thus, we should honor the results of device
+         * enumeration. The flag should be always set correctly by the serialized data, but it may fail. So,
+         * let's always set the flag here for safety. */
+        m->honor_device_enumeration = true;
+
         manager_ready(m);
 
         m->send_reloading_done = true;
index bce8020cfd4fa32db7dcdd94790cc2d4e96400fb..86b9ec202dbd68d670b734ae7a8440a08cac26cd 100644 (file)
@@ -395,6 +395,8 @@ struct Manager {
          * multiple times on the same unit. */
         unsigned sigchldgen;
         unsigned notifygen;
+
+        bool honor_device_enumeration;
 };
 
 #define MANAGER_IS_SYSTEM(m) ((m)->unit_file_scope == UNIT_FILE_SYSTEM)