]> git.ozlabs.org Git - petitboot/blobdiff - discover/device-handler.c
discover: extend URL in UI to support auto-discovery
[petitboot] / discover / device-handler.c
index 31cbcc2c1da50b87b9b5bf472227ebe2ce8559ab..5df070073b4d298c8a49a5488010434b73ff4f32 100644 (file)
@@ -457,6 +457,7 @@ struct {
 } device_type_map[] = {
        { IPMI_BOOTDEV_NETWORK, DEVICE_TYPE_NETWORK },
        { IPMI_BOOTDEV_DISK, DEVICE_TYPE_DISK },
 } device_type_map[] = {
        { IPMI_BOOTDEV_NETWORK, DEVICE_TYPE_NETWORK },
        { IPMI_BOOTDEV_DISK, DEVICE_TYPE_DISK },
+       { IPMI_BOOTDEV_DISK, DEVICE_TYPE_USB },
        { IPMI_BOOTDEV_CDROM, DEVICE_TYPE_OPTICAL },
 };
 
        { IPMI_BOOTDEV_CDROM, DEVICE_TYPE_OPTICAL },
 };
 
@@ -861,7 +862,13 @@ int device_handler_discover(struct device_handler *handler,
 
        status = talloc_zero(handler, struct boot_status);
        status->type = BOOT_STATUS_INFO;
 
        status = talloc_zero(handler, struct boot_status);
        status->type = BOOT_STATUS_INFO;
-       status->message = talloc_asprintf(status, "Processing %s device %s",
+       /*
+        * TRANSLATORS: this string will be passed the type and identifier
+        * of the device. For example, the first parameter could be "Disk",
+        * (which will be translated accordingly) and the second a Linux device
+        * identifier like 'sda1' (which will not be translated)
+        */
+       status->message = talloc_asprintf(status, _("Processing %s device %s"),
                                device_type_display_name(dev->device->type),
                                dev->device->id);
        boot_status(handler, status);
                                device_type_display_name(dev->device->type),
                                dev->device->id);
        boot_status(handler, status);
@@ -886,7 +893,11 @@ int device_handler_discover(struct device_handler *handler,
        device_handler_discover_context_commit(handler, ctx);
 
 out:
        device_handler_discover_context_commit(handler, ctx);
 
 out:
-       status->message = talloc_asprintf(status,"Processing %s complete\n",
+       /*
+        * TRANSLATORS: the format specifier in this string is a Linux
+        * device identifier, like 'sda1'
+        */
+       status->message = talloc_asprintf(status,_("Processing %s complete"),
                                dev->device->id);
        boot_status(handler, status);
 
                                dev->device->id);
        boot_status(handler, status);
 
@@ -905,7 +916,11 @@ int device_handler_dhcp(struct device_handler *handler,
 
        status = talloc_zero(handler, struct boot_status);
        status->type = BOOT_STATUS_INFO;
 
        status = talloc_zero(handler, struct boot_status);
        status->type = BOOT_STATUS_INFO;
-       status->message = talloc_asprintf(status, "Processing dhcp event on %s",
+       /*
+        * TRANSLATORS: this format specifier will be the name of a network
+        * device, like 'eth0'.
+        */
+       status->message = talloc_asprintf(status, _("Processing dhcp event on %s"),
                                dev->device->id);
        boot_status(handler, status);
 
                                dev->device->id);
        boot_status(handler, status);
 
@@ -917,7 +932,11 @@ int device_handler_dhcp(struct device_handler *handler,
 
        device_handler_discover_context_commit(handler, ctx);
 
 
        device_handler_discover_context_commit(handler, ctx);
 
-       status->message = talloc_asprintf(status,"Processing %s complete\n",
+       /*
+        * TRANSLATORS: this format specifier will be the name of a network
+        * device, like 'eth0'.
+        */
+       status->message = talloc_asprintf(status,_("Processing %s complete"),
                                dev->device->id);
        boot_status(handler, status);
 
                                dev->device->id);
        boot_status(handler, status);
 
@@ -936,7 +955,7 @@ int device_handler_conf(struct device_handler *handler,
 
        status = talloc_zero(handler, struct boot_status);
        status->type = BOOT_STATUS_INFO;
 
        status = talloc_zero(handler, struct boot_status);
        status->type = BOOT_STATUS_INFO;
-       status->message = talloc_asprintf(status, "Processing user config");
+       status->message = talloc_asprintf(status, _("Processing user config"));
        boot_status(handler, status);
 
        /* create our context */
        boot_status(handler, status);
 
        /* create our context */
@@ -948,7 +967,7 @@ int device_handler_conf(struct device_handler *handler,
        device_handler_discover_context_commit(handler, ctx);
 
        status->message = talloc_asprintf(status,
        device_handler_discover_context_commit(handler, ctx);
 
        status->message = talloc_asprintf(status,
-                               "Processing user config complete");
+                               _("Processing user config complete"));
        boot_status(handler, status);
 
        talloc_free(status);
        boot_status(handler, status);
 
        talloc_free(status);
@@ -1106,9 +1125,8 @@ static char *device_from_addr(void *ctx, struct pb_url *url)
        return dev;
 }
 
        return dev;
 }
 
-
 void device_handler_process_url(struct device_handler *handler,
 void device_handler_process_url(struct device_handler *handler,
-               const char *url)
+               const char *url, const char *mac, const char *ip)
 {
        struct discover_context *ctx;
        struct discover_device *dev;
 {
        struct discover_context *ctx;
        struct discover_device *dev;
@@ -1134,11 +1152,25 @@ void device_handler_process_url(struct device_handler *handler,
        event->type = EVENT_TYPE_USER;
        event->action = EVENT_ACTION_CONF;
 
        event->type = EVENT_TYPE_USER;
        event->action = EVENT_ACTION_CONF;
 
-       event->params = talloc_array(event, struct param, 1);
-       param = &event->params[0];
-       param->name = talloc_strdup(event, "pxeconffile");
-       param->value = talloc_strdup(event, url);
-       event->n_params = 1;
+       if (url[strlen(url) - 1] == '/') {
+               event->params = talloc_array(event, struct param, 3);
+               param = &event->params[0];
+               param->name = talloc_strdup(event, "pxepathprefix");
+               param->value = talloc_strdup(event, url);
+               param = &event->params[1];
+               param->name = talloc_strdup(event, "mac");
+               param->value = talloc_strdup(event, mac);
+               param = &event->params[2];
+               param->name = talloc_strdup(event, "ip");
+               param->value = talloc_strdup(event, ip);
+               event->n_params = 3;
+       } else {
+               event->params = talloc_array(event, struct param, 1);
+               param = &event->params[0];
+               param->name = talloc_strdup(event, "pxeconffile");
+               param->value = talloc_strdup(event, url);
+               event->n_params = 1;
+       }
 
        pb_url = pb_url_parse(event, event->params->value);
        if (!pb_url || !pb_url->host) {
 
        pb_url = pb_url_parse(event, event->params->value);
        if (!pb_url || !pb_url->host) {
@@ -1224,16 +1256,26 @@ static void device_handler_reinit_sources(struct device_handler *handler)
                        handler->dry_run);
 }
 
                        handler->dry_run);
 }
 
-static const char *fs_parameters(unsigned int rw_flags, const char *fstype)
+static const char *fs_parameters(struct discover_device *dev,
+                                unsigned int rw_flags)
 {
 {
+       const char *fstype = discover_device_get_param(dev, "ID_FS_TYPE");
+
+       /* XFS journals are not cross-endian compatible; don't try recovery
+        * even if we have a snapshot */
+       if (!strncmp(fstype, "xfs", strlen("xfs")))
+               return "norecovery";
+
+       /* If we have a snapshot available allow touching the filesystem */
+       if (dev->ramdisk)
+               return "";
+
        if ((rw_flags | MS_RDONLY) != MS_RDONLY)
                return "";
 
        if ((rw_flags | MS_RDONLY) != MS_RDONLY)
                return "";
 
-       /* Avoid writing back to the disk on journaled filesystems */
+       /* Avoid writes due to journal replay if we don't have a snapshot */
        if (!strncmp(fstype, "ext4", strlen("ext4")))
                return "norecovery";
        if (!strncmp(fstype, "ext4", strlen("ext4")))
                return "norecovery";
-       if (!strncmp(fstype, "xfs", strlen("xfs")))
-               return "norecovery";
 
        return "";
 }
 
        return "";
 }
@@ -1341,7 +1383,7 @@ static int mount_device(struct discover_device *dev)
        errno = 0;
        rc = mount(device_path, dev->mount_path, fstype,
                        MS_RDONLY | MS_SILENT,
        errno = 0;
        rc = mount(device_path, dev->mount_path, fstype,
                        MS_RDONLY | MS_SILENT,
-                       fs_parameters(MS_RDONLY, fstype));
+                       fs_parameters(dev, MS_RDONLY));
        if (!rc) {
                dev->mounted = true;
                dev->mounted_rw = false;
        if (!rc) {
                dev->mounted = true;
                dev->mounted_rw = false;
@@ -1391,10 +1433,15 @@ static int umount_device(struct discover_device *dev)
 int device_request_write(struct discover_device *dev, bool *release)
 {
        const char *fstype, *device_path;
 int device_request_write(struct discover_device *dev, bool *release)
 {
        const char *fstype, *device_path;
+       const struct config *config;
        int rc;
 
        *release = false;
 
        int rc;
 
        *release = false;
 
+       config = config_get();
+       if (!config->allow_writes)
+               return -1;
+
        if (!dev->mounted)
                return -1;
 
        if (!dev->mounted)
                return -1;
 
@@ -1416,7 +1463,7 @@ int device_request_write(struct discover_device *dev, bool *release)
 
        rc = mount(device_path, dev->mount_path, fstype,
                        MS_SILENT,
 
        rc = mount(device_path, dev->mount_path, fstype,
                        MS_SILENT,
-                       fs_parameters(MS_REMOUNT, fstype));
+                       fs_parameters(dev, MS_REMOUNT));
        if (rc)
                goto mount_ro;
 
        if (rc)
                goto mount_ro;
 
@@ -1429,7 +1476,7 @@ mount_ro:
               device_path, strerror(errno));
        if (mount(device_path, dev->mount_path, fstype,
                        MS_RDONLY | MS_SILENT,
               device_path, strerror(errno));
        if (mount(device_path, dev->mount_path, fstype,
                        MS_RDONLY | MS_SILENT,
-                       fs_parameters(MS_RDONLY, fstype)))
+                       fs_parameters(dev, MS_RDONLY)))
                pb_log("Unable to recover mount for %s: %s\n",
                       device_path, strerror(errno));
        return -1;
                pb_log("Unable to recover mount for %s: %s\n",
                       device_path, strerror(errno));
        return -1;
@@ -1438,7 +1485,6 @@ mount_ro:
 void device_release_write(struct discover_device *dev, bool release)
 {
        const char *fstype, *device_path;
 void device_release_write(struct discover_device *dev, bool release)
 {
        const char *fstype, *device_path;
-       int rc = 0;
 
        if (!release)
                return;
 
        if (!release)
                return;
@@ -1461,10 +1507,9 @@ void device_release_write(struct discover_device *dev, bool release)
                device_path = get_device_path(dev);
        }
 
                device_path = get_device_path(dev);
        }
 
-       mount(device_path, dev->mount_path, fstype,
+       if (mount(device_path, dev->mount_path, fstype,
                        MS_RDONLY | MS_SILENT,
                        MS_RDONLY | MS_SILENT,
-                       fs_parameters(MS_RDONLY, fstype));
-       if (rc)
+                       fs_parameters(dev, MS_RDONLY)))
                pb_log("Failed to remount %s read-only: %s\n",
                       device_path, strerror(errno));
        else
                pb_log("Failed to remount %s read-only: %s\n",
                       device_path, strerror(errno));
        else