discover: Make boot_priorities more flexible
authorJeremy Kerr <jk@ozlabs.org>
Thu, 30 Jan 2014 08:19:20 +0000 (16:19 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Thu, 30 Jan 2014 13:59:10 +0000 (21:59 +0800)
Rather than rely on the ordering of the boot_priorities array to define
which device types have a higher "default boot" priority, this change
introduces a slightly more flexible way of priority lookups, by adding a
separate priority field to struct boot_priority.

This means we can have an unordered array, change priorities without
re-writing the array, and implementing a disable mechanism.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
discover/device-handler.c
discover/platform.c
lib/pb-config/pb-config.c
lib/pb-protocol/pb-protocol.c
lib/types/types.h

index c57b7b62880d8d4a8952fd896ac3bfe8dd38311d..a2713904f01f4f85e30547c5a63ff643b0e46bf6 100644 (file)
@@ -386,28 +386,36 @@ static int default_option_priority(struct discover_boot_option *opt)
        for (i = 0; i < config->n_boot_priorities; i++) {
                prio = &config->boot_priorities[i];
                if (priority_match(prio, opt))
-                       break;
+                       return prio->priority;
        }
 
-       return i;
+       return 0;
 }
 
 static void set_default(struct device_handler *handler,
                struct discover_boot_option *opt)
 {
+       int new_prio;
+
        if (!handler->autoboot_enabled)
                return;
 
+       new_prio = default_option_priority(opt);
+
+       /* A negative priority indicates that we don't want to boot this device
+        * by default */
+       if (new_prio < 0)
+               return;
+
        /* Resolve any conflicts: if we have a new default option, it only
         * replaces the current if it has a higher priority. */
        if (handler->default_boot_option) {
-               int new_prio, cur_prio;
+               int cur_prio;
 
-               new_prio = default_option_priority(opt);
                cur_prio = default_option_priority(
                                        handler->default_boot_option);
 
-               if (new_prio < cur_prio) {
+               if (new_prio > cur_prio) {
                        handler->default_boot_option = opt;
                        /* extend the timeout a little, so the user sees some
                         * indication of the change */
index d52c9f65eecd48617b24f911a803f9498cde4ab4..db0ea61dd025c7fd6dabb93c51e12a9d434115cb 100644 (file)
@@ -67,8 +67,9 @@ void config_set_defaults(struct config *config)
        config->boot_priorities = talloc_array(config, struct boot_priority,
                                                config->n_boot_priorities);
        config->boot_priorities[0].type = DEVICE_TYPE_NETWORK;
+       config->boot_priorities[0].priority = 2;
        config->boot_priorities[1].type = DEVICE_TYPE_DISK;
-
+       config->boot_priorities[1].priority = 1;
 }
 
 int platform_init(void *ctx)
index 35008cc8c823afdf095fb2ffc319c0b828979b63..ed84fec9e76d8dc4fc21859eebdeed8fa9cd3f8f 100644 (file)
@@ -62,8 +62,11 @@ struct config *config_copy(void *ctx, const struct config *src)
        dest->boot_priorities = talloc_array(dest, struct boot_priority,
                        src->n_boot_priorities);
 
-       for (i = 0; i < src->n_boot_priorities; i++)
+       for (i = 0; i < src->n_boot_priorities; i++) {
+               dest->boot_priorities[i].priority =
+                                       src->boot_priorities[i].priority;
                dest->boot_priorities[i].type = src->boot_priorities[i].type;
+       }
 
        return dest;
 }
index 5a1cee7a417bc648e883a0c3020f0c42c640430d..3c472febdb14c88a7a0ef82112230c2d67d2fbc3 100644 (file)
@@ -279,7 +279,7 @@ int pb_protocol_config_len(const struct config *config)
                len += 4 + optional_strlen(config->network.dns_servers[i]);
 
        len += 4;
-       len += config->n_boot_priorities * 4;
+       len += config->n_boot_priorities * 8;
 
        return len;
 }
@@ -464,7 +464,11 @@ int pb_protocol_serialise_config(const struct config *config,
        *(uint32_t *)pos = __cpu_to_be32(config->n_boot_priorities);
        pos += 4;
        for (i = 0; i < config->n_boot_priorities; i++) {
-               *(uint32_t *)pos = __cpu_to_be32(config->boot_priorities[i].type);
+               *(uint32_t *)pos =
+                       __cpu_to_be32(config->boot_priorities[i].type);
+               pos += 4;
+               *(uint32_t *)pos =
+                       __cpu_to_be32(config->boot_priorities[i].priority);
                pos += 4;
        }
 
index 3a76cdaa751b6e0230e761c97df46942542efc0a..a1065eee62e24efe974dde1eaae11e0ba0dc5658 100644 (file)
@@ -109,6 +109,11 @@ struct network_config {
 };
 
 struct boot_priority {
+       /* Boot options with higher priority values will take precedence over
+        * lower values. Negative priorities signify "don't boot this by
+        * default".
+        */
+       int                     priority;
        enum device_type        type;
 };