From patchwork Mon May 2 06:32:53 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Mendoza-Jonas X-Patchwork-Id: 617377 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qyvd824sBz9t5C for ; Mon, 2 May 2016 16:33:16 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b=tQgUKX9C; dkim-atps=neutral Received: from ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3qyvd76Q7jzDqGy for ; Mon, 2 May 2016 16:33:15 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b=tQgUKX9C; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Received: from mendozajonas.com (mendozajonas.com [188.166.185.233]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3qyvd02nQSzDqCT for ; Mon, 2 May 2016 16:33:08 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b=tQgUKX9C; dkim-atps=neutral Received: from skellige.ozlabs.ibm.com (unknown [122.99.82.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client did not present a certificate) (Authenticated sender: sam@mendozajonas.com) by mendozajonas.com (Postfix) with ESMTPSA id 476DC14005E for ; Mon, 2 May 2016 14:33:03 +0800 (SGT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mendozajonas.com; s=mail; t=1462170784; bh=SPT7+WMZQQYRdez+k+q4ENL9dzLrKrq+XElM/Xsjark=; h=From:To:Subject:Date:In-Reply-To:References:From; b=tQgUKX9CnAwcWCX5z56EgViL/IQLZiQazLYYFd1njktXjhG6c4dVK0kGD/g4od2Id fN0SG9pbWJ/Wz9xx5IwBFsFmpxv1SipQng71WeYPWq9ZNcqvvcVC7ULI1VroHnDShx h5a4fATXScpW2Nc55z15/9rLkloFxH9coDtVvCO8= From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [PATCH 2/3] ui/ncurses: Start UI before connected to server Date: Mon, 2 May 2016 16:32:53 +1000 Message-Id: <1462170774-16407-2-git-send-email-sam@mendozajonas.com> X-Mailer: git-send-email 2.8.2 In-Reply-To: <1462170774-16407-1-git-send-email-sam@mendozajonas.com> References: <1462170774-16407-1-git-send-email-sam@mendozajonas.com> X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" 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 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 --- ui/ncurses/generic-main.c | 13 ++++++++---- ui/ncurses/nc-cui.c | 50 +++++++++++++++++++++++++++++++++++++++++------ ui/ncurses/nc-cui.h | 2 +- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/ui/ncurses/generic-main.c b/ui/ncurses/generic-main.c index 27744d4..7062796 100644 --- a/ui/ncurses/generic-main.c +++ b/ui/ncurses/generic-main.c @@ -49,8 +49,8 @@ static void print_usage(void) { print_version(); printf( -"%s: petitboot-nc [-h, --help] [-l, --log log-file]\n" -" [-s, --start-daemon] [-v, --verbose] [-V, --version]\n", +"%s: petitboot-nc [-h, --help] [-l, --log log-file] [-s, --start-daemon]\n" +" [-t, --timeout] [-v, --verbose] [-V, --version]\n", _("Usage")); } @@ -68,6 +68,7 @@ struct opts { enum opt_value show_help; const char *log_file; enum opt_value start_daemon; + enum opt_value timeout; enum opt_value verbose; enum opt_value show_version; }; @@ -82,11 +83,12 @@ static int opts_parse(struct opts *opts, int argc, char *argv[]) {"help", no_argument, NULL, 'h'}, {"log", required_argument, NULL, 'l'}, {"start-daemon", no_argument, NULL, 's'}, + {"timeout", no_argument, NULL, 't'}, {"verbose", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'V'}, { NULL, 0, NULL, 0}, }; - static const char short_options[] = "dhl:svV"; + static const char short_options[] = "dhl:stvV"; static const struct opts default_values = { 0 }; *opts = default_values; @@ -108,6 +110,9 @@ static int opts_parse(struct opts *opts, int argc, char *argv[]) case 's': opts->start_daemon = opt_yes; break; + case 't': + opts->timeout = opt_yes; + break; case 'v': opts->verbose = opt_yes; break; @@ -244,7 +249,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - cui = cui_init(NULL, NULL, opts.start_daemon); + cui = cui_init(NULL, NULL, opts.start_daemon, opts.timeout); if (!cui) return EXIT_FAILURE; diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c index 6888fa7..e2a744d 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,39 @@ 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. + */ +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 +940,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 +961,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 +988,10 @@ retry_start: goto fail_client_init; } - if (!cui->client) { + if (!cui->client && !timeout) { + waiter_register_timeout(cui->waitset, 1000, + 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__); diff --git a/ui/ncurses/nc-cui.h b/ui/ncurses/nc-cui.h index afdb3c8..b00d251 100644 --- a/ui/ncurses/nc-cui.h +++ b/ui/ncurses/nc-cui.h @@ -72,7 +72,7 @@ struct cui { struct cui *cui_init(void* platform_info, int (*js_map)(const struct js_event *e), - int start_daemon); + int start_daemon, int timeout); struct nc_scr *cui_set_current(struct cui *cui, struct nc_scr *scr); int cui_run(struct cui *cui); void cui_item_edit(struct pmenu_item *item);