diff options
author | Samuel Mendoza-Jonas <sam@mendozajonas.com> | 2016-05-02 13:18:39 +1000 |
---|---|---|
committer | Samuel Mendoza-Jonas <sam@mendozajonas.com> | 2016-05-06 13:57:09 +1000 |
commit | bbaa3ac16e14b1f386d70d14f16d0164d163017e (patch) | |
tree | 3d0929402f9f2175fe00e1f12a348eafcb136c12 /ui/ncurses/nc-cui.c | |
parent | 1949b1f0f990c7ab171339e20731fe6b17c92d8f (diff) | |
download | petitboot-bbaa3ac16e14b1f386d70d14f16d0164d163017e.zip petitboot-bbaa3ac16e14b1f386d70d14f16d0164d163017e.tar.gz |
ui/ncurses: Start UI before connected to server
If petitboot-nc starts before the discover server it will try to
connect for a short while waiting for the server to appear. However in
some scenarios the server can take longer than expected to come up, for
example if the kernel is compiled with modules and the system has many
disks, and the process will timeout and exit before the server is ready.
The UI does not appear during this time so it can appear as if Petitboot
failed to start at all.
Change the default behaviour to start the UI first, and then wait for
the server to appear. The UI will not timeout in this mode. The
"--timeout" option is added to start with the old behaviour.
Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
Diffstat (limited to 'ui/ncurses/nc-cui.c')
-rw-r--r-- | ui/ncurses/nc-cui.c | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c index 6888fa7..a2de48e 100644 --- a/ui/ncurses/nc-cui.c +++ b/ui/ncurses/nc-cui.c @@ -423,7 +423,7 @@ static int cui_process_key(void *arg) if (c == ERR) break; - if (!cui->has_input) { + if (!cui->has_input && cui->client) { pb_log("UI input received (key = %d), aborting " "default boot\n", c); discover_client_cancel_default(cui->client); @@ -798,13 +798,15 @@ static int menu_lang_execute(struct pmenu_item *item) static int menu_reinit_execute(struct pmenu_item *item) { - cui_send_reinit(cui_from_item(item)); + if (cui_from_item(item)->client) + cui_send_reinit(cui_from_item(item)); return 0; } static int menu_add_url_execute(struct pmenu_item *item) { - cui_show_add_url(cui_from_item(item)); + if (cui_from_item(item)->client) + cui_show_add_url(cui_from_item(item)); return 0; } @@ -894,6 +896,42 @@ static struct discover_client_ops cui_client_ops = { .update_config = cui_update_config, }; +/* cui_server_wait - Connect to the discover server. + * @arg: Pointer to the cui instance. + * + * A timeout callback that attempts to connect to the discover server; on + * failure it registers itself with a one second timeout to try again. + * On success the cui->client struct will be set. + * + * Since this updates the status line when called it must not be called + * before the UI is ready. + */ +static int cui_server_wait(void *arg) +{ + struct cui *cui = cui_from_arg(arg); + + if (cui->client) { + pb_debug("We already have a server!\n"); + return 0; + } + + /* We haven't yet connected to the server */ + pb_log("Trying to connect...\n"); + cui->client = discover_client_init(cui->waitset, + &cui_client_ops, cui); + + if (!cui->client) { + waiter_register_timeout(cui->waitset, 1000, cui_server_wait, + cui); + nc_scr_status_printf(cui->current, "Info: Waiting for server"); + } else { + nc_scr_status_printf(cui->current, "Info: Connected to server!"); + talloc_steal(cui, cui->client); + } + + return 0; +} + /** * cui_init - Setup the cui instance. * @platform_info: A value for the struct cui platform_info member. @@ -905,7 +943,7 @@ static struct discover_client_ops cui_client_ops = { */ struct cui *cui_init(void* platform_info, - int (*js_map)(const struct js_event *e), int start_daemon) + int (*js_map)(const struct js_event *e), int start_daemon, int timeout) { struct cui *cui; unsigned int i; @@ -926,7 +964,7 @@ struct cui *cui_init(void* platform_info, /* Loop here for scripts that just started the server. */ retry_start: - for (i = start_daemon ? 2 : 15; i; i--) { + for (i = start_daemon ? 2 : 15; i && timeout; i--) { cui->client = discover_client_init(cui->waitset, &cui_client_ops, cui); if (cui->client || !i) @@ -953,7 +991,12 @@ retry_start: goto fail_client_init; } - if (!cui->client) { + if (!cui->client && !timeout) { + /* Have the first timeout fire immediately so we can check + * for the server as soon as the UI is ready */ + waiter_register_timeout(cui->waitset, 0, + cui_server_wait, cui); + } else if (!cui->client) { pb_log("%s: discover_client_init failed.\n", __func__); fprintf(stderr, _("%s: error: discover_client_init failed.\n"), __func__); |