discover: Implement device priorities
authorJeremy Kerr <jk@ozlabs.org>
Thu, 19 Sep 2013 14:18:04 +0000 (22:18 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Thu, 19 Sep 2013 14:21:38 +0000 (22:21 +0800)
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
discover/device-handler.c
lib/pb-config/pb-config.c
lib/pb-config/pb-config.h

index cdfee483767e449c885d0ebf3db3671040a4c78f..f9d2dbf5d53f1450d56c0c201738567cfb9b9166 100644 (file)
@@ -334,17 +334,50 @@ static int default_timeout(void *arg)
        return 0;
 }
 
-static void set_default(struct device_handler *handler,
+static bool priority_match(struct boot_priority *prio,
                struct discover_boot_option *opt)
 {
-       if (handler->default_boot_option)
-               return;
+       return prio->type == opt->device->device->type;
+}
+
+static int default_option_priority(struct discover_boot_option *opt)
+{
+       const struct config *config;
+       struct boot_priority *prio;
+       int i;
+
+       config = config_get();
+
+       for (i = 0; i < config->n_boot_priorities; i++) {
+               prio = &config->boot_priorities[i];
+               if (priority_match(prio, opt))
+                       break;
+       }
+
+       return i;
+}
 
+static void set_default(struct device_handler *handler,
+               struct discover_boot_option *opt)
+{
        if (!handler->autoboot_enabled)
                return;
 
-       handler->default_boot_option = opt;
+       /* 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;
+
+               new_prio = default_option_priority(opt);
+               cur_prio = default_option_priority(
+                                       handler->default_boot_option);
+
+               if (new_prio >= cur_prio)
+                       return;
+       }
+
        handler->sec_to_boot = config_get()->autoboot_timeout_sec;
+       handler->default_boot_option = opt;
 
        pb_log("Boot option %s set as default, timeout %u sec.\n",
               opt->option->id, handler->sec_to_boot);
index aad3b9e5a44cf3f7838fe252e36a2b614a1d007f..b6f26c70fe16c3e3cd174d7392532d85ce43dc50 100644 (file)
@@ -1,5 +1,6 @@
 
 #include <log/log.h>
+#include <types/types.h>
 #include <talloc/talloc.h>
 
 #include "pb-config.h"
@@ -18,6 +19,13 @@ static void config_set_defaults(struct config *config)
        config->network.n_interfaces = 0;
        config->network.dns_servers = NULL;
        config->network.n_dns_servers = 0;
+
+       config->n_boot_priorities = 2;
+       config->boot_priorities = talloc_array(config, struct boot_priority,
+                                               config->n_boot_priorities);
+       config->boot_priorities[0].type = DEVICE_TYPE_NETWORK;
+       config->boot_priorities[1].type = DEVICE_TYPE_DISK;
+
 }
 
 static void dump_config(struct config *config)
index c74fa1b530188410478e3414a2c8759a813fdfda..523cada5cab3f745c792ff2d748610ee14f6832e 100644 (file)
@@ -4,6 +4,8 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include <types/types.h>
+
 #define HWADDR_SIZE    6
 
 struct interface_config {
@@ -30,10 +32,16 @@ struct network_config {
        int                     n_dns_servers;
 };
 
+struct boot_priority {
+       enum device_type        type;
+};
+
 struct config {
        bool                    autoboot_enabled;
        int                     autoboot_timeout_sec;
        struct network_config   network;
+       struct boot_priority    *boot_priorities;
+       int                     n_boot_priorities;
 };