]> git.ozlabs.org Git - petitboot/commitdiff
Merge branch 'pb-plugin' into master
authorSamuel Mendoza-Jonas <sam.mj@au1.ibm.com>
Fri, 11 Sep 2015 05:56:18 +0000 (15:56 +1000)
committerSamuel Mendoza-Jonas <sam.mj@au1.ibm.com>
Fri, 11 Sep 2015 05:58:41 +0000 (15:58 +1000)
Signed-off-by: Samuel Mendoza-Jonas <sam.mj@au1.ibm.com>
41 files changed:
discover/Makefile.am
discover/device-handler.c
discover/device-handler.h
discover/devmapper.c [new file with mode: 0644]
discover/devmapper.h [new file with mode: 0644]
discover/platform-powerpc.c
discover/platform.c
discover/udev.c
lib/Makefile.am
lib/fold/fold.c
lib/i18n/i18n.c [new file with mode: 0644]
lib/i18n/i18n.h
lib/pb-config/pb-config.c
lib/pb-protocol/pb-protocol.c
lib/types/types.c
lib/types/types.h
po/de.po
po/en.po
po/es.po
po/fr.po
po/it.po
po/ja.po
po/ko.po
po/pt_BR.po
po/ru.po
po/zh_CN.po
po/zh_TW.po
ui/ncurses/nc-add-url.c
ui/ncurses/nc-boot-editor.c
ui/ncurses/nc-config-help.c
ui/ncurses/nc-config.c
ui/ncurses/nc-cui.c
ui/ncurses/nc-lang.c
ui/ncurses/nc-menu.c
ui/ncurses/nc-subset.c
ui/ncurses/nc-sysinfo.c
ui/ncurses/nc-textscreen.c
ui/ncurses/nc-textscreen.h
ui/ncurses/nc-widgets.c
ui/test/discover-test.c
utils/pb-config.c

index 7808110811cb00654f5605a51031235f780be568..1672035fdacc45ab7b74c0cf0425844fc53a971a 100644 (file)
@@ -24,6 +24,8 @@ discover_pb_discover_SOURCES = \
        discover/device-handler.h \
        discover/discover-server.c \
        discover/discover-server.h \
+       discover/devmapper.c \
+       discover/devmapper.h \
        discover/event.c \
        discover/event.h \
        discover/params.c \
@@ -58,6 +60,10 @@ discover_pb_discover_LDADD = \
        $(core_lib) \
        $(UDEV_LIBS)
 
+discover_pb_discover_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -ldevmapper
+
 discover_pb_discover_CPPFLAGS = \
        $(AM_CPPFLAGS) \
        -DLOCAL_STATE_DIR='"$(localstatedir)"' \
index 64095f10d723c41f702caa2d3a9fcd2d0754eed1..4e25e079ca18185e21ec187e57a5cd09f9315e0f 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "device-handler.h"
 #include "discover-server.h"
+#include "devmapper.h"
 #include "user-event.h"
 #include "platform.h"
 #include "event.h"
@@ -56,6 +57,9 @@ struct device_handler {
        struct discover_device  **devices;
        unsigned int            n_devices;
 
+       struct ramdisk_device   **ramdisks;
+       unsigned int            n_ramdisks;
+
        struct waitset          *waitset;
        struct waiter           *timeout_waiter;
        bool                    autoboot_enabled;
@@ -319,6 +323,7 @@ struct device_handler *device_handler_init(struct discover_server *server,
 void device_handler_reinit(struct device_handler *handler)
 {
        struct discover_boot_option *opt, *tmp;
+       struct ramdisk_device *ramdisk;
        unsigned int i;
 
        device_handler_cancel_default(handler);
@@ -330,13 +335,20 @@ void device_handler_reinit(struct device_handler *handler)
        list_init(&handler->unresolved_boot_options);
 
        /* drop all devices */
-       for (i = 0; i < handler->n_devices; i++)
+       for (i = 0; i < handler->n_devices; i++) {
                discover_server_notify_device_remove(handler->server,
                                handler->devices[i]->device);
+               ramdisk = handler->devices[i]->ramdisk;
+               talloc_free(handler->devices[i]);
+               talloc_free(ramdisk);
+       }
 
        talloc_free(handler->devices);
        handler->devices = NULL;
        handler->n_devices = 0;
+       talloc_free(handler->ramdisks);
+       handler->ramdisks = NULL;
+       handler->n_ramdisks = 0;
 
        device_handler_reinit_sources(handler);
 }
@@ -445,6 +457,7 @@ struct {
 } 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 },
 };
 
@@ -748,6 +761,95 @@ void device_handler_add_device(struct device_handler *handler,
                network_register_device(handler->network, device);
 }
 
+void device_handler_add_ramdisk(struct device_handler *handler,
+               const char *path)
+{
+       struct ramdisk_device *dev;
+       unsigned int i;
+
+       if (!path)
+               return;
+
+       for (i = 0; i < handler->n_ramdisks; i++)
+               if (!strcmp(handler->ramdisks[i]->path, path))
+                       return;
+
+       dev = talloc_zero(handler, struct ramdisk_device);
+       if (!dev) {
+               pb_log("Failed to allocate memory to track %s\n", path);
+               return;
+       }
+
+       dev->path = talloc_strdup(handler, path);
+
+       handler->ramdisks = talloc_realloc(handler, handler->ramdisks,
+                               struct ramdisk_device *,
+                               handler->n_ramdisks + 1);
+       if (!handler->ramdisks) {
+               pb_log("Failed to reallocate memory"
+                      "- ramdisk tracking inconsistent!\n");
+               return;
+       }
+
+       handler->ramdisks[i] = dev;
+       i = handler->n_ramdisks++;
+}
+
+struct ramdisk_device *device_handler_get_ramdisk(
+               struct device_handler *handler)
+{
+       unsigned int i;
+       char *name;
+       dev_t id;
+
+       /* Check if free ramdisk exists */
+       for (i = 0; i < handler->n_ramdisks; i++)
+               if (!handler->ramdisks[i]->snapshot &&
+                   !handler->ramdisks[i]->origin &&
+                   !handler->ramdisks[i]->base)
+                       return handler->ramdisks[i];
+
+       /* Otherwise create a new one */
+       name = talloc_asprintf(handler, "/dev/ram%d",
+                       handler->n_ramdisks);
+       if (!name) {
+               pb_debug("Failed to allocate memory to name /dev/ram%d",
+                       handler->n_ramdisks);
+               return NULL;
+       }
+
+       id = makedev(1, handler->n_ramdisks);
+       if (mknod(name, S_IFBLK, id)) {
+               if (errno == EEXIST) {
+                       /* We haven't yet received updates for existing
+                        * ramdisks - add and use this one */
+                       pb_debug("Using untracked ramdisk %s\n", name);
+               } else {
+                       pb_log("Failed to create new ramdisk %s: %s\n",
+                              name, strerror(errno));
+                       return NULL;
+               }
+       }
+       device_handler_add_ramdisk(handler, name);
+       talloc_free(name);
+
+       return handler->ramdisks[i];
+}
+
+void device_handler_release_ramdisk(struct discover_device *device)
+{
+       struct ramdisk_device *ramdisk = device->ramdisk;
+
+       talloc_free(ramdisk->snapshot);
+       talloc_free(ramdisk->origin);
+       talloc_free(ramdisk->base);
+
+       ramdisk->snapshot = ramdisk->origin = ramdisk->base = NULL;
+       ramdisk->sectors = 0;
+
+       device->ramdisk = NULL;
+}
+
 /* Start discovery on a hotplugged device. The device will be in our devices
  * array, but has only just been initialised by the hotplug source.
  */
@@ -1123,28 +1225,46 @@ static void device_handler_reinit_sources(struct device_handler *handler)
                        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 "";
 
-       /* 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, "xfs", strlen("xfs")))
-               return "norecovery";
 
        return "";
 }
 
+static inline const char *get_device_path(struct discover_device *dev)
+{
+       return dev->ramdisk ? dev->ramdisk->snapshot : dev->device_path;
+}
+
 static bool check_existing_mount(struct discover_device *dev)
 {
        struct stat devstat, mntstat;
+       const char *device_path;
        struct mntent *mnt;
        FILE *fp;
        int rc;
 
-       rc = stat(dev->device_path, &devstat);
+       device_path = get_device_path(dev);
+
+       rc = stat(device_path, &devstat);
        if (rc) {
                pb_debug("%s: stat failed: %s\n", __func__, strerror(errno));
                return false;
@@ -1194,7 +1314,7 @@ static bool check_existing_mount(struct discover_device *dev)
 
 static int mount_device(struct discover_device *dev)
 {
-       const char *fstype;
+       const char *fstype, *device_path;
        int rc;
 
        if (!dev->device_path)
@@ -1226,11 +1346,13 @@ static int mount_device(struct discover_device *dev)
                goto err_free;
        }
 
+       device_path = get_device_path(dev);
+
        pb_log("mounting device %s read-only\n", dev->device_path);
        errno = 0;
-       rc = mount(dev->device_path, dev->mount_path, fstype,
+       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;
@@ -1239,7 +1361,10 @@ static int mount_device(struct discover_device *dev)
        }
 
        pb_log("couldn't mount device %s: mount failed: %s\n",
-                       dev->device_path, strerror(errno));
+                       device_path, strerror(errno));
+
+       /* If mount fails clean up any snapshot */
+       devmapper_destroy_snapshot(dev);
 
        pb_rmdir_recursive(mount_base(), dev->mount_path);
 err_free:
