chiark / gitweb /
implement coldpluggin
[elogind.git] / device.c
index 22b0f6085ecbd753ed91f43f85250d1a98630528..34d760a48a55930982958aa3a129cf8c3de86e31 100644 (file)
--- a/device.c
+++ b/device.c
@@ -8,6 +8,16 @@
 #include "strv.h"
 #include "log.h"
 
+static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
+        [DEVICE_DEAD] = UNIT_INACTIVE,
+        [DEVICE_AVAILABLE] = UNIT_ACTIVE
+};
+
+static const char* const state_string_table[_DEVICE_STATE_MAX] = {
+        [DEVICE_DEAD] = "dead",
+        [DEVICE_AVAILABLE] = "available"
+};
+
 static void device_done(Unit *u) {
         Device *d = DEVICE(u);
 
@@ -15,13 +25,31 @@ static void device_done(Unit *u) {
         free(d->sysfs);
 }
 
-static void device_dump(Unit *u, FILE *f, const char *prefix) {
+static void device_set_state(Device *d, DeviceState state) {
+        DeviceState old_state;
+        assert(d);
+
+        old_state = d->state;
+        d->state = state;
+
+        log_debug("%s changed %s → %s", unit_id(UNIT(d)), state_string_table[old_state], state_string_table[state]);
 
-        static const char* const state_table[_DEVICE_STATE_MAX] = {
-                [DEVICE_DEAD] = "dead",
-                [DEVICE_AVAILABLE] = "available"
-        };
+        unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state]);
+}
 
+static int device_coldplug(Unit *u) {
+        Device *d = DEVICE(u);
+
+        assert(d);
+        assert(d->state == DEVICE_DEAD);
+
+        if (d->sysfs)
+                device_set_state(d, DEVICE_AVAILABLE);
+
+        return 0;
+}
+
+static void device_dump(Unit *u, FILE *f, const char *prefix) {
         Device *d = DEVICE(u);
 
         assert(d);
@@ -29,11 +57,17 @@ static void device_dump(Unit *u, FILE *f, const char *prefix) {
         fprintf(f,
                 "%sDevice State: %s\n"
                 "%sSysfs Path: %s\n",
-                prefix, state_table[d->state],
-                prefix, d->sysfs);
+                prefix, state_string_table[d->state],
+                prefix, strna(d->sysfs));
+}
+
+static UnitActiveState device_active_state(Unit *u) {
+        assert(u);
+
+        return state_translation_table[DEVICE(u)->state];
 }
 
-static int device_add_escaped_name(Unit *u, const char *dn) {
+static int device_add_escaped_name(Unit *u, const char *prefix, const char *dn, bool make_id) {
         char *e;
         int r;
 
@@ -41,10 +75,14 @@ static int device_add_escaped_name(Unit *u, const char *dn) {
         assert(dn);
         assert(dn[0] == '/');
 
-        if (!(e = unit_name_escape_path(dn+1, ".device")))
+        if (!(e = unit_name_escape_path(prefix, dn+1, ".device")))
                 return -ENOMEM;
 
         r = unit_add_name(u, e);
+
+        if (r >= 0 && make_id)
+                unit_choose_id(u, e);
+
         free(e);
 
         if (r < 0 && r != -EEXIST)
@@ -79,7 +117,7 @@ static int device_process_device(Manager *m, struct udev_device *dev) {
                 return -ENOMEM;
 
         assert(sysfs[0] == '/');
-        if (!(e = unit_name_escape_path(sysfs+1, ".device")))
+        if (!(e = unit_name_escape_path("sysfs-", sysfs+1, ".device")))
                 return -ENOMEM;
 
         if (!(u = manager_get_unit(m, e))) {
@@ -104,11 +142,9 @@ static int device_process_device(Manager *m, struct udev_device *dev) {
                 }
 
                 if ((model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE")) ||
-                     (model = udev_device_get_property_value(dev, "ID_MODEL")))
-                        if (!(u->meta.description = strdup(model))) {
-                                r = -ENOMEM;
+                    (model = udev_device_get_property_value(dev, "ID_MODEL")))
+                        if ((r = unit_set_description(u, model)) < 0)
                                 goto fail;
-                        }
 
         } else {
                 delete = false;
@@ -116,12 +152,12 @@ static int device_process_device(Manager *m, struct udev_device *dev) {
         }
 
         if (dn)
-                if ((r = device_add_escaped_name(u, dn)) < 0)
+                if ((r = device_add_escaped_name(u, "node-", dn, true)) < 0)
                         goto fail;
 
         first = udev_device_get_devlinks_list_entry(dev);
         udev_list_entry_foreach(item, first)
-                if ((r = device_add_escaped_name(u, udev_list_entry_get_name(item))) < 0)
+                if ((r = device_add_escaped_name(u, "node-", udev_list_entry_get_name(item), false)) < 0)
                         goto fail;
 
         if (names) {
@@ -225,19 +261,17 @@ fail:
         return r;
 }
 
-static UnitActiveState device_active_state(Unit *u) {
-        return DEVICE(u)->state == DEVICE_DEAD ? UNIT_INACTIVE : UNIT_ACTIVE;
-}
-
 const UnitVTable device_vtable = {
         .suffix = ".device",
 
         .init = unit_load_fragment_and_dropin,
         .done = device_done,
+        .coldplug = device_coldplug,
+
         .dump = device_dump,
 
-        .enumerate = device_enumerate,
-        .shutdown = device_shutdown,
+        .active_state = device_active_state,
 
-        .active_state = device_active_state
+        .enumerate = device_enumerate,
+        .shutdown = device_shutdown
 };