discover: Add 'sync' user event
authorSamuel Mendoza-Jonas <sam@mendozajonas.com>
Tue, 26 Jul 2016 05:45:37 +0000 (15:45 +1000)
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>
Mon, 8 Aug 2016 03:52:50 +0000 (13:52 +1000)
Add a user event named 'sync' that causes the discover server to merge
the devicemapper snapshots of mounted devices. This is particularly
useful as a debug aid (for example, when copying logs to a USB device),
as the server will otherwise only sync changes to mounted devices in
response to parser actions.

The command can be called as

pb-event sync@device

to sync a particular device, or as

pb-event sync@all

to sync all devices with snapshots.

Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
discover/device-handler.c
discover/device-handler.h
discover/event.c
discover/event.h
discover/user-event.c
utils/pb-event.c

index 682a4e9ae865944d4acea0c62c5b9418ffe36227..c31fceaf5a11b1ac22c28f50ad530866f4b7f23e 100644 (file)
@@ -1581,6 +1581,41 @@ void device_release_write(struct discover_device *dev, bool release)
                dev->mounted = true;
 }
 
+void device_sync_snapshots(struct device_handler *handler, const char *device)
+{
+       struct discover_device *dev = NULL;
+       unsigned int i;
+
+       if (device) {
+               /* Find matching device and sync */
+               dev = device_lookup_by_name(handler, device);
+               if (!dev) {
+                       pb_log("%s: device name '%s' unrecognised\n",
+                               __func__, device);
+                       return;
+               }
+               if (dev->ramdisk)
+                       device_release_write(dev, true);
+               else
+                       pb_log("%s has no snapshot to merge, skipping\n",
+                               dev->device->id);
+               return;
+       }
+
+       /* Otherwise sync all relevant devices */
+       for (i = 0; i < handler->n_devices; i++) {
+               dev = handler->devices[i];
+               if (dev->device->type != DEVICE_TYPE_DISK &&
+                       dev->device->type != DEVICE_TYPE_USB)
+                       continue;
+               if (dev->ramdisk)
+                       device_release_write(dev, true);
+               else
+                       pb_log("%s has no snapshot to merge, skipping\n",
+                               dev->device->id);
+       }
+}
+
 #else
 
 void device_handler_discover_context_commit(
@@ -1628,4 +1663,10 @@ void device_release_write(struct discover_device *dev __attribute__((unused)),
 {
 }
 
+void device_sync_snapshots(
+               struct device_handler *handler __attribute__((unused)),
+               const char *device __attribute__((unused)))
+{
+}
+
 #endif
index 6b1a75787d31029288ca17cdc52bf453faa98787..b6f9fd51a27a7d77cd5f2ca9eef172b12d0bd016 100644 (file)
@@ -142,5 +142,6 @@ void device_handler_reinit(struct device_handler *handler);
 
 int device_request_write(struct discover_device *dev, bool *release);
 void device_release_write(struct discover_device *dev, bool release);
+void device_sync_snapshots(struct device_handler *handler, const char *device);
 
 #endif /* _DEVICE_HANDLER_H */
index 8b3a1ab8b344ca2662a97649b5113c71d173047c..242ae81bf1a756306c97db74ee0e69d62ae4d487 100644 (file)
@@ -55,6 +55,8 @@ static int event_parse_ad_header(char *buf, int len, enum event_action *action,
                *action = EVENT_ACTION_DHCP;
        else if (streq(buf, "boot"))
                *action = EVENT_ACTION_BOOT;
+       else if (streq(buf, "sync"))
+               *action = EVENT_ACTION_SYNC;
        else {
                pb_log("%s: unknown action: %s\n", __func__, buf);
                return -1;
index 35c07679db17eeb31bd75d533ef4b1ac9bf896ab..a6036159d75da1bb113c61539b06afa623feeb86 100644 (file)
@@ -14,6 +14,7 @@ enum event_action {
        EVENT_ACTION_CONF,
        EVENT_ACTION_DHCP,
        EVENT_ACTION_BOOT,
+       EVENT_ACTION_SYNC,
        EVENT_ACTION_MAX,
 };
 
index 15d9c87bebc2213a1cb265b532999921f0e92925..7350b6c3c4ef558927097c53066e81759d0a0a1f 100644 (file)
@@ -60,6 +60,8 @@ static const char *event_action_name(enum event_action action)
                return "dhcp";
        case EVENT_ACTION_BOOT:
                return "boot";
+       case EVENT_ACTION_SYNC:
+               return "sync";
        default:
                break;
        }
@@ -464,6 +466,18 @@ static int user_event_boot(struct user_event *uev, struct event *event)
        return 0;
 }
 
+static int user_event_sync(struct user_event *uev, struct event *event)
+{
+       struct device_handler *handler = uev->handler;
+
+       if (strncasecmp(event->device, "all", strlen("all")) != 0)
+               device_sync_snapshots(handler, event->device);
+       else
+               device_sync_snapshots(handler, NULL);
+
+       return 0;
+}
+
 static void user_event_handle_message(struct user_event *uev, char *buf,
        int len)
 {
@@ -499,6 +513,9 @@ static void user_event_handle_message(struct user_event *uev, char *buf,
        case EVENT_ACTION_BOOT:
                result = user_event_boot(uev, event);
                break;
+       case EVENT_ACTION_SYNC:
+               result = user_event_sync(uev, event);
+               break;
        default:
                break;
        }
index 572eb16c36be36d1302bfc7ccfbec5d2d3de0f41..10bf4f59ab3857b8ab6af8ef50ff012871c5a76e 100644 (file)
@@ -55,7 +55,7 @@ static void print_usage(void)
 "       Events can be read from stdin, or provided on the command line.\n"
 "       User events must have the following format:\n"
 "\n"
-"         (add|remove|boot)@device-id [name=value] [image=value] [args=value]\n"
+"         (add|remove|boot|sync)@device-id [name=value] [image=value] [args=value]\n"
 "\n"
 "       When read from stdin, components are separated by NUL chars\n"
 "\n"