@@ -1250,17 +1375,21 @@ err_free:
 
 static int umount_device(struct discover_device *dev)
 {
+       const char *device_path;
        int rc;
 
        if (!dev->mounted || !dev->unmount)
                return 0;
 
-       pb_log("unmounting device %s\n", dev->device_path);
+       device_path = get_device_path(dev);
+
+       pb_log("unmounting device %s\n", device_path);
        rc = umount(dev->mount_path);
        if (rc)
                return -1;
 
        dev->mounted = false;
+       devmapper_destroy_snapshot(dev);
 
        pb_rmdir_recursive(mount_base(), dev->mount_path);
 
@@ -1272,11 +1401,16 @@ static int umount_device(struct discover_device *dev)
 
 int device_request_write(struct discover_device *dev, bool *release)
 {
-       const char *fstype;
+       const char *fstype, *device_path;
+       const struct config *config;
        int rc;
 
        *release = false;
 
+       config = config_get();
+       if (!config->allow_writes)
+               return -1;
+
        if (!dev->mounted)
                return -1;
 
@@ -1285,16 +1419,20 @@ int device_request_write(struct discover_device *dev, bool *release)
 
        fstype = discover_device_get_param(dev, "ID_FS_TYPE");
 
-       pb_log("remounting device %s read-write\n", dev->device_path);
+       device_path = get_device_path(dev);
+
+       pb_log("remounting device %s read-write\n", device_path);
 
        rc = umount(dev->mount_path);
        if (rc) {
-               pb_log("Failed to unmount %s\n", dev->mount_path);
+               pb_log("Failed to unmount %s: %s\n",
+                      dev->mount_path, strerror(errno));
                return -1;
        }
-       rc = mount(dev->device_path, dev->mount_path, fstype,
+
+       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;
 
@@ -1303,29 +1441,50 @@ int device_request_write(struct discover_device *dev, bool *release)
        return 0;
 
 mount_ro:
-       pb_log("Unable to remount device %s read-write\n", dev->device_path);
-       rc = mount(dev->device_path, dev->mount_path, fstype,
+       pb_log("Unable to remount device %s read-write: %s\n",
+              device_path, strerror(errno));
+       if (mount(device_path, dev->mount_path, fstype,
                        MS_RDONLY | MS_SILENT,
-                       fs_parameters(MS_RDONLY, fstype));
-       if (rc)
-               pb_log("Unable to recover mount for %s\n", dev->device_path);
+                       fs_parameters(dev, MS_RDONLY)))
+               pb_log("Unable to recover mount for %s: %s\n",
+                      device_path, strerror(errno));
        return -1;
 }
 
 void device_release_write(struct discover_device *dev, bool release)
 {
-       const char *fstype;
+       const char *fstype, *device_path;
+       int rc = 0;
 
        if (!release)
                return;
 
+       device_path = get_device_path(dev);
+
        fstype = discover_device_get_param(dev, "ID_FS_TYPE");
 
-       pb_log("remounting device %s read-only\n", dev->device_path);
-       mount(dev->device_path, dev->mount_path, "",
-                       MS_REMOUNT | MS_RDONLY | MS_SILENT,
-                       fs_parameters(MS_RDONLY, fstype));
-       dev->mounted_rw = false;
+       pb_log("remounting device %s read-only\n", device_path);
+
+       if (umount(dev->mount_path)) {
+               pb_log("Failed to unmount %s\n", dev->mount_path);
+               return;
+       }
+       dev->mounted_rw = dev->mounted = false;
+
+       if (dev->ramdisk) {
+               devmapper_merge_snapshot(dev);
+               /* device_path becomes stale after merge */
+               device_path = get_device_path(dev);
+       }
+
+       mount(device_path, dev->mount_path, fstype,
+                       MS_RDONLY | MS_SILENT,
+                       fs_parameters(dev, MS_RDONLY));
+       if (rc)
+               pb_log("Failed to remount %s read-only: %s\n",
+                      device_path, strerror(errno));
+       else
+               dev->mounted = true;
 }
 
 #else
index b592c462494da3179deda8f9cb69e540bf26ee98..58777339d61bb33df2eae5afd7915a093dcab15c 100644 (file)
@@ -26,6 +26,7 @@ struct discover_device {
 
        char                    *mount_path;
        const char              *device_path;
+       struct ramdisk_device   *ramdisk;
        bool                    mounted;
        bool                    mounted_rw;
        bool                    unmount;
@@ -59,6 +60,14 @@ struct discover_context {
        void                    *test_data;
 };
 
+struct ramdisk_device {
+       const char      *path;
+       char            *snapshot;
+       char            *origin;
+       char            *base;
+       unsigned int    sectors;
+};
+
 struct device_handler *device_handler_init(struct discover_server *server,
                struct waitset *waitset, int dry_run);
 
@@ -72,6 +81,11 @@ struct discover_device *discover_device_create(struct device_handler *handler,
                const char *id);
 void device_handler_add_device(struct device_handler *handler,
                struct discover_device *device);
+void device_handler_add_ramdisk(struct device_handler *handler,
+               const char *path);
+struct ramdisk_device *device_handler_get_ramdisk(
+               struct device_handler *handler);
+void device_handler_release_ramdisk(struct discover_device *device);
 int device_handler_discover(struct device_handler *handler,
                struct discover_device *dev);
 int device_handler_dhcp(struct device_handler *handler,
diff --git a/discover/devmapper.c b/discover/devmapper.c
new file mode 100644 (file)
index 0000000..e2ef0b5
--- /dev/null
@@ -0,0 +1,553 @@
+#include <talloc/talloc.h>
+#include <types/types.h>
+#include <log/log.h>
+#include <errno.h>
+#include <string.h>
+
+#include "libdevmapper.h"
+#include "devmapper.h"
+#include "platform.h"
+
+#define MERGE_INTERVAL_US      200000
+
+struct target {
+       long unsigned int       start_sector;
+       long unsigned int       end_sector;
+       char                    *ttype;
+       char                    *params;
+};
+
+/* Return the number of sectors on a block device. Zero represents an error */
+static unsigned int get_block_sectors(struct discover_device *device)
+{
+       const char *tmp;
+       long unsigned int sectors;
+
+       tmp = discover_device_get_param(device, "ID_PART_ENTRY_SIZE");
+       if (!tmp) {
+               pb_debug("Could not retrieve ID_PART_ENTRY_SIZE for %s\n",
+                      device->device_path);
+               return 0;
+       }
+
+       errno = 0;
+       sectors = strtoul(tmp, NULL, 0);
+       if (errno) {
+               pb_debug("Error reading sector count for %s: %s\n",
+                      device->device_path, strerror(errno));
+               sectors = 0;
+       }
+
+       return sectors;
+}
+
+/*
+ * The system's libdm may or may not have udev sync support. Tell libdm
+ * to manage the creation of device nodes itself rather than waiting on udev
+ * to do it
+ */
+static inline int set_cookie(struct dm_task *task, uint32_t *cookie)
+{
+       uint16_t udev_rules = 0;
+       *cookie = 0;
+
+       dm_udev_set_sync_support(0);
+       udev_rules |= DM_UDEV_DISABLE_DM_RULES_FLAG |
+               DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG;
+
+       return dm_task_set_cookie(task, cookie, udev_rules);
+}
+
+static bool snapshot_merge_complete(const char *dm_name)
+{
+       long long unsigned int sectors, meta_sectors;
+       char *params = NULL,  *target_type = NULL;
+       uint64_t start, length;
+       struct dm_task *task;
+       bool result = true;
+       int n;
+
+       task = dm_task_create(DM_DEVICE_STATUS);
+       if (!task) {
+               pb_log("%s: Error creating task\n", __func__);
+               return result;
+       }
+
+       if (!dm_task_set_name(task, dm_name)) {
+               pb_log("No dm-device named '%s'\n", dm_name);
+               goto out;
+       }
+
+       if (!dm_task_run(task)) {
+               pb_log("Unable to retrieve status for '%s'\n", dm_name);
+               goto out;
+       }
+
+       dm_get_next_target(task, NULL, &start, &length, &target_type, &params);
+
+       if (!params) {
+               pb_log("Unable to retrieve params for '%s'\n", dm_name);
+               goto out;
+       }
+
+       if (!strncmp(params, "Invalid", strlen("Invalid"))) {
+               pb_log("dm-device %s has become invalid\n", dm_name);
+               goto out;
+       }
+
+       /* Merge is complete when metadata sectors are the only sectors
+        * allocated - see Documentation/device-mapper/snapshot.txt */
+       n = sscanf(params, "%llu/%*u %llu", &sectors, &meta_sectors);
+       if (n != 2) {
+               pb_log("%s unexpected status: '%s'\n", dm_name, params);
+               goto out;
+       }
+       result = sectors == meta_sectors;
+
+       pb_debug("%s merging; %llu sectors, %llu metadata sectors\n",
+                dm_name, sectors, meta_sectors);
+
+out:
+       /* In case of error or an invalid snapshot return true so callers will
+        * move on and catch the error */
+       dm_task_destroy(task);
+       return result;
+}
+
+/* Resume or suspend dm device */
+static int set_device_active(const char *dm_name, bool active)
+{
+       struct dm_task *task;
+       uint32_t cookie;
+       int rc = -1;
+
+       if (active)
+               task = dm_task_create(DM_DEVICE_RESUME);
+       else
+               task = dm_task_create(DM_DEVICE_SUSPEND);
+
+       if (!task) {
+               pb_log("%s: Could not create dm_task\n", __func__);
+               return rc;
+       }
+
+       if (!dm_task_set_name(task, dm_name)) {
+               pb_log("No dm-device named '%s'\n", dm_name);
+               goto out;
+       }
+
+       if (!set_cookie(task, &cookie))
+               goto out;
+
+       if (!dm_task_run(task)) {
+               pb_log("Unable to %s device '%s'\n",
+                      active ? "resume" : "suspend", dm_name);
+               goto out;
+       }
+
+       rc = 0;
+
+       /* Wait for /dev/mapper/ entries to be updated */
+       dm_udev_wait(cookie);
+
+out:
+       dm_task_destroy(task);
+       return rc;
+}
+
+/* Run a DM_DEVICE_CREATE task with provided table (ttype and params) */
+static int run_create_task(const char *dm_name, const struct target *target)
+{
+       struct dm_task *task;
+       uint32_t cookie;
+
+       pb_debug("%s: %lu %lu '%s' '%s'\n", __func__,
+                target->start_sector, target->end_sector,
+                target->ttype, target->params);
+
+       task = dm_task_create(DM_DEVICE_CREATE);
+       if (!task) {
+               pb_log("Error creating new dm-task\n");
+               return -1;
+       }
+
+       if (!dm_task_set_name(task, dm_name))
+               return -1;
+
+       if (!dm_task_add_target(task, target->start_sector, target->end_sector,
+                               target->ttype, target->params))
+               return -1;
+
+       if (!dm_task_set_add_node(task, DM_ADD_NODE_ON_CREATE))
+               return -1;
+
+       if (!set_cookie(task, &cookie))
+               return -1;
+
+       if (!dm_task_run(task)) {
+               pb_log("Error executing dm-task\n");
+               return -1;
+       }
+
+       /* Wait for /dev/mapper/ entry to appear */
+       dm_udev_wait(cookie);
+
+       dm_task_destroy(task);
+       return 0;
+}
+
+static int create_base(struct discover_device *device)
+{
+       struct target target;
+       char *name = NULL;
+       int rc = -1;
+
+       if (!device->ramdisk)
+               return rc;
+
+       target.start_sector = 0;
+       target.end_sector = device->ramdisk->sectors;
+
+       target.ttype = talloc_asprintf(device,  "linear");
+       target.params = talloc_asprintf(device, "%s 0", device->device_path);
+       if (!target.ttype || !target.params) {
+               pb_log("Failed to allocate map parameters\n");
+               goto out;
+       }
+
+       name = talloc_asprintf(device, "%s-base", device->device->id);
+       if (!name || run_create_task(name, &target))
+               goto out;
+
+       device->ramdisk->base = talloc_asprintf(device, "/dev/mapper/%s-base",
+                                       device->device->id);
+       if (!device->ramdisk->base) {
+               pb_log("Failed to track new device /dev/mapper/%s-base\n",
+                       device->device->id);
+               goto out;
+       }
+
+       rc = 0;
+
+out:
+       talloc_free(name);
+       talloc_free(target.params);
+       talloc_free(target.ttype);
+       return rc;
+}
+
+static int create_origin(struct discover_device *device)
+{
+       struct target target;
+       char *name = NULL;
+       int rc = -1;
+
+       if (!device->ramdisk || !device->ramdisk->base)
+               return -1;
+
+       target.start_sector = 0;
+       target.end_sector = device->ramdisk->sectors;
+
+       target.ttype = talloc_asprintf(device,  "snapshot-origin");
+       target.params = talloc_asprintf(device, "%s", device->ramdisk->base);
+       if (!target.ttype || !target.params) {
+               pb_log("Failed to allocate map parameters\n");
+               goto out;
+       }
+
+       name = talloc_asprintf(device, "%s-origin", device->device->id);
+       if (!name || run_create_task(name, &target))
+               goto out;
+
+       device->ramdisk->origin = talloc_asprintf(device,
+                                       "/dev/mapper/%s-origin",
+                                       device->device->id);
+       if (!device->ramdisk->origin) {
+               pb_log("Failed to track new device /dev/mapper/%s-origin\n",
+                      device->device->id);
+               goto out;
+       }
+
+       rc = 0;
+
+out:
+       talloc_free(name);
+       talloc_free(target.params);
+       talloc_free(target.ttype);
+       return rc;
+}
+
+static int create_snapshot(struct discover_device *device)
+{
+       struct target target;
+       int rc = -1;
+
+       if (!device->ramdisk || !device->ramdisk->base ||
+           !device->ramdisk->origin)
+               return -1;
+
+       target.start_sector = 0;
+       target.end_sector = device->ramdisk->sectors;
+
+       target.ttype = talloc_asprintf(device,  "snapshot");
+       target.params = talloc_asprintf(device, "%s %s P 8",
+                device->ramdisk->base, device->ramdisk->path);
+       if (!target.ttype || !target.params) {
+               pb_log("Failed to allocate snapshot parameters\n");
+               goto out;
+       }
+
+       if (run_create_task(device->device->id, &target))
+               goto out;
+
+       device->ramdisk->snapshot = talloc_asprintf(device, "/dev/mapper/%s",
+                                               device->device->id);
+       if (!device->ramdisk->snapshot) {
+               pb_log("Failed to track new device /dev/mapper/%s\n",
+                      device->device->id);
+               goto out;
+       }
+
+       rc = 0;
+
+out:
+       talloc_free(target.params);
+       talloc_free(target.ttype);
+       return rc;
+}
+
+int devmapper_init_snapshot(struct device_handler *handler,
+                    struct discover_device *device)
+{
+       struct ramdisk_device *ramdisk;
+
+       if (config_get()->disable_snapshots)
+               return 0;
+
+       ramdisk = device_handler_get_ramdisk(handler);
+       if (!ramdisk) {
+               pb_log("No ramdisk available for snapshot %s\n",
+                      device->device->id);
+               return -1;
+       }
+
+       ramdisk->sectors = get_block_sectors(device);
+       if (!ramdisk->sectors) {
+               pb_log("Error retreiving sectors for %s\n",
+                      device->device->id);
+               return -1;
+       }
+
+       device->ramdisk = ramdisk;
+
+       /* Create linear map */
+       if (create_base(device)) {
+               pb_log("Error creating linear base\n");
+               goto err;
+       }
+
+       /* Create snapshot-origin */
+       if (create_origin(device)) {
+               pb_log("Error creating snapshot-origin\n");
+               goto err;
+       }
+
+       if (set_device_active(device->ramdisk->origin, false)) {
+               pb_log("Failed to suspend origin\n");
+               goto err;
+       }
+
+       /* Create snapshot */
+       if (create_snapshot(device)) {
+               pb_log("Error creating snapshot\n");
+               goto err;
+       }
+
+       if (set_device_active(device->ramdisk->origin, true)) {
+               pb_log("Failed to resume origin\n");
+               goto err;
+       }
+
+       pb_log("Snapshot successfully created for %s\n", device->device->id);
+
+       return 0;
+
+err:
+       pb_log("Error creating snapshot devices for %s\n", device->device->id);
+       devmapper_destroy_snapshot(device);
+       return -1;
+}
+
+/* Destroy specific dm device */
+static int destroy_device(const char *dm_name)
+{
+       struct dm_task *task;
+       uint32_t cookie;
+       int rc = -1;
+
+       task = dm_task_create(DM_DEVICE_REMOVE);
+       if (!task) {
+               pb_log("%s: could not create dm_task\n", __func__);
+               return -1;
+       }
+
+       if (!dm_task_set_name(task, dm_name)) {
+               pb_log("No dm device named '%s'\n", dm_name);
+               goto out;
+       }
+
+       if (!set_cookie(task, &cookie))
+               goto out;
+
+       if (!dm_task_run(task)) {
+               pb_log("Unable to remove device '%s'\n", dm_name);
+               goto out;
+       }
+
+       rc = 0;
+
+       /* Wait for /dev/mapper/ entries to be removed */
+       dm_udev_wait(cookie);
+
+out:
+       dm_task_destroy(task);
+       return rc;
+}
+
+/* Destroy all dm devices related to a discover_device's snapshot */
+int devmapper_destroy_snapshot(struct discover_device *device)
+{
+       int rc = -1;
+
+       if (!device->ramdisk)
+               return 0;
+
+       if (device->mounted) {
+               pb_log("Can not remove snapshot: %s is mounted\n",
+                      device->device->id);
+               return -1;
+       }
+
+       /* Clean up dm devices in order */
+       if (device->ramdisk->snapshot)
+               if (destroy_device(device->ramdisk->snapshot))
+                       goto out;
+
+       if (device->ramdisk->origin)
+               if (destroy_device(device->ramdisk->origin))
+                       goto out;
+
+       if (device->ramdisk->base)
+               if (destroy_device(device->ramdisk->base))
+                       goto out;
+
+       rc = 0;
+out:
+       if (rc)
+               pb_log("Warning: %s snapshot not cleanly removed\n",
+                      device->device->id);
+       device_handler_release_ramdisk(device);
+       return rc;
+}
+
+static int reload_snapshot(struct discover_device *device, bool merge)
+{
+       struct target target;
+       struct dm_task *task;
+       int rc = -1;
+
+       target.start_sector = 0;
+       target.end_sector = device->ramdisk->sectors;
+
+       if (merge) {
+               target.ttype = talloc_asprintf(device,  "snapshot-merge");
+               target.params = talloc_asprintf(device, "%s %s P 8",
+                        device->ramdisk->base, device->ramdisk->path);
+       } else {
+               target.ttype = talloc_asprintf(device,  "snapshot-origin");
+               target.params = talloc_asprintf(device, "%s",
+                        device->ramdisk->base);
+       }
+       if (!target.ttype || !target.params) {
+               pb_log("%s: failed to allocate parameters\n", __func__);
+               goto err1;
+       }
+
+       task = dm_task_create(DM_DEVICE_RELOAD);
+       if (!task) {
+               pb_log("%s: Error creating task\n", __func__);
+               goto err1;
+       }
+
+       if (!dm_task_set_name(task, device->ramdisk->origin)) {
+               pb_log("No dm-device named '%s'\n", device->ramdisk->origin);
+               goto err2;
+       }
+
+       if (!dm_task_add_target(task, target.start_sector, target.end_sector,
+                               target.ttype, target.params)) {
+               pb_log("%s: Failed to set target\n", __func__);
+               goto err2;
+       }
+
+       if (!dm_task_run(task)) {
+               pb_log("Failed to reload %s\n", device->ramdisk->origin);
+               goto err2;
+       }
+
+       rc = 0;
+err2:
+       dm_task_destroy(task);
+err1:
+       talloc_free(target.ttype);
+       talloc_free(target.params);
+       return rc;
+}
+
+int devmapper_merge_snapshot(struct discover_device *device)
+{
+       if (device->mounted) {
+               pb_log("%s: %s still mounted\n", __func__, device->device->id);
+               return -1;
+       }
+
+       /* Suspend origin device */
+       if (set_device_active(device->ramdisk->origin, false)) {
+               pb_log("%s: failed to suspend %s\n",
+                      __func__, device->ramdisk->origin);
+               return -1;
+       }
+
+       /* Destroy snapshot */
+       if (destroy_device(device->ramdisk->snapshot)) {
+               /* The state of the snapshot is unknown, but try to
+                * resume to allow the snapshot to be remounted */
+               set_device_active(device->ramdisk->origin, true);
+               return -1;
+       }
+       talloc_free(device->ramdisk->snapshot);
+       device->ramdisk->snapshot = NULL;
+
+       /* Reload origin device for merging */
+       reload_snapshot(device, true);
+
+       /* Resume origin device */
+       set_device_active(device->ramdisk->origin, true);
+
+       /* Block until merge complete */
+       while (!snapshot_merge_complete(device->ramdisk->origin))
+               usleep(MERGE_INTERVAL_US);
+
+       /* Suspend origin device */
+       set_device_active(device->ramdisk->origin, false);
+
+       /* Reload origin device */
+       reload_snapshot(device, false);
+
+       /* Re-create snapshot */
+       if (create_snapshot(device))
+               return -1;
+
+       /* Resume origin device */
+       return set_device_active(device->ramdisk->origin, true);
+}
diff --git a/discover/devmapper.h b/discover/devmapper.h
new file mode 100644 (file)
index 0000000..ae8196c
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _DEVMAPPER_H
+#define _DEVMAPPER_H
+
+#include "device-handler.h"
+
+int devmapper_init_snapshot(struct device_handler *handler,
+                    struct discover_device *device);
+int devmapper_destroy_snapshot(struct discover_device *device);
+int devmapper_merge_snapshot(struct discover_device *device);
+
+#endif /* _DEVMAPPER_H */
index 2b3b043489e889573d0033d8c354d5bffb39d8d4..d45cced422917076e3743917a948fc6beefca170 100644 (file)
@@ -53,6 +53,8 @@ static const char *known_params[] = {
        "petitboot,bootdevs",
        "petitboot,language",
        "petitboot,debug?",
+       "petitboot,write?",
+       "petitboot,snapshots?",
        NULL,
 };
 
@@ -548,6 +550,14 @@ static void populate_config(struct platform_powerpc *platform,
                val = get_param(platform, "petitboot,debug?");
                config->debug = val && !strcmp(val, "true");
        }
+
+       val = get_param(platform, "petitboot,write?");
+       if (val)
+               config->allow_writes = !strcmp(val, "true");
+
+       val = get_param(platform, "petitboot,snapshots?");
+       if (val)
+               config->disable_snapshots = !strcmp(val, "false");
 }
 
 static char *iface_config_str(void *ctx, struct interface_config *config)
@@ -707,6 +717,12 @@ static int update_config(struct platform_powerpc *platform,
        val = config->lang ?: "";
        update_string_config(platform, "petitboot,language", val);
 
+       if (config->allow_writes == defaults->allow_writes)
+               val = "";
+       else
+               val = config->allow_writes ? "true" : "false";
+       update_string_config(platform, "petitboot,write?", val);
+
        update_network_config(platform, config);
 
        update_bootdev_config(platform, config);
index 74e2a82df3225519fdcc2ad49ebc3502214bda09..a6bd74c7a0757b0a2f2de8da38eac4c5e9ce8e81 100644 (file)
@@ -35,6 +35,9 @@ static void dump_config(struct config *config)
        if (config->safe_mode)
                pb_log(" safe mode: active\n");
 
+       if (config->disable_snapshots)
+               pb_log(" dm-snapshots disabled\n");
+
        for (i = 0; i < config->network.n_interfaces; i++) {
                struct interface_config *ifconf =
                        config->network.interfaces[i];
@@ -108,6 +111,8 @@ void config_set_defaults(struct config *config)
        config->network.n_dns_servers = 0;
        config->safe_mode = false;
        config->lang = NULL;
+       config->allow_writes = true;
+       config->disable_snapshots = false;
 
        config->n_autoboot_opts = 2;
        config->autoboot_opts = talloc_array(config, struct autoboot_option,
index 6ccb8d4ba42917aed8669cf4e78bff03cc500a6e..6cc718ea4614f9da6e7110fd9901144c5f37fb7c 100644 (file)
@@ -25,6 +25,7 @@
 #include "pb-discover.h"
 #include "device-handler.h"
 #include "cdrom.h"
+#include "devmapper.h"
 
 /* We set a default monitor buffer size, as we may not process monitor
  * events while performing device discvoery. systemd uses a 128M buffer, so
@@ -73,13 +74,21 @@ static int udev_handle_block_add(struct pb_udev *udev, struct udev_device *dev,
                const char *name)
 {
        struct discover_device *ddev;
+       unsigned int i = 0;
        const char *typestr;
        const char *uuid;
        const char *path;
        const char *node;
        const char *prop;
        const char *type;
-       bool cdrom;
+       const char *devname;
+       const char *ignored_types[] = {
+               "linux_raid_member",
+               "swap",
+               "LVM2_member",
+               NULL,
+       };
+       bool cdrom, usb;
 
        typestr = udev_device_get_devtype(dev);
        if (!typestr) {
@@ -94,12 +103,16 @@ static int udev_handle_block_add(struct pb_udev *udev, struct udev_device *dev,
 
        node = udev_device_get_devnode(dev);
        path = udev_device_get_devpath(dev);
-       if (path && (strstr(path, "virtual/block/loop")
-                       || strstr(path, "virtual/block/ram"))) {
+       if (path && strstr(path, "virtual/block/loop")) {
                pb_log("SKIP: %s: ignored (path=%s)\n", name, path);
                return 0;
        }
 
+       if (path && strstr(path, "virtual/block/ram")) {
+               device_handler_add_ramdisk(udev->handler, node);
+               return 0;
+       }
+
        cdrom = node && !!udev_device_get_property_value(dev, "ID_CDROM");
        if (cdrom) {
                /* CDROMs require a little initialisation, to get
@@ -111,12 +124,28 @@ static int udev_handle_block_add(struct pb_udev *udev, struct udev_device *dev,
                }
        }
 
+       /* If our environment's udev can recognise them explictly skip any
+        * device mapper devices we encounter */
+       devname = udev_device_get_property_value(dev, "DM_NAME");
+       if (devname) {
+               pb_debug("SKIP: dm-device %s\n", devname);
+               return 0;
+       }
+
        type = udev_device_get_property_value(dev, "ID_FS_TYPE");
        if (!type) {
                pb_log("SKIP: %s: no ID_FS_TYPE property\n", name);
                return 0;
        }
 
+       while (ignored_types[i]) {
+               if (!strncmp(type, ignored_types[i], strlen(ignored_types[i]))) {
+                       pb_log("SKIP: %s: ignore '%s' filesystem\n", name, type);
+                       return 0;
+               }
+               i++;
+       }
+
        /* We may see multipath devices; they'll have the same uuid as an
         * existing device, so only parse the first. */
        uuid = udev_device_get_property_value(dev, "ID_FS_UUID");
@@ -138,10 +167,21 @@ static int udev_handle_block_add(struct pb_udev *udev, struct udev_device *dev,
        prop = udev_device_get_property_value(dev, "ID_FS_LABEL");
        if (prop)
                ddev->label = talloc_strdup(ddev, prop);
-       ddev->device->type = cdrom ? DEVICE_TYPE_OPTICAL : DEVICE_TYPE_DISK;
+
+       usb = !!udev_device_get_property_value(dev, "ID_USB_DRIVER");
+       if (cdrom)
+               ddev->device->type = DEVICE_TYPE_OPTICAL;
+       else
+               ddev->device->type = usb ? DEVICE_TYPE_USB : DEVICE_TYPE_DISK;
 
        udev_setup_device_params(dev, ddev);
 
+       /* Create a snapshot for all disks, unless it is an assembled RAID array */
+       if ((ddev->device->type == DEVICE_TYPE_DISK ||
+            ddev->device->type == DEVICE_TYPE_USB) &&
+           !udev_device_get_property_value(dev, "MD_LEVEL"))
+               devmapper_init_snapshot(udev->handler, ddev);
+
        device_handler_discover(udev->handler, ddev);
 
        return 0;
index b39cc9bebef9f0bd5e9a3ae43dc739441394ce11..a2421a52f498c0e69363c996eaa334d4dc4e0f7b 100644 (file)
@@ -26,6 +26,7 @@ lib_libpbcore_la_SOURCES = \
        lib/fold/fold.h \
        lib/fold/fold.c \
        lib/i18n/i18n.h \
+       lib/i18n/i18n.c \
        lib/log/log.h \
        lib/log/log.c \
        lib/list/list.c \
index fd23b066f3e58b49c107176d5957c8eaae68b845..2566253aca8de697149d2c17477eb26ba14b455a 100644 (file)
@@ -36,8 +36,9 @@ void fold_text(const char *text,
 
                assert(bytes != (size_t)-1);
 
-               /* we'll get a zero size for the nul terminator */
-               if (!bytes) {
+               /* we'll get a zero size for the nul terminator, or (size_t) -2
+                * if we've reached the end of the buffer */
+               if (!bytes || bytes == (size_t) -2) {
                        line_cb(arg, start, end - start);
                        break;
                }
diff --git a/lib/i18n/i18n.c b/lib/i18n/i18n.c
new file mode 100644 (file)
index 0000000..dd8d79b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  Copyright (C) 2013 IBM Corporation
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define _XOPEN_SOURCE
+
+#include <string.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+#include <i18n/i18n.h>
+
+/* Return the number of columns required to display a localised string */
+int strncols(const char *str)
+{
+       int wlen, ncols;
+       wchar_t *wstr;
+
+       wlen = mbstowcs(NULL, str, 0);
+       if (wlen <= 0)
+               return wlen;
+
+       wstr = malloc(sizeof(wchar_t) * wlen + 1);
+       if (!wstr)
+               return -1;
+
+       wlen = mbstowcs(wstr, str, wlen);
+       if (wlen <= 0) {
+               free(wstr);
+               return wlen;
+       }
+
+       ncols = wcswidth(wstr, wlen);
+
+       free(wstr);
+       return ncols;
+}
index d7ff154ded7535e8468fa041b6dba6b8d472297b..dde02f1423962bda5eea398a7334cb8533185f84 100644 (file)
@@ -22,5 +22,7 @@
 
 #define _(x) gettext(x)
 
+int strncols(const char *str);
+
 #endif /* I18N_H */
 
index 98a6078bc552bb19f6a95d841ba2dd13024807f2..8200883a4a5d8ddd44bf593e6b60c0d24e441b00 100644 (file)
@@ -77,6 +77,8 @@ struct config *config_copy(void *ctx, const struct config *src)
        dest->ipmi_bootdev = src->ipmi_bootdev;
        dest->ipmi_bootdev_persistent = src->ipmi_bootdev_persistent;
 
+       dest->allow_writes = src->allow_writes;
+
        if (src->lang && strlen(src->lang))
                dest->lang = talloc_strdup(dest, src->lang);
        else
index 69ea35d2eed735382abe2bf22acc64444311159c..7d45f512b0dcb81db6b83ba6223e6eb921dde30f 100644 (file)
@@ -290,6 +290,8 @@ int pb_protocol_config_len(const struct config *config)
 
        len += 4 + 4; /* ipmi_bootdev, ipmi_bootdev_persistent */
 
+       len += 4; /* allow_writes */
+
        len += 4 + optional_strlen(config->lang);
 
        return len;
@@ -502,6 +504,9 @@ int pb_protocol_serialise_config(const struct config *config,
        *(uint32_t *)pos = config->ipmi_bootdev_persistent;
        pos += 4;
 
+       *(uint32_t *)pos = config->allow_writes;
+       pos += 4;
+
        pos += pb_protocol_serialise_string(pos, config->lang);
 
        assert(pos <= buf + buf_len);
@@ -958,6 +963,10 @@ int pb_protocol_deserialise_config(struct config *config,
                goto out;
        config->ipmi_bootdev_persistent = !!tmp;
 
+       if (read_u32(&pos, &len, &tmp))
+               goto out;
+       config->allow_writes = !!tmp;
+
        if (read_string(config, &pos, &len, &str))
                goto out;
 
index 95a3a48cb4fca9571fa9a6eac54449b9c2378c2e..63045e1a29d2a933abd98bb8ed8826f2adea7a9c 100644 (file)
@@ -27,8 +27,10 @@ const char *device_type_display_name(enum device_type type)
        switch (type) {
        case DEVICE_TYPE_DISK:
                return _("Disk");
+       case DEVICE_TYPE_USB:
+               return _("USB");
        case DEVICE_TYPE_OPTICAL:
-               return _("Optical");
+               return _("CD/DVD");
        case DEVICE_TYPE_NETWORK:
                return _("Network");
        case DEVICE_TYPE_ANY:
@@ -44,6 +46,8 @@ const char *device_type_name(enum device_type type)
        switch (type) {
        case DEVICE_TYPE_DISK:
                return "disk";
+       case DEVICE_TYPE_USB:
+               return "usb";
        case DEVICE_TYPE_OPTICAL:
                return "optical";
        case DEVICE_TYPE_NETWORK:
@@ -60,6 +64,8 @@ enum device_type find_device_type(const char *str)
 {
        if (!strncmp(str, "disk", strlen("disk")))
                return DEVICE_TYPE_DISK;
+       if (!strncmp(str, "usb", strlen("usb")))
+               return DEVICE_TYPE_USB;
        if (!strncmp(str, "optical", strlen("optical")))
                return DEVICE_TYPE_OPTICAL;
        if (!strncmp(str, "network", strlen("network")))
index e5c7e3e00225daa162c7850eb1d302da63074f7a..6a2c25810fff5c80a07ad2f11af44924b225f469 100644 (file)
@@ -8,6 +8,7 @@
 enum device_type {
        DEVICE_TYPE_NETWORK,
        DEVICE_TYPE_DISK,
+       DEVICE_TYPE_USB,
        DEVICE_TYPE_OPTICAL,
        DEVICE_TYPE_ANY,
        DEVICE_TYPE_UNKNOWN,
@@ -146,9 +147,12 @@ struct config {
        unsigned int            ipmi_bootdev;
        bool                    ipmi_bootdev_persistent;
 
+       bool                    allow_writes;
+
        char                    *lang;
 
        /* not user-settable */
+       bool                    disable_snapshots;
        bool                    safe_mode;
        bool                    debug;
 };
index c6b41f2323655f65ad2ef61ae0f287ef42dc0cb2..5db0e248b13afe107315e8036613331ec156e7e8 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: petitboot 20140623-g89bd2ed2-dirty\n"
 "Report-Msgid-Bugs-To: Geoff Levand <geoff@infradead.org>\n"
-"POT-Creation-Date: 2014-10-13 09:24+1100\n"
+"POT-Creation-Date: 2015-08-19 14:19+1000\n"
 "PO-Revision-Date: 2014-06-24 13:56+0800\n"
 "Last-Translator: Jeremy Kerr <jk@ozlabs.org>\n"
 "Language-Team: German\n"
@@ -17,7 +17,7 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 msgid "running boot hooks"
-msgstr "Aktive Boot-Anbindungspunkte (Hooks)"
+msgstr "Aktive Bootanbindungspunkte"
 
 #, c-format
 msgid "Couldn't load %s"
@@ -130,20 +130,28 @@ msgstr "Systemkonfiguration"
 msgid "No IP / mask values are set"
 msgstr "Keine Werte für IP/Maske festgelegt"
 
+msgid "Select a boot device to add"
+msgstr "Wählen Sie eine Booteinheit aus, die hinzugefügt werden soll"
+
 msgid "Waiting for configuration data..."
 msgstr "Warten auf Konfigurationsdaten..."
 
-msgid "Autoboot:"
-msgstr "Autom. Booten:"
+#, fuzzy
+msgid "Add Device"
+msgstr "Einheit:"
 
-msgid "Don't autoboot"
-msgstr "Kein automatisches Booten"
+msgid "Clear"
+msgstr "Inhalt löschen"
 
-msgid "Autoboot from any disk/network device"
-msgstr "Von jeder Platte/Netzeinheit automatisch booten"
+msgid "Clear & Boot Any"
+msgstr "Inhalt löschen & beliebige booten"
 
-msgid "Only autoboot from a specific disk/network device"
-msgstr "Nur von bestimmter Platte/Netzeinheit autom. booten"
+#, fuzzy
+msgid "Boot Order:"
+msgstr "Bootargumente:"
+
+msgid "(None)"
+msgstr "(Keine Angabe)"
 
 #, c-format
 msgid "disk: %s [uuid: %s]"
@@ -153,9 +161,13 @@ msgstr "Platte: %s [UUID: %s]"
 msgid "net:  %s [mac: %s]"
 msgstr "Netz:  %s [MAC: %s]"
 
+#, fuzzy
+msgid "Any Device"
+msgstr "Einheit:"
+
 #, c-format
-msgid "Unknown UUID: %s"
-msgstr "Unbekannte UUID: %s"
+msgid "Any %s device"
+msgstr "Jede %s-Einheit"
 
 msgid "Timeout:"
 msgstr "Zeitlimit:"
@@ -163,6 +175,13 @@ msgstr "Zeitlimit:"
 msgid "seconds"
 msgstr "Sekunden"
 
+#, c-format
+msgid "%s IPMI boot option: %s"
+msgstr "IPMI-Bootoption für %s: %s"
+
+msgid "Clear option:"
+msgstr "Option 'Inhalt löschen':"
+
 msgid "Network:"
 msgstr "Netz:"
 
@@ -205,6 +224,17 @@ msgstr "(falls nicht vom DHCP-Server bereitgestellt)"
 msgid "Selecting 'OK' will exit safe mode"
 msgstr "Durch die Auswahl von 'OK' wird der abgesicherte Modus beendet"
 
+#, fuzzy
+msgid "Disk R/W:"
+msgstr "Platte"
+
+msgid "Prevent all writes to disk"
+msgstr "Alle Schreibvorgänge auf die Platte verhindern"
+
+msgid "Allow bootloader scripts to modify disks"
+msgstr ""
+"Zulassen, dass mit Scripts des Bootladeprogramms Platten geändert werden"
+
 msgid "Petitboot System Configuration"
 msgstr "Petitboot-Systemkonfiguration"
 
@@ -425,7 +455,7 @@ msgid ""
 "host/pxeconffile or http://host/pxeconffile"
 msgstr ""
 "Geben Sie hier eine gültige URL ein, um eine ferne Konfigurationsdatei vom "
-"Typ 'pxe-boot' abzurufen, und analysieren sie sie.\n"
+"Typ 'pxe-boot' abzurufen, und analysieren Sie sie.\n"
 "\n"
 "URLs haben das Format 'Schema://host/path/to/pxeconffile'. Beispiele: tftp://"
 "host/pxeconffile oder http://host/pxeconffile"
@@ -483,24 +513,29 @@ msgstr ""
 "Beispiel: root=/dev/sda1 console=hvc0\n"
 "\n"
 
+#, fuzzy
 msgid ""
-"Autoboot: There are three possible options for automatic-boot hehaviour:\n"
-"\n"
-"Don't autoboot: boot options will be listed in the petitboot menu, but none "
-"will be booted automatically. User interaction will be required to continue "
+"Autoboot: Specify which devices to autoboot from.\n"
+"\n"
+"By selecting the 'Add Device' button new devices can be added to the "
+"autoboot list, either by UUID, MAC address, or device type. Once added to "
+"the boot order, the priority of devices can be changed with the 'left' and "
+"'right' keys Devices can be individually removed from the boot order with "
+"the minus key. Use this option if you have multiple operating system images "
+"installed.\n"
+"\n"
+"To autoboot from any device, select the 'Clear & Boot Any' button. In this "
+"case, any boot option that is marked as a default (by bootloader "
+"configuration) will be booted automatically after a timeout. Use this option "
+"if you want to quickly boot your system without changing any boot option "
+"settings. This is the typical configuration.\n"
+"\n"
+"To disable autoboot, select the 'Clear' button, which will clear the boot "
+"order. With autoboot disabled, user interaction will be required to continue "
 "past the petitboot menu. Use this option if you want the machine to wait for "
 "an explicit boot selection, or want to interact with petitboot before "
 "booting the system\n"
 "\n"
-"Autoboot from any disk/network device: any boot option that is marked as a "
-"default (by bootloader configuration) will be booted automatically after a "
-"timeout. Use this option if you want to quickly boot your system without "
-"changing any boot option settings. This is the typical configuration.\n"
-"\n"
-"Only autoboot from a specific disk/network device: only boot options from a "
-"single device (specifed here) will be booted automatically after a timeout. "
-"Use this option if you have multiple operating system images installed.\n"
-"\n"
 "Timeout: Specify the length of time, in seconds, that the main menu will be "
 "displayed before the default boot option is started. This option is only "
 "displayed if autoboot is enabled.\n"
@@ -567,3 +602,18 @@ msgstr ""
 
 msgid "Usage"
 msgstr "Verwendung"
+
+#~ msgid "Autoboot:"
+#~ msgstr "Autoboot:"
+
+#~ msgid "Don't autoboot"
+#~ msgstr "Don't autoboot"
+
+#~ msgid "Autoboot from any disk/network device"
+#~ msgstr "Autoboot from any disk/network device"
+
+#~ msgid "Only autoboot from a specific disk/network device"
+#~ msgstr "Only autoboot from a specific disk/network device"
+
+#~ msgid "Unknown UUID: %s"
+#~ msgstr "Unknown UUID: %s"
index 5a3edde907a52f9522b2afcec4ed2148b08797e4..e3e07b5aab77cc51c5d9951e0e06215ee7686360 100644 (file)
--- a/po/en.po
+++ b/po/en.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: petitboot 20140623-g89bd2ed2-dirty\n"
 "Report-Msgid-Bugs-To: Geoff Levand <geoff@infradead.org>\n"
-"POT-Creation-Date: 2014-10-13 09:24+1100\n"
+"POT-Creation-Date: 2015-08-19 14:19+1000\n"
 "PO-Revision-Date: 2014-06-24 13:56+0800\n"
 "Last-Translator: Jeremy Kerr <jk@ozlabs.org>\n"
 "Language-Team: English\n"
@@ -128,20 +128,28 @@ msgstr "System Configuration"
 msgid "No IP / mask values are set"
 msgstr "No IP / mask values are set"
 
+msgid "Select a boot device to add"
+msgstr ""
+
 msgid "Waiting for configuration data..."
 msgstr "Waiting for configuration data..."
 
-msgid "Autoboot:"
-msgstr "Autoboot:"
+#, fuzzy
+msgid "Add Device"
+msgstr "Device:"
+
+msgid "Clear"
+msgstr ""
 
-msgid "Don't autoboot"
-msgstr "Don't autoboot"
+msgid "Clear & Boot Any"
+msgstr ""
 
-msgid "Autoboot from any disk/network device"
-msgstr "Autoboot from any disk/network device"
+#, fuzzy
+msgid "Boot Order:"
+msgstr "Boot arguments:"
 
-msgid "Only autoboot from a specific disk/network device"
-msgstr "Only autoboot from a specific disk/network device"
+msgid "(None)"
+msgstr ""
 
 #, c-format
 msgid "disk: %s [uuid: %s]"
@@ -151,9 +159,13 @@ msgstr "disk: %s [uuid: %s]"
 msgid "net:  %s [mac: %s]"
 msgstr "net:  %s [mac: %s]"
 
+#, fuzzy
+msgid "Any Device"
+msgstr "Device:"
+
 #, c-format
-msgid "Unknown UUID: %s"
-msgstr "Unknown UUID: %s"
+msgid "Any %s device"
+msgstr ""
 
 msgid "Timeout:"
 msgstr "Timeout:"
@@ -161,6 +173,13 @@ msgstr "Timeout:"
 msgid "seconds"
 msgstr "seconds"
 
+#, c-format
+msgid "%s IPMI boot option: %s"
+msgstr ""
+
+msgid "Clear option:"
+msgstr ""
+
 msgid "Network:"
 msgstr "Network:"
 
@@ -203,6 +222,16 @@ msgstr "(if not provided by DHCP server)"
 msgid "Selecting 'OK' will exit safe mode"
 msgstr "Selecting 'OK' will exit safe mode"
 
+#, fuzzy
+msgid "Disk R/W:"
+msgstr "Disk"
+
+msgid "Prevent all writes to disk"
+msgstr ""
+
+msgid "Allow bootloader scripts to modify disks"
+msgstr ""
+
 msgid "Petitboot System Configuration"
 msgstr "Petitboot System Configuration"
 
@@ -470,24 +499,29 @@ msgstr ""
 "Example: root=/dev/sda1 console=hvc0\n"
 "\n"
 
+#, fuzzy
 msgid ""
-"Autoboot: There are three possible options for automatic-boot hehaviour:\n"
-"\n"
-"Don't autoboot: boot options will be listed in the petitboot menu, but none "
-"will be booted automatically. User interaction will be required to continue "
+"Autoboot: Specify which devices to autoboot from.\n"
+"\n"
+"By selecting the 'Add Device' button new devices can be added to the "
+"autoboot list, either by UUID, MAC address, or device type. Once added to "
+"the boot order, the priority of devices can be changed with the 'left' and "
+"'right' keys Devices can be individually removed from the boot order with "
+"the minus key. Use this option if you have multiple operating system images "
+"installed.\n"
+"\n"
+"To autoboot from any device, select the 'Clear & Boot Any' button. In this "
+"case, any boot option that is marked as a default (by bootloader "
+"configuration) will be booted automatically after a timeout. Use this option "
+"if you want to quickly boot your system without changing any boot option "
+"settings. This is the typical configuration.\n"
+"\n"
+"To disable autoboot, select the 'Clear' button, which will clear the boot "
+"order. With autoboot disabled, user interaction will be required to continue "
 "past the petitboot menu. Use this option if you want the machine to wait for "
 "an explicit boot selection, or want to interact with petitboot before "
 "booting the system\n"
 "\n"
-"Autoboot from any disk/network device: any boot option that is marked as a "
-"default (by bootloader configuration) will be booted automatically after a "
-"timeout. Use this option if you want to quickly boot your system without "
-"changing any boot option settings. This is the typical configuration.\n"
-"\n"
-"Only autoboot from a specific disk/network device: only boot options from a "
-"single device (specifed here) will be booted automatically after a timeout. "
-"Use this option if you have multiple operating system images installed.\n"
-"\n"
 "Timeout: Specify the length of time, in seconds, that the main menu will be "
 "displayed before the default boot option is started. This option is only "
 "displayed if autoboot is enabled.\n"
@@ -547,3 +581,18 @@ msgstr ""
 
 msgid "Usage"
 msgstr "Usage"
+
+#~ msgid "Autoboot:"
+#~ msgstr "Autoboot:"
+
+#~ msgid "Don't autoboot"
+#~ msgstr "Don't autoboot"
+
+#~ msgid "Autoboot from any disk/network device"
+#~ msgstr "Autoboot from any disk/network device"
+
+#~ msgid "Only autoboot from a specific disk/network device"
+#~ msgstr "Only autoboot from a specific disk/network device"
+
+#~ msgid "Unknown UUID: %s"
+#~ msgstr "Unknown UUID: %s"
index 09629e2591810ea277a74a8e623b6f10ad4a7eb4..1683881eb6c06f6142fb2b2e811e179489dc5e61 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: petitboot 20140623-g89bd2ed2-dirty\n"
 "Report-Msgid-Bugs-To: Geoff Levand <geoff@infradead.org>\n"
-"POT-Creation-Date: 2014-10-13 09:24+1100\n"
+"POT-Creation-Date: 2015-08-19 14:19+1000\n"
 "PO-Revision-Date: 2014-06-24 13:56+0800\n"
 "Last-Translator: Jeremy Kerr <jk@ozlabs.org>\n"
 "Language-Team: Spanish\n"
@@ -14,7 +14,7 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
 
 msgid "running boot hooks"
 msgstr "ejecutando ganchos de arranque"
@@ -96,7 +96,7 @@ msgid "Petitboot Config Retrieval"
 msgstr "Recuperación de configuración de Petitboot"
 
 msgid "tab=next, shift+tab=previous, x=exit, h=help"
-msgstr "tab=siguiente, shift+tab=anterior, x=salida, h=ayuda"
+msgstr "tab=siguiente, mayús+tab=anterior, x=salir, h=ayuda"
 
 msgid "Boot Option Editor"
 msgstr "Editor de opciones de arranque"
@@ -128,20 +128,28 @@ msgstr "Configuración del sistema"
 msgid "No IP / mask values are set"
 msgstr "No se han establecido valores IP / máscara"
 
+msgid "Select a boot device to add"
+msgstr "Seleccione un dispositivo de arranque para añadirlo"
+
 msgid "Waiting for configuration data..."
 msgstr "Esperando datos de configuración..."
 
-msgid "Autoboot:"
-msgstr "Arranque automático:"
+#, fuzzy
+msgid "Add Device"
+msgstr "Dispositivo:"
 
-msgid "Don't autoboot"
-msgstr "No arrancar automáticamente"
+msgid "Clear"
+msgstr "Borrar"
 
-msgid "Autoboot from any disk/network device"
-msgstr "Arranque automático desde cualquier dispositivo de disco/red"
+msgid "Clear & Boot Any"
+msgstr "Borrar y realizar cualquier arranque"
 
-msgid "Only autoboot from a specific disk/network device"
-msgstr "Arranque automático sólo desde un dispositivo de disco/red"
+#, fuzzy
+msgid "Boot Order:"
+msgstr "Argumentos de arranque:"
+
+msgid "(None)"
+msgstr "(Ninguno)"
 
 #, c-format
 msgid "disk: %s [uuid: %s]"
@@ -151,16 +159,27 @@ msgstr "disco: %s [uuid: %s]"
 msgid "net:  %s [mac: %s]"
 msgstr "red:  %s [mac: %s]"
 
+#, fuzzy
+msgid "Any Device"
+msgstr "Dispositivo:"
+
 #, c-format
-msgid "Unknown UUID: %s"
-msgstr "UUID desconocido: %s"
+msgid "Any %s device"
+msgstr "Cualquier dispositivo %s"
 
 msgid "Timeout:"
-msgstr "Tiempo de espera:"
+msgstr "Tiempo espera:"
 
 msgid "seconds"
 msgstr "segundos"
 
+#, c-format
+msgid "%s IPMI boot option: %s"
+msgstr "Opción de arranque de IPMI %s: %s"
+
+msgid "Clear option:"
+msgstr "Borrar opción:"
+
 msgid "Network:"
 msgstr "Red:"
 
@@ -203,6 +222,16 @@ msgstr "(si no se proporciona por servidor DHCP)"
 msgid "Selecting 'OK' will exit safe mode"
 msgstr "Si selecciona 'Aceptar' saldrá de la modalidad segura"
 
+#, fuzzy
+msgid "Disk R/W:"
+msgstr "Disco"
+
+msgid "Prevent all writes to disk"
+msgstr "Impide todas las escrituras en disco"
+
+msgid "Allow bootloader scripts to modify disks"
+msgstr "Permite a los scripts del gestor de arranque modificar los discos"
+
 msgid "Petitboot System Configuration"
 msgstr "Configuración del sistema de Petitboot"
 
@@ -475,24 +504,29 @@ msgstr ""
 "Ejemplo: root=/dev/sda1 console=hvc0\n"
 "\n"
 
+#, fuzzy
 msgid ""
-"Autoboot: There are three possible options for automatic-boot hehaviour:\n"
-"\n"
-"Don't autoboot: boot options will be listed in the petitboot menu, but none "
-"will be booted automatically. User interaction will be required to continue "
+"Autoboot: Specify which devices to autoboot from.\n"
+"\n"
+"By selecting the 'Add Device' button new devices can be added to the "
+"autoboot list, either by UUID, MAC address, or device type. Once added to "
+"the boot order, the priority of devices can be changed with the 'left' and "
+"'right' keys Devices can be individually removed from the boot order with "
+"the minus key. Use this option if you have multiple operating system images "
+"installed.\n"
+"\n"
+"To autoboot from any device, select the 'Clear & Boot Any' button. In this "
+"case, any boot option that is marked as a default (by bootloader "
+"configuration) will be booted automatically after a timeout. Use this option "
+"if you want to quickly boot your system without changing any boot option "
+"settings. This is the typical configuration.\n"
+"\n"
+"To disable autoboot, select the 'Clear' button, which will clear the boot "
+"order. With autoboot disabled, user interaction will be required to continue "
 "past the petitboot menu. Use this option if you want the machine to wait for "
 "an explicit boot selection, or want to interact with petitboot before "
 "booting the system\n"
 "\n"
-"Autoboot from any disk/network device: any boot option that is marked as a "
-"default (by bootloader configuration) will be booted automatically after a "
-"timeout. Use this option if you want to quickly boot your system without "
-"changing any boot option settings. This is the typical configuration.\n"
-"\n"
-"Only autoboot from a specific disk/network device: only boot options from a "
-"single device (specifed here) will be booted automatically after a timeout. "
-"Use this option if you have multiple operating system images installed.\n"
-"\n"
 "Timeout: Specify the length of time, in seconds, that the main menu will be "
 "displayed before the default boot option is started. This option is only "
 "displayed if autoboot is enabled.\n"
@@ -557,3 +591,18 @@ msgstr ""
 
 msgid "Usage"
 msgstr "Uso"
+
+#~ msgid "Autoboot:"
+#~ msgstr "Autoboot:"
+
+#~ msgid "Don't autoboot"
+#~ msgstr "Don't autoboot"
+
+#~ msgid "Autoboot from any disk/network device"
+#~ msgstr "Autoboot from any disk/network device"
+
+#~ msgid "Only autoboot from a specific disk/network device"
+#~ msgstr "Only autoboot from a specific disk/network device"
+
+#~ msgid "Unknown UUID: %s"
+#~ msgstr "Unknown UUID: %s"
index 6d3e15fa0cf5d2cdea07e9958e33945af9562b03..a136ad9eee3c59f03ab8807ae3a8f23da52fea88 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: petitboot 20140623-g89bd2ed2-dirty\n"
 "Report-Msgid-Bugs-To: Geoff Levand <geoff@infradead.org>\n"
-"POT-Creation-Date: 2014-10-13 09:24+1100\n"
+"POT-Creation-Date: 2015-08-19 14:19+1000\n"
 "PO-Revision-Date: 2014-06-24 13:56+0800\n"
 "Last-Translator: Jeremy Kerr <jk@ozlabs.org>\n"
 "Language-Team: French\n"
@@ -14,7 +14,7 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=2; plural=n>1;\n"
 
 msgid "running boot hooks"
 msgstr "exécution points d'ancrage d'amorçage"
@@ -128,20 +128,28 @@ msgstr "Configuration système"
 msgid "No IP / mask values are set"
 msgstr "Aucune valeur IP/de masque définie"
 
+msgid "Select a boot device to add"
+msgstr "Sélectionner une unité d'amorçage à ajouter"
+
 msgid "Waiting for configuration data..."
 msgstr "Attente de données de configuration..."
 
-msgid "Autoboot:"
-msgstr "Amorçage auto :"
+#, fuzzy
+msgid "Add Device"
+msgstr "Unité :"
 
-msgid "Don't autoboot"
-msgstr "Pas d'amorçage automatique"
+msgid "Clear"
+msgstr "Effacer"
 
-msgid "Autoboot from any disk/network device"
-msgstr "Amorçage automatique depuis unité de disque/réseau"
+msgid "Clear & Boot Any"
+msgstr "Effacer & amorcer"
 
-msgid "Only autoboot from a specific disk/network device"
-msgstr "Amorçage auto seulement depuis unité disque/réseau spécifique"
+#, fuzzy
+msgid "Boot Order:"
+msgstr "Arguments d'amorçage :"
+
+msgid "(None)"
+msgstr "(Aucun)"
 
 #, c-format
 msgid "disk: %s [uuid: %s]"
@@ -151,9 +159,13 @@ msgstr "disque : %s [uuid : %s]"
 msgid "net:  %s [mac: %s]"
 msgstr "réseau :  %s [mac : %s]"
 
+#, fuzzy
+msgid "Any Device"
+msgstr "Unité :"
+
 #, c-format
-msgid "Unknown UUID: %s"
-msgstr "UUID inconnu : %s"
+msgid "Any %s device"
+msgstr "N'importe quelle unité %s"
 
 msgid "Timeout:"
 msgstr "Délai attente :"
@@ -161,6 +173,13 @@ msgstr "Délai attente :"
 msgid "seconds"
 msgstr "secondes"
 
+#, c-format
+msgid "%s IPMI boot option: %s"
+msgstr "%s Option d'amorçage IPMI : %s"
+
+msgid "Clear option:"
+msgstr "Option d'effacement :"
+
 msgid "Network:"
 msgstr "Réseau :"
 
@@ -203,6 +222,16 @@ msgstr "(si non fourni par le serveur DHCP)"
 msgid "Selecting 'OK' will exit safe mode"
 msgstr "Sélectionner 'OK' vous fera sortir du mode sans échec"
 
+#, fuzzy
+msgid "Disk R/W:"
+msgstr "Disque"
+
+msgid "Prevent all writes to disk"
+msgstr "Empêcher toute écriture sur le disque "
+
+msgid "Allow bootloader scripts to modify disks"
+msgstr "Autoriser les scripts de chargeur de démarrage à modifier les disques "
+
 msgid "Petitboot System Configuration"
 msgstr "Configuration de système Petitboot"
 
@@ -476,24 +505,29 @@ msgstr ""
 "Exemple : root=/dev/sda1 console=hvc0\n"
 "\n"
 
+#, fuzzy
 msgid ""
-"Autoboot: There are three possible options for automatic-boot hehaviour:\n"
-"\n"
-"Don't autoboot: boot options will be listed in the petitboot menu, but none "
-"will be booted automatically. User interaction will be required to continue "
+"Autoboot: Specify which devices to autoboot from.\n"
+"\n"
+"By selecting the 'Add Device' button new devices can be added to the "
+"autoboot list, either by UUID, MAC address, or device type. Once added to "
+"the boot order, the priority of devices can be changed with the 'left' and "
+"'right' keys Devices can be individually removed from the boot order with "
+"the minus key. Use this option if you have multiple operating system images "
+"installed.\n"
+"\n"
+"To autoboot from any device, select the 'Clear & Boot Any' button. In this "
+"case, any boot option that is marked as a default (by bootloader "
+"configuration) will be booted automatically after a timeout. Use this option "
+"if you want to quickly boot your system without changing any boot option "
+"settings. This is the typical configuration.\n"
+"\n"
+"To disable autoboot, select the 'Clear' button, which will clear the boot "
+"order. With autoboot disabled, user interaction will be required to continue "
 "past the petitboot menu. Use this option if you want the machine to wait for "
 "an explicit boot selection, or want to interact with petitboot before "
 "booting the system\n"
 "\n"
-"Autoboot from any disk/network device: any boot option that is marked as a "
-"default (by bootloader configuration) will be booted automatically after a "
-"timeout. Use this option if you want to quickly boot your system without "
-"changing any boot option settings. This is the typical configuration.\n"
-"\n"
-"Only autoboot from a specific disk/network device: only boot options from a "
-"single device (specifed here) will be booted automatically after a timeout. "
-"Use this option if you have multiple operating system images installed.\n"
-"\n"
 "Timeout: Specify the length of time, in seconds, that the main menu will be "
 "displayed before the default boot option is started. This option is only "
 "displayed if autoboot is enabled.\n"
@@ -558,3 +592,18 @@ msgstr ""
 
 msgid "Usage"
 msgstr "Utilisation"
+
+#~ msgid "Autoboot:"
+#~ msgstr "Autoboot:"
+
+#~ msgid "Don't autoboot"
+#~ msgstr "Don't autoboot"
+
+#~ msgid "Autoboot from any disk/network device"
+#~ msgstr "Autoboot from any disk/network device"
+
+#~ msgid "Only autoboot from a specific disk/network device"
+#~ msgstr "Only autoboot from a specific disk/network device"
+
+#~ msgid "Unknown UUID: %s"
+#~ msgstr "Unknown UUID: %s"
index 1c351985e8fc8e78ca661c7f65efed9ef28ee5dd..601b85f1ff6cc96a6ac65d3e50ca2d22d6348331 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: petitboot 20140623-g89bd2ed2-dirty\n"
 "Report-Msgid-Bugs-To: Geoff Levand <geoff@infradead.org>\n"
-"POT-Creation-Date: 2014-10-13 09:24+1100\n"
+"POT-Creation-Date: 2015-08-19 14:19+1000\n"
 "PO-Revision-Date: 2014-06-24 13:56+0800\n"
 "Last-Translator: Jeremy Kerr <jk@ozlabs.org>\n"
 "Language-Team: Italian\n"
@@ -14,7 +14,7 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
 
 msgid "running boot hooks"
 msgstr "esecuzione di hook di avvio"
@@ -129,20 +129,28 @@ msgstr "Configurazione di sistema"
 msgid "No IP / mask values are set"
 msgstr "Non è stato impostato alcun valore di IP/maschera"
 
+msgid "Select a boot device to add"
+msgstr "Selezionare un dispositivo di avvio da aggiungere"
+
 msgid "Waiting for configuration data..."
 msgstr "In attesa dei dati di configurazione..."
 
-msgid "Autoboot:"
-msgstr "Avvio automatico:"
+#, fuzzy
+msgid "Add Device"
+msgstr "Dispositivo:"
 
-msgid "Don't autoboot"
-msgstr "Non eseguire l'avvio automatico"
+msgid "Clear"
+msgstr "Ripulisci"
 
-msgid "Autoboot from any disk/network device"
-msgstr "Avvia automaticamente da qualsiasi dispositivo di rete/disco"
+msgid "Clear & Boot Any"
+msgstr "Ripulisci e avvia tutto"
 
-msgid "Only autoboot from a specific disk/network device"
-msgstr "Avvia automaticamente solo da uno specifico dispositivo di rete/disco"
+#, fuzzy
+msgid "Boot Order:"
+msgstr "Argomenti avvio:"
+
+msgid "(None)"
+msgstr "(Nessuno)"
 
 #, c-format
 msgid "disk: %s [uuid: %s]"
@@ -152,9 +160,13 @@ msgstr "disco: %s [uuid: %s]"
 msgid "net:  %s [mac: %s]"
 msgstr "rete:  %s [mac: %s]"
 
+#, fuzzy
+msgid "Any Device"
+msgstr "Dispositivo:"
+
 #, c-format
-msgid "Unknown UUID: %s"
-msgstr "UUID sconosciuto: %s"
+msgid "Any %s device"
+msgstr "Qualsiasi dispositivo %s"
 
 msgid "Timeout:"
 msgstr "Timeout:"
@@ -162,6 +174,13 @@ msgstr "Timeout:"
 msgid "seconds"
 msgstr "secondi"
 
+#, c-format
+msgid "%s IPMI boot option: %s"
+msgstr "Opzione di avvio IPMI %s: %s"
+
+msgid "Clear option:"
+msgstr "Ripulisci opzione:"
+
 msgid "Network:"
 msgstr "Rete:"
 
@@ -204,6 +223,16 @@ msgstr "(se non fornito dal server DHCP)"
 msgid "Selecting 'OK' will exit safe mode"
 msgstr "Selezionando 'OK' si uscirà in modalità sicura"
 
+#, fuzzy
+msgid "Disk R/W:"
+msgstr "Disco"
+
+msgid "Prevent all writes to disk"
+msgstr "Impedisci tutte le scritture su disco"
+
+msgid "Allow bootloader scripts to modify disks"
+msgstr "Consenti script bootloader per modificare i dischi"
+
 msgid "Petitboot System Configuration"
 msgstr "Configurazione di sistema Petitboot"
 
@@ -476,24 +505,29 @@ msgstr ""
 "Esempio: root=/dev/sda1 console=hvc0\n"
 "\n"
 
+#, fuzzy
 msgid ""
-"Autoboot: There are three possible options for automatic-boot hehaviour:\n"
-"\n"
-"Don't autoboot: boot options will be listed in the petitboot menu, but none "
-"will be booted automatically. User interaction will be required to continue "
+"Autoboot: Specify which devices to autoboot from.\n"
+"\n"
+"By selecting the 'Add Device' button new devices can be added to the "
+"autoboot list, either by UUID, MAC address, or device type. Once added to "
+"the boot order, the priority of devices can be changed with the 'left' and "
+"'right' keys Devices can be individually removed from the boot order with "
+"the minus key. Use this option if you have multiple operating system images "
+"installed.\n"
+"\n"
+"To autoboot from any device, select the 'Clear & Boot Any' button. In this "
+"case, any boot option that is marked as a default (by bootloader "
+"configuration) will be booted automatically after a timeout. Use this option "
+"if you want to quickly boot your system without changing any boot option "
+"settings. This is the typical configuration.\n"
+"\n"
+"To disable autoboot, select the 'Clear' button, which will clear the boot "
+"order. With autoboot disabled, user interaction will be required to continue "
 "past the petitboot menu. Use this option if you want the machine to wait for "
 "an explicit boot selection, or want to interact with petitboot before "
 "booting the system\n"
 "\n"
-"Autoboot from any disk/network device: any boot option that is marked as a "
-"default (by bootloader configuration) will be booted automatically after a "
-"timeout. Use this option if you want to quickly boot your system without "
-"changing any boot option settings. This is the typical configuration.\n"
-"\n"
-"Only autoboot from a specific disk/network device: only boot options from a "
-"single device (specifed here) will be booted automatically after a timeout. "
-"Use this option if you have multiple operating system images installed.\n"
-"\n"
 "Timeout: Specify the length of time, in seconds, that the main menu will be "
 "displayed before the default boot option is started. This option is only "
 "displayed if autoboot is enabled.\n"
@@ -559,3 +593,18 @@ msgstr ""
 
 msgid "Usage"
 msgstr "Utilizzo"
+
+#~ msgid "Autoboot:"
+#~ msgstr "Autoboot:"
+
+#~ msgid "Don't autoboot"
+#~ msgstr "Don't autoboot"
+
+#~ msgid "Autoboot from any disk/network device"
+#~ msgstr "Autoboot from any disk/network device"
+
+#~ msgid "Only autoboot from a specific disk/network device"
+#~ msgstr "Only autoboot from a specific disk/network device"
+
+#~ msgid "Unknown UUID: %s"
+#~ msgstr "Unknown UUID: %s"
index c225fe8c41311cb98924f285f9ac62f73590b89b..52f635c3cf7431d17b50c5272744225f2f7467ae 100644 (file)
--- a/po/ja.po
+++ b/po/ja.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: petitboot 20140623-g89bd2ed2-dirty\n"
 "Report-Msgid-Bugs-To: Geoff Levand <geoff@infradead.org>\n"
-"POT-Creation-Date: 2014-10-13 09:24+1100\n"
+"POT-Creation-Date: 2015-08-19 14:19+1000\n"
 "PO-Revision-Date: 2014-06-24 13:56+0800\n"
 "Last-Translator: Jeremy Kerr <jk@ozlabs.org>\n"
 "Language-Team: Japanese\n"
@@ -14,7 +14,7 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
 
 msgid "running boot hooks"
 msgstr "ブート・フックを実行しています"
@@ -128,20 +128,28 @@ msgstr "システム構成"
 msgid "No IP / mask values are set"
 msgstr "IP/マスク値が設定されていません"
 
+msgid "Select a boot device to add"
+msgstr "追加するブート・デバイスの選択"
+
 msgid "Waiting for configuration data..."
 msgstr "構成データを待っています..."
 
-msgid "Autoboot:"
-msgstr "自動ブート:"
+#, fuzzy
+msgid "Add Device"
+msgstr "デバイス: "
 
-msgid "Don't autoboot"
-msgstr "自動ブートしない"
+msgid "Clear"
+msgstr "消去"
 
-msgid "Autoboot from any disk/network device"
-msgstr "任意のディスク/ネットワーク・デバイスから自動ブート"
+msgid "Clear & Boot Any"
+msgstr "消去していずれかをブート"
 
-msgid "Only autoboot from a specific disk/network device"
-msgstr "特定ディスク/ネットワークデバイスからのみ自動ブート"
+#, fuzzy
+msgid "Boot Order:"
+msgstr "ブート引数:"
+
+msgid "(None)"
+msgstr "(なし)"
 
 #, c-format
 msgid "disk: %s [uuid: %s]"
@@ -151,9 +159,13 @@ msgstr "ディスク: %s [uuid: %s]"
 msgid "net:  %s [mac: %s]"
 msgstr "net:  %s [mac: %s]"
 
+#, fuzzy
+msgid "Any Device"
+msgstr "デバイス: "
+
 #, c-format
-msgid "Unknown UUID: %s"
-msgstr "ä¸\8dæ\98\8e UUID: %s"
+msgid "Any %s device"
+msgstr "ä»»æ\84\8fã\81® %s ã\83\87ã\83\90ã\82¤ã\82¹"
 
 msgid "Timeout:"
 msgstr "タイムアウト:"
@@ -161,6 +173,13 @@ msgstr "タイムアウト:"
 msgid "seconds"
 msgstr "秒"
 
+#, c-format
+msgid "%s IPMI boot option: %s"
+msgstr "%s IPMI ブート・オプション: %s"
+
+msgid "Clear option:"
+msgstr "消去オプション:"
+
 msgid "Network:"
 msgstr "ネットワーク:"
 
@@ -203,6 +222,16 @@ msgstr "(DHCP サーバーから提供されない場合)"
 msgid "Selecting 'OK' will exit safe mode"
 msgstr "「OK」を選択するとセーフ・モードが終了します"
 
+#, fuzzy
+msgid "Disk R/W:"
+msgstr "ディスク"
+
+msgid "Prevent all writes to disk"
+msgstr "ディスクへの書き込みをすべて抑止する"
+
+msgid "Allow bootloader scripts to modify disks"
+msgstr "ブート・ローダー・スクリプトでディスクを変更できるようにする"
+
 msgid "Petitboot System Configuration"
 msgstr "Petitboot システム構成"
 
@@ -348,7 +377,7 @@ msgstr "アップ"
 
 #, fuzzy
 msgid "down"
-msgstr "ダウン"
+msgstr "ã\83ªã\83³ã\82¯ã\83\80ã\82¦ã\83³"
 
 msgid "Petitboot System Information"
 msgstr "Petitboot システム情報"
@@ -479,24 +508,29 @@ msgstr ""
 "例えば、root=/dev/sda1 console=hvc0 のように入力します。\n"
 "\n"
 
+#, fuzzy
 msgid ""
-"Autoboot: There are three possible options for automatic-boot hehaviour:\n"
-"\n"
-"Don't autoboot: boot options will be listed in the petitboot menu, but none "
-"will be booted automatically. User interaction will be required to continue "
+"Autoboot: Specify which devices to autoboot from.\n"
+"\n"
+"By selecting the 'Add Device' button new devices can be added to the "
+"autoboot list, either by UUID, MAC address, or device type. Once added to "
+"the boot order, the priority of devices can be changed with the 'left' and "
+"'right' keys Devices can be individually removed from the boot order with "
+"the minus key. Use this option if you have multiple operating system images "
+"installed.\n"
+"\n"
+"To autoboot from any device, select the 'Clear & Boot Any' button. In this "
+"case, any boot option that is marked as a default (by bootloader "
+"configuration) will be booted automatically after a timeout. Use this option "
+"if you want to quickly boot your system without changing any boot option "
+"settings. This is the typical configuration.\n"
+"\n"
+"To disable autoboot, select the 'Clear' button, which will clear the boot "
+"order. With autoboot disabled, user interaction will be required to continue "
 "past the petitboot menu. Use this option if you want the machine to wait for "
 "an explicit boot selection, or want to interact with petitboot before "
 "booting the system\n"
 "\n"
-"Autoboot from any disk/network device: any boot option that is marked as a "
-"default (by bootloader configuration) will be booted automatically after a "
-"timeout. Use this option if you want to quickly boot your system without "
-"changing any boot option settings. This is the typical configuration.\n"
-"\n"
-"Only autoboot from a specific disk/network device: only boot options from a "
-"single device (specifed here) will be booted automatically after a timeout. "
-"Use this option if you have multiple operating system images installed.\n"
-"\n"
 "Timeout: Specify the length of time, in seconds, that the main menu will be "
 "displayed before the default boot option is started. This option is only "
 "displayed if autoboot is enabled.\n"
@@ -559,3 +593,18 @@ msgstr ""
 
 msgid "Usage"
 msgstr "使用法"
+
+#~ msgid "Autoboot:"
+#~ msgstr "Autoboot:"
+
+#~ msgid "Don't autoboot"
+#~ msgstr "Don't autoboot"
+
+#~ msgid "Autoboot from any disk/network device"
+#~ msgstr "Autoboot from any disk/network device"
+
+#~ msgid "Only autoboot from a specific disk/network device"
+#~ msgstr "Only autoboot from a specific disk/network device"
+
+#~ msgid "Unknown UUID: %s"
+#~ msgstr "Unknown UUID: %s"
index 769083607bd244abaa818a325008510ad0c29a2c..9e899cf9121b1f176f06ee84da5e3b59d97106ff 100644 (file)
--- a/po/ko.po
+++ b/po/ko.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: petitboot 20140623-g89bd2ed2-dirty\n"
 "Report-Msgid-Bugs-To: Geoff Levand <geoff@infradead.org>\n"
-"POT-Creation-Date: 2014-10-13 09:24+1100\n"
+"POT-Creation-Date: 2015-08-19 14:19+1000\n"
 "PO-Revision-Date: 2014-06-24 13:56+0800\n"
 "Last-Translator: Jeremy Kerr <jk@ozlabs.org>\n"
 "Language-Team: Korean\n"
@@ -14,7 +14,7 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
 
 msgid "running boot hooks"
 msgstr "부트 후크 실행 중"
@@ -128,20 +128,28 @@ msgstr "시스템 구성"
 msgid "No IP / mask values are set"
 msgstr "IP/마스크 값이 설정되지 않음"
 
+msgid "Select a boot device to add"
+msgstr "추가할 부트 장치를 선택하십시오. "
+
 msgid "Waiting for configuration data..."
 msgstr "구성 데이터 대기 중..."
 
-msgid "Autoboot:"
-msgstr "자동 부트:"
+#, fuzzy
+msgid "Add Device"
+msgstr "장치: "
 
-msgid "Don't autoboot"
-msgstr "ì\9e\90ë\8f\99 ë¶\80í\8a¸í\95\98ì§\80 ì\95\8aì\9d\8c"
+msgid "Clear"
+msgstr "ì\84 í\83\9d ì·¨ì\86\8c"
 
-msgid "Autoboot from any disk/network device"
-msgstr "모든 디스크/네트워크 장치에서 자동 부트"
+msgid "Clear & Boot Any"
+msgstr "선택 취소 & 모든 부트"
 
-msgid "Only autoboot from a specific disk/network device"
-msgstr "특정 디스크/네트워크 장치에서만 자동 부트"
+#, fuzzy
+msgid "Boot Order:"
+msgstr "부트 인수:"
+
+msgid "(None)"
+msgstr "(없음)"
 
 #, c-format
 msgid "disk: %s [uuid: %s]"
@@ -151,9 +159,13 @@ msgstr "디스크: %s [uuid: %s]"
 msgid "net:  %s [mac: %s]"
 msgstr "네트:  %s [mac: %s]"
 
+#, fuzzy
+msgid "Any Device"
+msgstr "장치: "
+
 #, c-format
-msgid "Unknown UUID: %s"
-msgstr "알 수 없는 UUID: %s"
+msgid "Any %s device"
+msgstr "모든 %s 장치"
 
 msgid "Timeout:"
 msgstr "제한시간:"
@@ -161,6 +173,13 @@ msgstr "제한시간:"
 msgid "seconds"
 msgstr "초"
 
+#, c-format
+msgid "%s IPMI boot option: %s"
+msgstr "%s IPMI 부트 옵션: %s"
+
+msgid "Clear option:"
+msgstr "선택 취소 옵션:"
+
 msgid "Network:"
 msgstr "네트워크:"
 
@@ -203,6 +222,16 @@ msgstr "(DHCP 서버에서 제공되지 않은 경우)"
 msgid "Selecting 'OK' will exit safe mode"
 msgstr "'확인'을 선택하면 안전 모드를 종료합니다."
 
+#, fuzzy
+msgid "Disk R/W:"
+msgstr "디스크"
+
+msgid "Prevent all writes to disk"
+msgstr "디스크에 대한 모든 쓰기 방지"
+
+msgid "Allow bootloader scripts to modify disks"
+msgstr "부트 로더 스크립트가 디스크를 수정하도록 허용"
+
 msgid "Petitboot System Configuration"
 msgstr "Petitboot 시스템 구성"
 
@@ -471,24 +500,29 @@ msgstr ""
 "예: root=/dev/sda1 console=hvc0\n"
 "\n"
 
+#, fuzzy
 msgid ""
-"Autoboot: There are three possible options for automatic-boot hehaviour:\n"
-"\n"
-"Don't autoboot: boot options will be listed in the petitboot menu, but none "
-"will be booted automatically. User interaction will be required to continue "
+"Autoboot: Specify which devices to autoboot from.\n"
+"\n"
+"By selecting the 'Add Device' button new devices can be added to the "
+"autoboot list, either by UUID, MAC address, or device type. Once added to "
+"the boot order, the priority of devices can be changed with the 'left' and "
+"'right' keys Devices can be individually removed from the boot order with "
+"the minus key. Use this option if you have multiple operating system images "
+"installed.\n"
+"\n"
+"To autoboot from any device, select the 'Clear & Boot Any' button. In this "
+"case, any boot option that is marked as a default (by bootloader "
+"configuration) will be booted automatically after a timeout. Use this option "
+"if you want to quickly boot your system without changing any boot option "
+"settings. This is the typical configuration.\n"
+"\n"
+"To disable autoboot, select the 'Clear' button, which will clear the boot "
+"order. With autoboot disabled, user interaction will be required to continue "
 "past the petitboot menu. Use this option if you want the machine to wait for "
 "an explicit boot selection, or want to interact with petitboot before "
 "booting the system\n"
 "\n"
-"Autoboot from any disk/network device: any boot option that is marked as a "
-"default (by bootloader configuration) will be booted automatically after a "
-"timeout. Use this option if you want to quickly boot your system without "
-"changing any boot option settings. This is the typical configuration.\n"
-"\n"
-"Only autoboot from a specific disk/network device: only boot options from a "
-"single device (specifed here) will be booted automatically after a timeout. "
-"Use this option if you have multiple operating system images installed.\n"
-"\n"
 "Timeout: Specify the length of time, in seconds, that the main menu will be "
 "displayed before the default boot option is started. This option is only "
 "displayed if autoboot is enabled.\n"
@@ -544,3 +578,18 @@ msgstr ""
 
 msgid "Usage"
 msgstr "사용법"
+
+#~ msgid "Autoboot:"
+#~ msgstr "Autoboot:"
+
+#~ msgid "Don't autoboot"
+#~ msgstr "Don't autoboot"
+
+#~ msgid "Autoboot from any disk/network device"
+#~ msgstr "Autoboot from any disk/network device"
+
+#~ msgid "Only autoboot from a specific disk/network device"
+#~ msgstr "Only autoboot from a specific disk/network device"
+
+#~ msgid "Unknown UUID: %s"
+#~ msgstr "Unknown UUID: %s"
index 6e71d6e5c61aed88ae6b3bd9d44d0434ea563c1b..be8d0f09f3e1152ade85fa9b9ccc46f70a1e4ca8 100644 (file)
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: petitboot 20140623-g89bd2ed2-dirty\n"
 "Report-Msgid-Bugs-To: Geoff Levand <geoff@infradead.org>\n"
-"POT-Creation-Date: 2014-10-13 09:24+1100\n"
+"POT-Creation-Date: 2015-08-19 14:19+1000\n"
 "PO-Revision-Date: 2014-06-24 13:56+0800\n"
 "Last-Translator: Jeremy Kerr <jk@ozlabs.org>\n"
 "Language-Team: Portugese (Brazil)\n"
@@ -14,7 +14,7 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=2; plural=n>1;\n"
 
 msgid "running boot hooks"
 msgstr "executando ganchos de inicialização"
@@ -128,24 +128,28 @@ msgstr "Configuração do Sistema"
 msgid "No IP / mask values are set"
 msgstr "Nenhum valor de máscara/IP está configurado"
 
+msgid "Select a boot device to add"
+msgstr "Selecione um dispositivo de inicialização a incluir."
+
 msgid "Waiting for configuration data..."
 msgstr "Aguardando dados de configuração..."
 
-msgid "Autoboot:"
-msgstr "Executar a inicialização automática:"
+#, fuzzy
+msgid "Add Device"
+msgstr "Dispositivo:"
 
-msgid "Don't autoboot"
-msgstr "Não executar a inicialização automática"
+msgid "Clear"
+msgstr "Limpar"
 
-msgid "Autoboot from any disk/network device"
-msgstr ""
-"Executar a inicialização automática a partir de qualquer dispositivo de "
-"disco/rede"
+msgid "Clear & Boot Any"
+msgstr "Limpar e inicializar qualquer um"
 
-msgid "Only autoboot from a specific disk/network device"
-msgstr ""
-"Executar a inicialização automática apenas a partir de um dispositivo de "
-"disco/rede específico"
+#, fuzzy
+msgid "Boot Order:"
+msgstr "Argumentos de inicialização:"
+
+msgid "(None)"
+msgstr "(Nenhum)"
 
 #, c-format
 msgid "disk: %s [uuid: %s]"
@@ -155,9 +159,13 @@ msgstr "disco: %s [uuid: %s]"
 msgid "net:  %s [mac: %s]"
 msgstr "rede:  %s [mac: %s]"
 
+#, fuzzy
+msgid "Any Device"
+msgstr "Dispositivo:"
+
 #, c-format
-msgid "Unknown UUID: %s"
-msgstr "UUID (identificador exclusivo universal) Desconhecido: %s"
+msgid "Any %s device"
+msgstr "Qualquer dispositivo %s"
 
 msgid "Timeout:"
 msgstr "Tempo Limite:"
@@ -165,6 +173,13 @@ msgstr "Tempo Limite:"
 msgid "seconds"
 msgstr "segundos"
 
+#, c-format
+msgid "%s IPMI boot option: %s"
+msgstr "%s Opção de inicialização de IPMI: %s"
+
+msgid "Clear option:"
+msgstr "Limpar opção:"
+
 msgid "Network:"
 msgstr "Rede:"
 
@@ -210,6 +225,16 @@ msgstr "(se não for fornecido pelo servidor DHCP)"
 msgid "Selecting 'OK' will exit safe mode"
 msgstr "Selecionar 'OK' irá sair do modo de segurança"
 
+#, fuzzy
+msgid "Disk R/W:"
+msgstr "Disco"
+
+msgid "Prevent all writes to disk"
+msgstr "Evitar todas as gravações em disco"
+
+msgid "Allow bootloader scripts to modify disks"
+msgstr "Permitir que scripts de carregador de inicialização modifiquem discos"
+
 msgid "Petitboot System Configuration"
 msgstr "Configuração do Sistema Petitboot"
 
@@ -410,7 +435,7 @@ msgstr ""
 "Para configurar o idioma da interface do petitboot, digite L (idioma).\n"
 "\n"
 "Para localizar opções de inicialização novas ou atualizadas no sistema, "
-"selecione a opção 'Varrer novamentedispositivos'.\n"
+"selecione a opção 'Varrer novamente dispositivos'.\n"
 "\n"
 "Para recuperar novas opções de inicialização a partir de um arquivo de "
 "configuração remoto, selecione a opção 'Recuperar configuração a partir da "
@@ -482,24 +507,29 @@ msgstr ""
 "Exemplo: root=/dev/sda1 console=hvc0\n"
 "\n"
 
+#, fuzzy
 msgid ""
-"Autoboot: There are three possible options for automatic-boot hehaviour:\n"
-"\n"
-"Don't autoboot: boot options will be listed in the petitboot menu, but none "
-"will be booted automatically. User interaction will be required to continue "
+"Autoboot: Specify which devices to autoboot from.\n"
+"\n"
+"By selecting the 'Add Device' button new devices can be added to the "
+"autoboot list, either by UUID, MAC address, or device type. Once added to "
+"the boot order, the priority of devices can be changed with the 'left' and "
+"'right' keys Devices can be individually removed from the boot order with "
+"the minus key. Use this option if you have multiple operating system images "
+"installed.\n"
+"\n"
+"To autoboot from any device, select the 'Clear & Boot Any' button. In this "
+"case, any boot option that is marked as a default (by bootloader "
+"configuration) will be booted automatically after a timeout. Use this option "
+"if you want to quickly boot your system without changing any boot option "
+"settings. This is the typical configuration.\n"
+"\n"
+"To disable autoboot, select the 'Clear' button, which will clear the boot "
+"order. With autoboot disabled, user interaction will be required to continue "
 "past the petitboot menu. Use this option if you want the machine to wait for "
 "an explicit boot selection, or want to interact with petitboot before "
 "booting the system\n"
 "\n"
-"Autoboot from any disk/network device: any boot option that is marked as a "
-"default (by bootloader configuration) will be booted automatically after a "
-"timeout. Use this option if you want to quickly boot your system without "
-"changing any boot option settings. This is the typical configuration.\n"
-"\n"
-"Only autoboot from a specific disk/network device: only boot options from a "
-"single device (specifed here) will be booted automatically after a timeout. "
-"Use this option if you have multiple operating system images installed.\n"
-"\n"
 "Timeout: Specify the length of time, in seconds, that the main menu will be "
 "displayed before the default boot option is started. This option is only "
 "displayed if autoboot is enabled.\n"
@@ -567,3 +597,18 @@ msgstr ""
 
 msgid "Usage"
 msgstr "Uso"
+
+#~ msgid "Autoboot:"
+#~ msgstr "Autoboot:"
+
+#~ msgid "Don't autoboot"
+#~ msgstr "Don't autoboot"
+
+#~ msgid "Autoboot from any disk/network device"
+#~ msgstr "Autoboot from any disk/network device"
+
+#~ msgid "Only autoboot from a specific disk/network device"
+#~ msgstr "Only autoboot from a specific disk/network device"
+
+#~ msgid "Unknown UUID: %s"
+#~ msgstr "Unknown UUID: %s"
index f913db180997d3b2c2eb182485a391f2288a4393..bfbb5037ee379edea3667fdfdfbd0cd82a30cf49 100644 (file)
--- a/po/ru.po
+++ b/po/ru.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: petitboot 20140623-g89bd2ed2-dirty\n"
 "Report-Msgid-Bugs-To: Geoff Levand <geoff@infradead.org>\n"
-"POT-Creation-Date: 2014-10-13 09:24+1100\n"
+"POT-Creation-Date: 2015-08-19 14:19+1000\n"
 "PO-Revision-Date: 2014-06-24 13:56+0800\n"
 "Last-Translator: Jeremy Kerr <jk@ozlabs.org>\n"
 "Language-Team: Russian\n"
@@ -14,7 +14,8 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 
 msgid "running boot hooks"
 msgstr "выполнение привязок загрузки"
@@ -128,21 +129,28 @@ msgstr "Конфигурация системы"
 msgid "No IP / mask values are set"
 msgstr "Не задано значение IP / маски"
 
+msgid "Select a boot device to add"
+msgstr "Выберите загрузочное устройство для добавления"
+
 msgid "Waiting for configuration data..."
 msgstr "Ожидание данных конфигурации..."
 
-msgid "Autoboot:"
-msgstr "Автоматическая загрузка:"
+#, fuzzy
+msgid "Add Device"
+msgstr "Устройство:"
 
-msgid "Don't autoboot"
-msgstr "Ð\9dе Ð·Ð°Ð³Ñ\80Ñ\83жаÑ\82Ñ\8cÑ\81Ñ\8f Ð°Ð²Ñ\82омаÑ\82иÑ\87еÑ\81ки"
+msgid "Clear"
+msgstr "Ð\9eÑ\87иÑ\81Ñ\82иÑ\82Ñ\8c"
 
-msgid "Autoboot from any disk/network device"
-msgstr "Ð\90вÑ\82омаÑ\82иÑ\87еÑ\81ки Ð·Ð°Ð³Ñ\80Ñ\83жаÑ\82Ñ\8cÑ\81Ñ\8f Ñ\81 Ð»Ñ\8eбого Ð´Ð¸Ñ\81ка/Ñ\81еÑ\82евого Ñ\83Ñ\81Ñ\82Ñ\80ойÑ\81Ñ\82ва"
+msgid "Clear & Boot Any"
+msgstr "Ð\9eÑ\87иÑ\81Ñ\82иÑ\82Ñ\8c Ð¸ Ð·Ð°Ð³Ñ\80Ñ\83зиÑ\82Ñ\8c Ð²Ñ\81е"
 
-msgid "Only autoboot from a specific disk/network device"
-msgstr ""
-"Автоматически загружаться только с указанного диска/сетевого устройства"
+#, fuzzy
+msgid "Boot Order:"
+msgstr "Аргументы загрузки:"
+
+msgid "(None)"
+msgstr "(Нет)"
 
 #, c-format
 msgid "disk: %s [uuid: %s]"
@@ -152,9 +160,13 @@ msgstr "диск: %s [uuid: %s]"
 msgid "net:  %s [mac: %s]"
 msgstr "сеть:  %s [mac: %s]"
 
+#, fuzzy
+msgid "Any Device"
+msgstr "Устройство:"
+
 #, c-format
-msgid "Unknown UUID: %s"
-msgstr "Ð\9dеизвеÑ\81Ñ\82нÑ\8bй UUID: %s"
+msgid "Any %s device"
+msgstr "Ð\9bÑ\8eбое Ñ\83Ñ\81Ñ\82Ñ\80ойÑ\81Ñ\82во %s"
 
 msgid "Timeout:"
 msgstr "Тайм-аут:"
@@ -162,6 +174,13 @@ msgstr "Тайм-аут:"
 msgid "seconds"
 msgstr "секунд"
 
+#, c-format
+msgid "%s IPMI boot option: %s"
+msgstr "Опция загрузки IPMI %s: %s"
+
+msgid "Clear option:"
+msgstr "Опция очистки:"
+
 msgid "Network:"
 msgstr "Сеть:"
 
@@ -175,10 +194,10 @@ msgid "Static IP configuration"
 msgstr "Конфигурация статического IP"
 
 msgid "link up"
-msgstr "подклÑ\8eÑ\87иÑ\82Ñ\8cÑ\81Ñ\8f"
+msgstr "линиÑ\8f Ñ\81вÑ\8fзи Ð°ÐºÑ\82ивна"
 
 msgid "link down"
-msgstr "оÑ\82клÑ\8eÑ\87иÑ\82Ñ\8cÑ\81Ñ\8f"
+msgstr "линиÑ\8f Ñ\81вÑ\8fзи Ð½ÐµÐ°ÐºÑ\82ивна"
 
 msgid "IP/mask:"
 msgstr "IP/маска:"
@@ -204,6 +223,16 @@ msgstr "(если не предоставляется сервером DHCP)"
 msgid "Selecting 'OK' will exit safe mode"
 msgstr "После нажатия 'OK' безопасный режим будет выключен"
 
+#, fuzzy
+msgid "Disk R/W:"
+msgstr "Диск"
+
+msgid "Prevent all writes to disk"
+msgstr "Запретить любую запись на диск"
+
+msgid "Allow bootloader scripts to modify disks"
+msgstr "Разрешить сценарии загрузчика для изменения дисков"
+
 msgid "Petitboot System Configuration"
 msgstr "Конфигурация Petitboot System"
 
@@ -328,7 +357,7 @@ msgstr " UUID:       %s"
 
 #, c-format
 msgid " mounted at: %s"
-msgstr " Ñ\83Ñ\81Ñ\82ановлено Ð²: %s"
+msgstr " Ñ\82оÑ\87ка Ð¼Ð¾Ð½Ñ\82иÑ\80ованиÑ\8f: %s"
 
 msgid "Network interfaces"
 msgstr "Сетевые интерфейсы"
@@ -341,14 +370,14 @@ msgstr " MAC:  %s"
 #. * link status for a network connection.
 #, c-format
 msgid " link: %s"
-msgstr " связь: %s"
+msgstr " линия связи: %s"
 
 msgid "up"
-msgstr "вкл"
+msgstr "акÑ\82ивна"
 
 #, fuzzy
 msgid "down"
-msgstr "вÑ\8bкл"
+msgstr "неакÑ\82ивна"
 
 msgid "Petitboot System Information"
 msgstr "Информация о системе Petitboot"
@@ -473,24 +502,29 @@ msgstr ""
 "Пример: root=/dev/sda1 console=hvc0\n"
 "\n"
 
+#, fuzzy
 msgid ""
-"Autoboot: There are three possible options for automatic-boot hehaviour:\n"
-"\n"
-"Don't autoboot: boot options will be listed in the petitboot menu, but none "
-"will be booted automatically. User interaction will be required to continue "
+"Autoboot: Specify which devices to autoboot from.\n"
+"\n"
+"By selecting the 'Add Device' button new devices can be added to the "
+"autoboot list, either by UUID, MAC address, or device type. Once added to "
+"the boot order, the priority of devices can be changed with the 'left' and "
+"'right' keys Devices can be individually removed from the boot order with "
+"the minus key. Use this option if you have multiple operating system images "
+"installed.\n"
+"\n"
+"To autoboot from any device, select the 'Clear & Boot Any' button. In this "
+"case, any boot option that is marked as a default (by bootloader "
+"configuration) will be booted automatically after a timeout. Use this option "
+"if you want to quickly boot your system without changing any boot option "
+"settings. This is the typical configuration.\n"
+"\n"
+"To disable autoboot, select the 'Clear' button, which will clear the boot "
+"order. With autoboot disabled, user interaction will be required to continue "
 "past the petitboot menu. Use this option if you want the machine to wait for "
 "an explicit boot selection, or want to interact with petitboot before "
 "booting the system\n"
 "\n"
-"Autoboot from any disk/network device: any boot option that is marked as a "
-"default (by bootloader configuration) will be booted automatically after a "
-"timeout. Use this option if you want to quickly boot your system without "
-"changing any boot option settings. This is the typical configuration.\n"
-"\n"
-"Only autoboot from a specific disk/network device: only boot options from a "
-"single device (specifed here) will be booted automatically after a timeout. "
-"Use this option if you have multiple operating system images installed.\n"
-"\n"
 "Timeout: Specify the length of time, in seconds, that the main menu will be "
 "displayed before the default boot option is started. This option is only "
 "displayed if autoboot is enabled.\n"
@@ -520,7 +554,7 @@ msgstr ""
 "или если хотите поработать с petitboot до загрузки системы\n"
 "\n"
 "Автозагрузка с любого диска/сетевого устройства: любой вариант загрузки с "
-"оÑ\82меÑ\82кой Ð¿Ð¾ Ñ\83молÑ\87аниÑ\8e (задаеÑ\82Ñ\81Ñ\8f Ð² Ð½Ð°Ñ\81Ñ\82Ñ\80ойкаÑ\85 bootloader) будет автоматически "
+"оÑ\82меÑ\82кой Ð¿Ð¾ Ñ\83молÑ\87аниÑ\8e (в ÐºÐ¾Ð½Ñ\84игÑ\83Ñ\80аÑ\86ии Ð·Ð°Ð³Ñ\80Ñ\83зÑ\87ика) будет автоматически "
 "загружен после тайм-аута. Используйте этот вариант в том случае, если хотите "
 "быстро загрузить систему без изменения каких-либо настроек варианта "
 "загрузки. Является стандартной конфигурацией.\n"
@@ -552,3 +586,18 @@ msgstr ""
 
 msgid "Usage"
 msgstr "Использование"
+
+#~ msgid "Autoboot:"
+#~ msgstr "Autoboot:"
+
+#~ msgid "Don't autoboot"
+#~ msgstr "Don't autoboot"
+
+#~ msgid "Autoboot from any disk/network device"
+#~ msgstr "Autoboot from any disk/network device"
+
+#~ msgid "Only autoboot from a specific disk/network device"
+#~ msgstr "Only autoboot from a specific disk/network device"
+
+#~ msgid "Unknown UUID: %s"
+#~ msgstr "Unknown UUID: %s"
index 62976b08768f577ae69ebb551afca55b3829aeb1..1ba5e9508c1b33242ee001f0d8244a114517bf8f 100644 (file)
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: petitboot 20140623-g89bd2ed2-dirty\n"
 "Report-Msgid-Bugs-To: Geoff Levand <geoff@infradead.org>\n"
-"POT-Creation-Date: 2014-10-13 09:24+1100\n"
+"POT-Creation-Date: 2015-08-19 14:19+1000\n"
 "PO-Revision-Date: 2014-06-24 13:56+0800\n"
 "Last-Translator: Jeremy Kerr <jk@ozlabs.org>\n"
 "Language-Team: Simplified Chinese\n"
@@ -128,20 +128,28 @@ msgstr "系统配置"
 msgid "No IP / mask values are set"
 msgstr "未设置任何 IP/掩码值"
 
+msgid "Select a boot device to add"
+msgstr "选择要添加的引导设备"
+
 msgid "Waiting for configuration data..."
 msgstr "正在等待配置数据..."
 
-msgid "Autoboot:"
-msgstr "自动引导:"
+#, fuzzy
+msgid "Add Device"
+msgstr "设备:"
 
-msgid "Don't autoboot"
-msgstr "不自动引导"
+msgid "Clear"
+msgstr "清除"
 
-msgid "Autoboot from any disk/network device"
-msgstr "从任何磁盘/网络设备自动引导"
+msgid "Clear & Boot Any"
+msgstr "清除并引导任何项"
 
-msgid "Only autoboot from a specific disk/network device"
-msgstr "仅从特定磁盘/网络设备自动引导"
+#, fuzzy
+msgid "Boot Order:"
+msgstr "引导参数:"
+
+msgid "(None)"
+msgstr "(无)"
 
 #, c-format
 msgid "disk: %s [uuid: %s]"
@@ -151,9 +159,13 @@ msgstr "磁盘:%s [uuid:%s]"
 msgid "net:  %s [mac: %s]"
 msgstr "网路:%s [mac:%s]"
 
+#, fuzzy
+msgid "Any Device"
+msgstr "设备:"
+
 #, c-format
-msgid "Unknown UUID: %s"
-msgstr "未知 UUID:%s"
+msgid "Any %s device"
+msgstr "任何 %s 设备"
 
 msgid "Timeout:"
 msgstr "超时:"
@@ -161,6 +173,13 @@ msgstr "超时:"
 msgid "seconds"
 msgstr "秒"
 
+#, c-format
+msgid "%s IPMI boot option: %s"
+msgstr "%s IPMI 引导选项:%s"
+
+msgid "Clear option:"
+msgstr "清除选项:"
+
 msgid "Network:"
 msgstr "网络:"
 
@@ -203,6 +222,16 @@ msgstr "(如果不是由 DHCP 服务器提供)"
 msgid "Selecting 'OK' will exit safe mode"
 msgstr "选择“确定”将退出安全模式"
 
+#, fuzzy
+msgid "Disk R/W:"
+msgstr "磁盘"
+
+msgid "Prevent all writes to disk"
+msgstr "阻止对磁盘的所有写入操作"
+
+msgid "Allow bootloader scripts to modify disks"
+msgstr "允许引导程序脚本修改磁盘"
+
 msgid "Petitboot System Configuration"
 msgstr "Petitboot 系统配置"
 
@@ -295,7 +324,7 @@ msgstr "选择 Petitboot 语言"
 
 #, c-format
 msgid "!Invalid option %d"
-msgstr "!无效的选项 %d"
+msgstr "!无效选项 %d"
 
 msgid "Disk"
 msgstr "磁盘"
@@ -462,24 +491,29 @@ msgstr ""
 "示例:root=/dev/sda1 console=hvc0\n"
 "\n"
 
+#, fuzzy
 msgid ""
-"Autoboot: There are three possible options for automatic-boot hehaviour:\n"
-"\n"
-"Don't autoboot: boot options will be listed in the petitboot menu, but none "
-"will be booted automatically. User interaction will be required to continue "
+"Autoboot: Specify which devices to autoboot from.\n"
+"\n"
+"By selecting the 'Add Device' button new devices can be added to the "
+"autoboot list, either by UUID, MAC address, or device type. Once added to "
+"the boot order, the priority of devices can be changed with the 'left' and "
+"'right' keys Devices can be individually removed from the boot order with "
+"the minus key. Use this option if you have multiple operating system images "
+"installed.\n"
+"\n"
+"To autoboot from any device, select the 'Clear & Boot Any' button. In this "
+"case, any boot option that is marked as a default (by bootloader "
+"configuration) will be booted automatically after a timeout. Use this option "
+"if you want to quickly boot your system without changing any boot option "
+"settings. This is the typical configuration.\n"
+"\n"
+"To disable autoboot, select the 'Clear' button, which will clear the boot "
+"order. With autoboot disabled, user interaction will be required to continue "
 "past the petitboot menu. Use this option if you want the machine to wait for "
 "an explicit boot selection, or want to interact with petitboot before "
 "booting the system\n"
 "\n"
-"Autoboot from any disk/network device: any boot option that is marked as a "
-"default (by bootloader configuration) will be booted automatically after a "
-"timeout. Use this option if you want to quickly boot your system without "
-"changing any boot option settings. This is the typical configuration.\n"
-"\n"
-"Only autoboot from a specific disk/network device: only boot options from a "
-"single device (specifed here) will be booted automatically after a timeout. "
-"Use this option if you have multiple operating system images installed.\n"
-"\n"
 "Timeout: Specify the length of time, in seconds, that the main menu will be "
 "displayed before the default boot option is started. This option is only "
 "displayed if autoboot is enabled.\n"
@@ -518,8 +552,8 @@ msgstr ""
 "\n"
 "网络选项:\n"
 "\n"
-"æ\89\80æ\9c\89æ´»å\8a¨æ\8e¥å\8f£ä¸\8aç\9a\84 DHCPï¼\9aè\87ªå\8a¨å°\86 IP å\9c°å\9d\80å\88\86é\85\8dç»\99æ¯\8f个ç½\91ç»\9cæ\8e¥å\8f£ã\80\82å¦\82æ\9e\9cæ\82¨ç\9a\84ç½\91ç»\9cä¸\8aæ\9c\89 "
-"DHCP 服务器,请使用 此选项。\n"
+"æ\89\80æ\9c\89æ´»å\8a¨æ\8e¥å\8f£ä¸\8aç\9a\84 DHCPï¼\9aè\87ªå\8a¨å°\86 IP å\9c°å\9d\80å\88\86é\85\8dç»\99æ¯\8f个ç½\91ç»\9cæ\8e¥å\8f£ã\80\82å¦\82æ\9e\9cæ\82¨ç\9a\84ç½\91ç»\9c中å­\98å\9c¨ "
+"DHCP 服务器,请使用此选项。\n"
 "\n"
 "特定接口上的 DHCP:自动将 IP 地址分配给选择的网络接口。不配置其他接口。如果您"
 "在不同的接口上有多个 DHCP 服务器,但在引导期间只想配置单个接口,请选择此选"
@@ -530,3 +564,18 @@ msgstr ""
 
 msgid "Usage"
 msgstr "用法"
+
+#~ msgid "Autoboot:"
+#~ msgstr "Autoboot:"
+
+#~ msgid "Don't autoboot"
+#~ msgstr "Don't autoboot"
+
+#~ msgid "Autoboot from any disk/network device"
+#~ msgstr "Autoboot from any disk/network device"
+
+#~ msgid "Only autoboot from a specific disk/network device"
+#~ msgstr "Only autoboot from a specific disk/network device"
+
+#~ msgid "Unknown UUID: %s"
+#~ msgstr "Unknown UUID: %s"
index 657062f0ebac6b775ed291618b7277f9672def3c..d25038ef5f116815938a45a0fa86f3fe6d91d930 100644 (file)
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: petitboot 20140623-g89bd2ed2-dirty\n"
 "Report-Msgid-Bugs-To: Geoff Levand <geoff@infradead.org>\n"
-"POT-Creation-Date: 2014-10-13 09:24+1100\n"
+"POT-Creation-Date: 2015-08-19 14:19+1000\n"
 "PO-Revision-Date: 2014-06-24 13:56+0800\n"
 "Last-Translator: Jeremy Kerr <jk@ozlabs.org>\n"
 "Language-Team: Traditional Chinese\n"
@@ -128,20 +128,28 @@ msgstr "系統配置"
 msgid "No IP / mask values are set"
 msgstr "未設定任何 IP/遮罩值"
 
+msgid "Select a boot device to add"
+msgstr "選取要新增的啟動裝置"
+
 msgid "Waiting for configuration data..."
 msgstr "正在等待配置資料..."
 
-msgid "Autoboot:"
-msgstr "自動啟動:"
+#, fuzzy
+msgid "Add Device"
+msgstr "裝置:"
 
-msgid "Don't autoboot"
-msgstr "不自動啟動"
+msgid "Clear"
+msgstr "清除"
 
-msgid "Autoboot from any disk/network device"
-msgstr "從任何磁碟/網路裝置自動啟動"
+msgid "Clear & Boot Any"
+msgstr "清除並啟動任意項"
 
-msgid "Only autoboot from a specific disk/network device"
-msgstr "僅從特定的磁碟/網路裝置自動啟動"
+#, fuzzy
+msgid "Boot Order:"
+msgstr "啟動引數:"
+
+msgid "(None)"
+msgstr "(無)"
 
 #, c-format
 msgid "disk: %s [uuid: %s]"
@@ -151,9 +159,13 @@ msgstr "磁碟:%s [UUID:%s]"
 msgid "net:  %s [mac: %s]"
 msgstr "網路:%s [MAC:%s]"
 
+#, fuzzy
+msgid "Any Device"
+msgstr "裝置:"
+
 #, c-format
-msgid "Unknown UUID: %s"
-msgstr "ä¸\8dæ\98\8e UUIDï¼\9a%s"
+msgid "Any %s device"
+msgstr "ä»»ä½\95 %s è£\9dç½®"
 
 msgid "Timeout:"
 msgstr "逾時:"
@@ -161,6 +173,13 @@ msgstr "逾時:"
 msgid "seconds"
 msgstr "秒"
 
+#, c-format
+msgid "%s IPMI boot option: %s"
+msgstr "%s IPMI 啟動選項:%s"
+
+msgid "Clear option:"
+msgstr "清除選項:"
+
 msgid "Network:"
 msgstr "網路:"
 
@@ -203,6 +222,16 @@ msgstr "(如果 DHCP 伺服器未提供的話)"
 msgid "Selecting 'OK' will exit safe mode"
 msgstr "選取「確定」將會結束安全模式"
 
+#, fuzzy
+msgid "Disk R/W:"
+msgstr "磁碟"
+
+msgid "Prevent all writes to disk"
+msgstr "阻止全部寫入磁碟"
+
+msgid "Allow bootloader scripts to modify disks"
+msgstr "容許開機載入器 Script 修改磁碟"
+
 msgid "Petitboot System Configuration"
 msgstr "Petitboot 系統配置"
 
@@ -295,7 +324,7 @@ msgstr "選取 Petitboot 語言"
 
 #, c-format
 msgid "!Invalid option %d"
-msgstr "選項 %d 無效!"
+msgstr "!無效選項 %d"
 
 msgid "Disk"
 msgstr "磁碟"
@@ -465,24 +494,29 @@ msgstr ""
 "範例:root=/dev/sda1 console=hvc0\n"
 "\n"
 
+#, fuzzy
 msgid ""
-"Autoboot: There are three possible options for automatic-boot hehaviour:\n"
-"\n"
-"Don't autoboot: boot options will be listed in the petitboot menu, but none "
-"will be booted automatically. User interaction will be required to continue "
+"Autoboot: Specify which devices to autoboot from.\n"
+"\n"
+"By selecting the 'Add Device' button new devices can be added to the "
+"autoboot list, either by UUID, MAC address, or device type. Once added to "
+"the boot order, the priority of devices can be changed with the 'left' and "
+"'right' keys Devices can be individually removed from the boot order with "
+"the minus key. Use this option if you have multiple operating system images "
+"installed.\n"
+"\n"
+"To autoboot from any device, select the 'Clear & Boot Any' button. In this "
+"case, any boot option that is marked as a default (by bootloader "
+"configuration) will be booted automatically after a timeout. Use this option "
+"if you want to quickly boot your system without changing any boot option "
+"settings. This is the typical configuration.\n"
+"\n"
+"To disable autoboot, select the 'Clear' button, which will clear the boot "
+"order. With autoboot disabled, user interaction will be required to continue "
 "past the petitboot menu. Use this option if you want the machine to wait for "
 "an explicit boot selection, or want to interact with petitboot before "
 "booting the system\n"
 "\n"
-"Autoboot from any disk/network device: any boot option that is marked as a "
-"default (by bootloader configuration) will be booted automatically after a "
-"timeout. Use this option if you want to quickly boot your system without "
-"changing any boot option settings. This is the typical configuration.\n"
-"\n"
-"Only autoboot from a specific disk/network device: only boot options from a "
-"single device (specifed here) will be booted automatically after a timeout. "
-"Use this option if you have multiple operating system images installed.\n"
-"\n"
 "Timeout: Specify the length of time, in seconds, that the main menu will be "
 "displayed before the default boot option is started. This option is only "
 "displayed if autoboot is enabled.\n"
@@ -522,7 +556,7 @@ msgstr ""
 "網路選項:\n"
 "\n"
 "對所有作用中介面使用 DHCP:自動將 IP 位址指派給每一個網路介面。如果您的網路中"
-"有 DHCP 伺服器請使用此選項。\n"
+"有 DHCP 伺服器請使用此選項。\n"
 "\n"
 "對特定介面使用 DHCP:自動將 IP 位址指派給選定的網路介面。不配置其他介面。如果"
 "您在不同的介面上具有多個 DHCP 伺服器,但在啟動期間只想配置單一介面,請選取此"
@@ -533,3 +567,18 @@ msgstr ""
 
 msgid "Usage"
 msgstr "用法"
+
+#~ msgid "Autoboot:"
+#~ msgstr "Autoboot:"
+
+#~ msgid "Don't autoboot"
+#~ msgstr "Don't autoboot"
+
+#~ msgid "Autoboot from any disk/network device"
+#~ msgstr "Autoboot from any disk/network device"
+
+#~ msgid "Only autoboot from a specific disk/network device"
+#~ msgstr "Only autoboot from a specific disk/network device"
+
+#~ msgid "Unknown UUID: %s"
+#~ msgstr "Unknown UUID: %s"
index cf55b03a104df725fcb9c2207c816cda87df1b5a..451b05014cc2a752659fe43fce6a619d79bfac2c 100644 (file)
@@ -194,9 +194,9 @@ static void add_url_screen_layout_widgets(struct add_url_screen *screen)
        widget_move(widget_button_base(screen->widgets.ok_b),
                y, screen->field_x);
        widget_move(widget_button_base(screen->widgets.help_b),
-               y, screen->field_x + 10);
+               y, screen->field_x + 14);
        widget_move(widget_button_base(screen->widgets.cancel_b),
-               y, screen->field_x + 24);
+               y, screen->field_x + 28);
 }
 
 static void add_url_screen_setup_widgets(struct add_url_screen *screen)
@@ -210,7 +210,7 @@ static void add_url_screen_setup_widgets(struct add_url_screen *screen)
                        _("Configuration URL:"));
        screen->widgets.url_f = widget_new_textbox(set, 0, 0, 50, NULL);
 
-       screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, _("OK"),
+       screen->widgets.ok_b = widget_new_button(set, 0, 0, 10, _("OK"),
                        ok_click, screen);
        screen->widgets.help_b = widget_new_button(set, 0, 0, 10, _("Help"),
                        help_click, screen);
index 274bd9d2fa1b4df079eb050c10524bc46abad5b1..4012ec5a7658dfdc8f429e00130307ed7692ec44 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <assert.h>
 #include <string.h>
-#include <stdlib.h>
 
 #include "log/log.h"
 #include "talloc/talloc.h"
@@ -45,6 +44,7 @@ struct boot_editor {
                                        struct pmenu_item *item,
                                        struct pb_boot_data *bd);
        bool                    need_redraw;
+       bool                    need_update;
 
        int                     label_x;
        int                     field_x;
@@ -110,7 +110,14 @@ static struct boot_editor *boot_editor_from_arg(void *arg)
 static int boot_editor_post(struct nc_scr *scr)
 {
        struct boot_editor *boot_editor = boot_editor_from_scr(scr);
-       widgetset_post(boot_editor->widgetset);
+
+       if (boot_editor->need_update) {
+               boot_editor_update(boot_editor, boot_editor->cui->sysinfo);
+               boot_editor->need_update = false;
+       } else {
+               widgetset_post(boot_editor->widgetset);
+       }
+
        nc_scr_frame_draw(scr);
        if (boot_editor->need_redraw) {
                redrawwin(scr->main_ncw);
@@ -318,9 +325,12 @@ static void boot_editor_layout_widgets(struct boot_editor *boot_editor)
 
 
        y++;
-       widget_move(widget_button_base(boot_editor->widgets.ok_b), y, 9);
-       widget_move(widget_button_base(boot_editor->widgets.help_b), y, 19);
-       widget_move(widget_button_base(boot_editor->widgets.cancel_b), y, 33);
+       widget_move(widget_button_base(boot_editor->widgets.ok_b), y,
+                   boot_editor->field_x);
+       widget_move(widget_button_base(boot_editor->widgets.help_b), y,
+                   boot_editor->field_x + 14);
+       widget_move(widget_button_base(boot_editor->widgets.cancel_b), y,
+                   boot_editor->field_x + 28);
 }
 
 static void boot_editor_widget_focus(struct nc_widget *widget, void *arg)
@@ -491,7 +501,7 @@ static void boot_editor_setup_widgets(struct boot_editor *boot_editor,
        boot_editor->widgets.args_f = widget_new_textbox(set, 0, 0,
                                        field_size, boot_editor->args);
 
-       boot_editor->widgets.ok_b = widget_new_button(set, 0, 0, 6,
+       boot_editor->widgets.ok_b = widget_new_button(set, 0, 0, 10,
                                        _("OK"), ok_click, boot_editor);
        boot_editor->widgets.help_b = widget_new_button(set, 0, 0, 10,
                                        _("Help"), help_click, boot_editor);
@@ -504,6 +514,11 @@ void boot_editor_update(struct boot_editor *boot_editor,
 {
        int height;
 
+       if (boot_editor->cui->current != boot_editor_scr(boot_editor)) {
+               boot_editor->need_update = true;
+               return;
+       }
+
        widgetset_unpost(boot_editor->widgetset);
 
        height = pad_height(sysinfo ? sysinfo->n_blockdevs : 0);
@@ -524,36 +539,6 @@ void boot_editor_update(struct boot_editor *boot_editor,
        pad_refresh(boot_editor);
 }
 
-/* Return the number of columns required to display a localised string */
-static int strncols(const char *str)
-{
-       int i, wlen, ncols = 0;
-       wchar_t *wstr;
-
-       wlen = mbstowcs(NULL, str, 0);
-       if (wlen <= 0)
-               return wlen;
-
-       wstr = malloc(sizeof(wchar_t) * wlen + 1);
-       if (!wstr)
-               return -1;
-
-       wlen = mbstowcs(wstr, str, wlen);
-       if (wlen <= 0) {
-               free(wstr);
-               return wlen;
-       }
-
-       /* Processing each character individually lets us use the same
-        * check for all languages */
-       for (i = 0; i < wlen; i++) {
-               ncols += wcwidth(wstr[i]);
-       }
-
-       free(wstr);
-       return ncols;
-}
-
 struct boot_editor *boot_editor_init(struct cui *cui,
                struct pmenu_item *item,
                const struct system_info *sysinfo,
@@ -574,6 +559,7 @@ struct boot_editor *boot_editor_init(struct cui *cui,
        boot_editor->on_exit = on_exit;
        boot_editor->state = STATE_EDIT;
        boot_editor->need_redraw = false;
+       boot_editor->need_update = false;
 
        int ncols1 = strncols(_("Device tree:"));
        int ncols2 = strncols(_("Boot arguments:"));
index 22ced3c3d2b85107416383e65b23fbf08c7fbca2..23bcd9d8bc8ed24cb53c9c9311513a56db23dd81 100644 (file)
@@ -40,4 +40,8 @@ only want to configure a single interface during boot.\n"
 "Static IP configuration: Allows you to specify an IPv4 address and network \
 mask, gateway, and a DNS server or servers for a network interface. Select \
 this option if you do not have a DHCP server, or want explicit control of \
-network settings.");
+network settings.\n"
+"\n"
+"Disk R/W: Certain bootloader configurations may request write access to \
+disks to save information or update parameters (eg. GRUB2). "
+"Use this option to control access to disks.\n");
index 76ede39905755b5cc9d747a5bc673e1a4ce02b8b..64fb4c792139d71dc0891dda330752b2427dc272 100644 (file)
@@ -33,7 +33,7 @@
 #include "nc-config.h"
 #include "nc-widgets.h"
 
-#define N_FIELDS       32
+#define N_FIELDS       34
 
 extern struct help_text config_help_text;
 
@@ -53,6 +53,7 @@ struct config_screen {
        bool                    show_help;
        bool                    show_subset;
        bool                    need_redraw;
+       bool                    need_update;
 
        void                    (*on_exit)(struct cui *);
 
@@ -100,6 +101,9 @@ struct config_screen {
                struct nc_widget_label          *dns_dhcp_help_l;
                struct nc_widget_label          *dns_help_l;
 
+               struct nc_widget_label          *allow_write_l;
+               struct nc_widget_select         *allow_write_f;
+
                struct nc_widget_label          *safe_mode;
                struct nc_widget_button         *ok_b;
                struct nc_widget_button         *help_b;
@@ -167,21 +171,6 @@ static void config_screen_resize(struct nc_scr *scr)
        (void)screen;
 }
 
-static int config_screen_post(struct nc_scr *scr)
-{
-       struct config_screen *screen = config_screen_from_scr(scr);
-       screen->show_subset = false;
-       widgetset_post(screen->widgetset);
-       nc_scr_frame_draw(scr);
-       if (screen->need_redraw) {
-               redrawwin(scr->main_ncw);
-               screen->need_redraw = false;
-       }
-       wrefresh(screen->scr.main_ncw);
-       pad_refresh(screen);
-       return 0;
-}
-
 static int config_screen_unpost(struct nc_scr *scr)
 {
        struct config_screen *screen = config_screen_from_scr(scr);
@@ -203,6 +192,7 @@ static int screen_process_form(struct config_screen *screen)
        struct config *config;
        int i, n_boot_opts, rc, idx;
        unsigned int *order;
+       bool allow_write;
        char mac[20];
 
        config = config_copy(screen, screen->cui->config);
@@ -331,6 +321,10 @@ static int screen_process_form(struct config_screen *screen)
                }
        }
 
+       allow_write = widget_select_get_value(screen->widgets.allow_write_f);
+       if (allow_write != config->allow_writes)
+               config->allow_writes = allow_write;
+
        config->safe_mode = false;
        rc = cui_send_config(screen->cui, config);
        talloc_free(config);
@@ -410,11 +404,11 @@ static void config_screen_layout_widgets(struct config_screen *screen)
        y += 1;
 
        widget_move(widget_button_base(screen->widgets.boot_add_b),
-                       y, screen->field_x);
+                       y++, screen->field_x);
        widget_move(widget_button_base(screen->widgets.boot_any_b),
-                       y, screen->field_x + 14);
+                       y++, screen->field_x);
        widget_move(widget_button_base(screen->widgets.boot_none_b),
-                       y, screen->field_x + 34);
+                       y, screen->field_x);
 
        wf = widget_button_base(screen->widgets.boot_add_b);
        if (widget_subset_n_inactive(screen->widgets.boot_order_f))
@@ -540,12 +534,18 @@ static void config_screen_layout_widgets(struct config_screen *screen)
                y += 1;
        }
 
+       layout_pair(screen, y, screen->widgets.allow_write_l,
+                   widget_select_base(screen->widgets.allow_write_f));
+       y += widget_height(widget_select_base(screen->widgets.allow_write_f));
+
+       y += 1;
+
        widget_move(widget_button_base(screen->widgets.ok_b),
                        y, screen->field_x);
        widget_move(widget_button_base(screen->widgets.help_b),
-                       y, screen->field_x + 10);
+                       y, screen->field_x + 14);
        widget_move(widget_button_base(screen->widgets.cancel_b),
-                       y, screen->field_x + 24);
+                       y, screen->field_x + 28);
 }
 
 static void config_screen_network_change(void *arg, int value)
@@ -696,6 +696,7 @@ static void config_screen_setup_widgets(struct config_screen *screen,
        char *str, *ip, *mask, *gw;
        enum net_conf_type type;
        unsigned int i;
+       int add_len, clear_len, any_len, min_len = 20;
 
        build_assert(sizeof(screen->widgets) / sizeof(struct widget *)
                        == N_FIELDS);
@@ -703,15 +704,19 @@ static void config_screen_setup_widgets(struct config_screen *screen,
        type = screen->net_conf_type;
        ifcfg = first_active_interface(config);
 
-       screen->widgets.boot_add_b = widget_new_button(set, 0, 0, 10,
+       add_len = max(min_len, strncols(_("Add Device")));
+       clear_len = max(min_len, strncols(_("Clear")));
+       any_len = max(min_len, strncols(_("Clear & Boot Any")));
+
+       screen->widgets.boot_add_b = widget_new_button(set, 0, 0, add_len,
                                        _("Add Device"),
                                        config_screen_add_device, screen);
 
-       screen->widgets.boot_none_b = widget_new_button(set, 0, 0, 10,
+       screen->widgets.boot_none_b = widget_new_button(set, 0, 0, clear_len,
                                        _("Clear"),
                                        config_screen_autoboot_none, screen);
 
-       screen->widgets.boot_any_b = widget_new_button(set, 0, 0, 16,
+       screen->widgets.boot_any_b = widget_new_button(set, 0, 0, any_len,
                                        _("Clear & Boot Any"),
                                        config_screen_autoboot_any, screen);
 
@@ -748,7 +753,7 @@ static void config_screen_setup_widgets(struct config_screen *screen,
                widget_subset_add_option(screen->widgets.boot_order_f, label);
        }
 
-       for (i = DEVICE_TYPE_NETWORK; i < DEVICE_TYPE_NETWORK + 4; i++) {
+       for (i = DEVICE_TYPE_NETWORK; i < DEVICE_TYPE_UNKNOWN; i++) {
                char *label;
 
                if (i == DEVICE_TYPE_ANY)
@@ -806,7 +811,8 @@ static void config_screen_setup_widgets(struct config_screen *screen,
        }
 
        screen->widgets.network_l = widget_new_label(set, 0, 0, _("Network:"));
-       screen->widgets.network_f = widget_new_select(set, 0, 0, 50);
+       screen->widgets.network_f = widget_new_select(set, 0, 0,
+                                               COLS - screen->field_x - 1);
 
        widget_select_add_option(screen->widgets.network_f,
                                        NET_CONF_TYPE_DHCP_ALL,
@@ -900,7 +906,20 @@ static void config_screen_setup_widgets(struct config_screen *screen,
                screen->widgets.safe_mode = widget_new_label(set, 0, 0,
                         _("Selecting 'OK' will exit safe mode"));
 
-       screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, _("OK"),
+       screen->widgets.allow_write_l = widget_new_label(set, 0, 0,
+                       _("Disk R/W:"));
+       screen->widgets.allow_write_f = widget_new_select(set, 0, 0,
+                                               COLS - screen->field_x - 1);
+
+       widget_select_add_option(screen->widgets.allow_write_f, 0,
+                               _("Prevent all writes to disk"),
+                               !config->allow_writes);
+
+       widget_select_add_option(screen->widgets.allow_write_f, 1,
+                               _("Allow bootloader scripts to modify disks"),
+                               config->allow_writes);
+
+       screen->widgets.ok_b = widget_new_button(set, 0, 0, 10, _("OK"),
                        ok_click, screen);
        screen->widgets.help_b = widget_new_button(set, 0, 0, 10, _("Help"),
                        help_click, screen);
@@ -911,18 +930,22 @@ static void config_screen_setup_widgets(struct config_screen *screen,
 static void config_screen_widget_focus(struct nc_widget *widget, void *arg)
 {
        struct config_screen *screen = arg;
-       int w_y, s_max;
+       int w_y, w_height, w_focus, s_max, adjust;
 
-       w_y = widget_y(widget) + widget_focus_y(widget);
+       w_height = widget_height(widget);
+       w_focus = widget_focus_y(widget);
+       w_y = widget_y(widget) + w_focus;
        s_max = getmaxy(screen->scr.sub_ncw) - 1;
 
        if (w_y < screen->scroll_y)
                screen->scroll_y = w_y;
 
-       else if (w_y + screen->scroll_y + 1 > s_max)
-               screen->scroll_y = 1 + w_y - s_max;
-
-       else
+       else if (w_y + screen->scroll_y + 1 > s_max) {
+               /* Fit as much of the widget into the screen as possible */
+               adjust = min(s_max - 1, w_height - w_focus);
+               if (w_y + adjust >= screen->scroll_y + s_max)
+                       screen->scroll_y = max(0, 1 + w_y + adjust - s_max);
+       } else
                return;
 
        pad_refresh(screen);
@@ -983,10 +1006,38 @@ void config_screen_update(struct config_screen *screen,
                const struct config *config,
                const struct system_info *sysinfo)
 {
+       if (screen->cui->current != config_screen_scr(screen)) {
+               screen->need_update = true;
+               return;
+       }
+
        config_screen_draw(screen, config, sysinfo);
        pad_refresh(screen);
 }
 
+static int config_screen_post(struct nc_scr *scr)
+{
+       struct config_screen *screen = config_screen_from_scr(scr);
+       screen->show_subset = false;
+
+       if (screen->need_update) {
+               config_screen_draw(screen, screen->cui->config,
+                                  screen->cui->sysinfo);
+               screen->need_update = false;
+       } else {
+               widgetset_post(screen->widgetset);
+       }
+
+       nc_scr_frame_draw(scr);
+       if (screen->need_redraw) {
+               redrawwin(scr->main_ncw);
+               screen->need_redraw = false;
+       }
+       wrefresh(screen->scr.main_ncw);
+       pad_refresh(screen);
+       return 0;
+}
+
 static int config_screen_destroy(void *arg)
 {
        struct config_screen *screen = arg;
@@ -1012,6 +1063,7 @@ struct config_screen *config_screen_init(struct cui *cui,
        screen->cui = cui;
        screen->on_exit = on_exit;
        screen->need_redraw = false;
+       screen->need_update = false;
        screen->label_x = 2;
        screen->field_x = 17;
 
index 56e7653af112c67e8f0afc67c6fc45b4d6cb794e..c975c0f126e0095bc0f65db3b29d2dadd65835e0 100644 (file)
@@ -698,6 +698,9 @@ static void cui_update_sysinfo(struct system_info *sysinfo, void *arg)
        if (cui->sysinfo_screen)
                sysinfo_screen_update(cui->sysinfo_screen, sysinfo);
 
+       if (cui->subset_screen)
+               subset_screen_update(cui->subset_screen);
+
        /* ... and do the same with the config screen... */
        if (cui->config_screen)
                config_screen_update(cui->config_screen, cui->config, sysinfo);
@@ -744,6 +747,9 @@ static void cui_update_config(struct config *config, void *arg)
        if (config->lang)
                cui_update_language(cui, config->lang);
 
+       if (cui->subset_screen)
+               subset_screen_update(cui->subset_screen);
+
        if (cui->config_screen)
                config_screen_update(cui->config_screen, config, cui->sysinfo);
 
index 0b871566aa83fbeda61e02da393f6fb204be36ed..3d86659cd44e9897cf9100de60b715fee6da85eb 100644 (file)
@@ -229,7 +229,7 @@ static void lang_screen_layout_widgets(struct lang_screen *screen)
        widget_move(widget_button_base(screen->widgets.ok_b),
                        y, screen->field_x);
        widget_move(widget_button_base(screen->widgets.cancel_b),
-                       y, screen->field_x + 10);
+                       y, screen->field_x + 14);
 }
 
 static void lang_screen_setup_empty(struct lang_screen *screen)
@@ -286,7 +286,7 @@ static void lang_screen_setup_widgets(struct lang_screen *screen,
                screen->widgets.safe_mode = widget_new_label(set, 0, 0,
                         _("Selecting 'OK' will exit safe mode"));
 
-       screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, _("OK"),
+       screen->widgets.ok_b = widget_new_button(set, 0, 0, 10, _("OK"),
                        ok_click, screen);
        screen->widgets.cancel_b = widget_new_button(set, 0, 0, 10, _("Cancel"),
                        cancel_click, screen);
index b8f9a35e0cddcd7ac16bbd330e73104ee8a0a3e4..3f09d62385b4df4043e985d965347aad13c905c1 100644 (file)
@@ -253,6 +253,7 @@ struct pmenu_item *pmenu_find_device(struct pmenu *menu, struct device *dev,
        switch (dev->type) {
        case DEVICE_TYPE_OPTICAL:
        case DEVICE_TYPE_DISK:
+       case DEVICE_TYPE_USB:
                /* Find block info */
                for (i = 0; sys && i < sys->n_blockdevs; i++) {
                        bd = sys->blockdevs[i];
@@ -263,8 +264,7 @@ struct pmenu_item *pmenu_find_device(struct pmenu *menu, struct device *dev,
                }
                if (matched) {
                        snprintf(buf,sizeof(buf),"[%s: %s / %s]",
-                               dev->type == DEVICE_TYPE_DISK ?
-                                       _("Disk") : _("CD/DVD"),
+                               device_type_display_name(dev->type),
                                bd->name, bd->uuid);
                }
                break;
index f38e3949b5561ea3105c8df869af9fe78b03a901..0faed3b1d6f1b510fdaa9872f81ab69099c8d4af 100644 (file)
@@ -62,6 +62,12 @@ struct nc_scr *subset_screen_return_scr(struct subset_screen *screen)
        return screen->return_scr;
 }
 
+void subset_screen_update(struct subset_screen *screen)
+{
+       pb_debug("Exiting subset due to update\n");
+       return screen->on_exit(screen->cui);
+}
+
 static struct subset_screen *subset_screen_from_scr(struct nc_scr *scr)
 {
        struct subset_screen *subset_screen;
index bde8b331ce2b05fbe9ced376f5736fd31a78226f..ac8ece785f6533a3708233de608c6652941e1cde 100644 (file)
@@ -104,7 +104,11 @@ void sysinfo_screen_update(struct sysinfo_screen *screen,
                const struct system_info *sysinfo)
 {
        sysinfo_screen_populate(screen, sysinfo);
-       text_screen_draw(&screen->text_scr);
+
+       if (screen->text_scr.cui->help_screen)
+               screen->text_scr.need_update = true;
+       else
+               text_screen_draw(&screen->text_scr);
 }
 
 struct sysinfo_screen *sysinfo_screen_init(struct cui *cui,
index 826244cb0a0e9618f086e5a47d133ca751a8de2f..55428e791986d102665fc0aaa42fa36addea3fda 100644 (file)
@@ -183,6 +183,13 @@ void text_screen_set_help(struct text_screen *screen, const char *title,
 
 static int text_screen_post(struct nc_scr *scr)
 {
+       struct text_screen *screen = text_screen_from_scr(scr);
+
+       if (screen->need_update) {
+               text_screen_draw(screen);
+               screen->need_update = false;
+       }
+
        nc_scr_frame_draw(scr);
        redrawwin(scr->main_ncw);
        wrefresh(scr->main_ncw);
@@ -202,6 +209,7 @@ void text_screen_init(struct text_screen *screen, struct cui *cui,
 
        screen->cui = cui;
        screen->on_exit = on_exit;
+       screen->need_update = false;
 
        screen->scr.frame.ltitle = talloc_strdup(screen, title);
        screen->scr.frame.rtitle = NULL;
index 25107cb476caadf32fcf97d311960064ae0cace4..df47186287f7cbb6967d88387e3036f3117b1c5a 100644 (file)
@@ -28,6 +28,7 @@ struct text_screen {
        int                     n_lines;
        int                     n_alloc_lines;
        int                     scroll_y;
+       bool                    need_update;
        const char              *help_title;
        const struct help_text  *help_text;
        void                    (*on_exit)(struct cui *);
index 3daced1a68b56c9e2cb1628384f5b06c70968194..7e03e573d943a81d84ce45c3ba56a2729c8029ed 100644 (file)
@@ -51,6 +51,8 @@
 #include <types/types.h>
 #include <log/log.h>
 #include <util/util.h>
+#include <i18n/i18n.h>
+#include <fold/fold.h>
 
 #include "nc-cui.h"
 #include "nc-widgets.h"
@@ -137,6 +139,7 @@ struct nc_widget_select {
                char            *str;
                int             val;
                FIELD           *field;
+               int             lines;
        } *options;
        int                     top, left, size;
        int                     n_options, selected_option;
@@ -838,21 +841,25 @@ static void select_set_visible(struct nc_widget *widget, bool visible)
 static void select_move(struct nc_widget *widget, int y, int x)
 {
        struct nc_widget_select *select = to_select(widget);
-       int i;
+       int i, cur = 0;
 
-       for (i = 0; i < select->n_options; i++)
-               field_move(select->options[i].field, y + i, x);
+       for (i = 0; i < select->n_options; i++) {
+               field_move(select->options[i].field, y + cur, x);
+               cur += select->options[i].lines;
+       }
 }
 
 static void select_field_focus(struct nc_widget *widget, FIELD *field)
 {
        struct nc_widget_select *select = to_select(widget);
-       int i;
+       int i, cur = 0;
 
        for (i = 0; i < select->n_options; i++) {
-               if (field != select->options[i].field)
+               if (field != select->options[i].field) {
+                       cur += select->options[i].lines;
                        continue;
-               widget->focus_y = i;
+               }
+               widget->focus_y = cur;
                return;
        }
 }
@@ -894,10 +901,47 @@ struct nc_widget_select *widget_new_select(struct nc_widgetset *set,
        return select;
 }
 
+static int widget_select_fold_cb(void *arg, const char *buf, int len)
+{
+       struct nc_widget_select *select = arg;
+       char *line, *newstr, *padbuf = NULL;
+       int i, pad;
+
+       if (!len)
+               return 0;
+
+       line = talloc_strndup(select->options, buf, len);
+
+       i = select->n_options - 1;
+       pad = max(0, select->widget.width - strncols(line));
+
+       if (pad) {
+               padbuf = talloc_array(select->options, char, pad + 1);
+               memset(padbuf, ' ', pad);
+               padbuf[pad] = '\0';
+       }
+
+       if (select->options[i].str)
+               newstr = talloc_asprintf_append(select->options[i].str,
+                                                        "%s%s", line,
+                                                        pad ? padbuf : "");
+       else
+               newstr = talloc_asprintf(select->options, "%s%s", line,
+                                                        pad ? padbuf : "");
+
+       select->options[i].str = newstr;
+       select->options[i].lines++;
+
+       talloc_free(padbuf);
+       talloc_free(line);
+       return 0;
+}
+
 void widget_select_add_option(struct nc_widget_select *select, int value,
                const char *text, bool selected)
 {
        const char *str;
+       char *full_text;
        FIELD *f;
        int i;
 
@@ -916,23 +960,29 @@ void widget_select_add_option(struct nc_widget_select *select, int value,
                str = select_unselected_str;
 
        i = select->n_options++;
-       select->widget.height = select->n_options;
-
        select->options = talloc_realloc(select, select->options,
                                struct select_option, i + 2);
        select->options[i].val = value;
-       select->options[i].str = talloc_asprintf(select->options,
-                                       "%s %s", str, text);
+       select->options[i].lines = 0;
+       select->options[i].str = NULL;
 
-       select->options[i].field = f = new_field(1, select->size,
-                                               select->top + i,
-                                               select->left, 0, 0);
+       full_text = talloc_asprintf(select->options, "%s %s", str, text);
+       fold_text(full_text, select->widget.width,
+                 widget_select_fold_cb, select);
 
-       field_opts_off(f, O_WRAP | O_EDIT);
+       select->options[i].field = f = new_field(select->options[i].lines,
+                                       select->size,
+                                       select->top + select->widget.height,
+                                       select->left, 0, 0);
+
+       select->widget.height += select->options[i].lines;
+
+       field_opts_off(f, O_EDIT);
        set_field_userptr(f, &select->widget);
        set_field_buffer(f, 0, select->options[i].str);
 
        widgetset_add_field(select->set, f);
+       talloc_free(full_text);
 }
 
 int widget_select_get_value(struct nc_widget_select *select)
@@ -944,7 +994,7 @@ int widget_select_get_value(struct nc_widget_select *select)
 
 int widget_select_height(struct nc_widget_select *select)
 {
-       return select->n_options;
+       return select->widget.height;
 }
 
 void widget_select_on_change(struct nc_widget_select *select,
@@ -1002,16 +1052,18 @@ struct nc_widget_button *widget_new_button(struct nc_widgetset *set,
                void (*click)(void *), void *arg)
 {
        struct nc_widget_button *button;
+       int idx, len, pad1, pad2, bufsz;
        char *text;
        FIELD *f;
-       int idx, len;
+
+       int field_size = size + 2;
 
        button = talloc_zero(set, struct nc_widget_button);
        button->widget.height = 1;
-       button->widget.width = size;
+       button->widget.width = field_size;
        button->widget.x = x;
        button->widget.y = y;
-       button->widget.field = f = new_field(1, size + 2, y, x, 0, 0);
+       button->widget.field = f = new_field(1, field_size, y, x, 0, 0);
        button->widget.process_key = button_process_key;
        button->widget.focussed_attr = A_REVERSE;
        button->widget.unfocussed_attr = A_NORMAL;
@@ -1021,17 +1073,28 @@ struct nc_widget_button *widget_new_button(struct nc_widgetset *set,
        field_opts_off(f, O_EDIT);
        set_field_userptr(f, &button->widget);
 
-       /* center str in a size-char buffer, but don't overrun */
-       len = strlen(str);
-       len = min(len, size);
-       idx = (size - len) / 2;
+       /* Center str in the field. This depends on the number of columns used
+        * by the string, not the number of chars in str */
+       len = strncols(str);
+       if (len <= size) {
+               idx = (field_size - len) / 2;
+       } else {
+               idx = 1;
+               pb_log("Warning: '%s' %d columns wide "
+                      "but button is %d columns wide\n",
+                      str, len, size);
+       }
+
+       pad1 = max(idx - 1, 0);
+       pad2 = max(size - len - pad1, 0);
+       bufsz = 1 + pad1 + strlen(str) + pad2 + 2;
 
-       text = talloc_array(button, char, size + 3);
-       memset(text, ' ', size + 2);
-       memcpy(text + idx + 1, str, len);
+       text = talloc_array(button, char, bufsz);
+       memset(text, ' ', bufsz);
+       memcpy(text + idx, str, strlen(str));
        text[0] = '[';
-       text[size + 1] = ']';
-       text[size + 2] = '\0';
+       text[bufsz - 2] = ']';
+       text[bufsz - 1] = '\0';
 
        set_field_buffer(f, 0, text);
 
index 363a28978f810561ddd00991c96683ce9edd9f9a..b099b59128b7bbec99f34845a708d89dc45ea9a7 100644 (file)
@@ -8,6 +8,8 @@ static const char *device_type_string(enum device_type type)
        switch (type) {
        case DEVICE_TYPE_DISK:
                return "disk";
+       case DEVICE_TYPE_USB:
+               return "usb";
        case DEVICE_TYPE_NETWORK:
                return "network";
        case DEVICE_TYPE_OPTICAL:
index 009bec742330223ba966f811e680b94e19ea5c7c..c52180b71686dde5f91ab9920accefb481486e88 100644 (file)
@@ -79,6 +79,8 @@ static void print_config(void *ctx, struct config *config, const char *var)
                        config->safe_mode ? "enabled" : "disabled");
        print_one_config(ctx, var, "debug", "%s",
                        config->debug ? "enabled" : "disabled");
+       print_one_config(ctx, var, "dm-snapshots", "%s",
+                       config->disable_snapshots ? "disabled" : "enabled");
 }
 
 int main(int argc, char **argv)