From patchwork Wed Nov 20 02:42:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Kerr X-Patchwork-Id: 1197777 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47Hng81sh6z9sPV for ; Wed, 20 Nov 2019 14:07:32 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=ozlabs.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=ozlabs.org header.i=@ozlabs.org header.b="gZ/XgRaA"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 47Hng80qkpzDqbv for ; Wed, 20 Nov 2019 14:07:32 +1100 (AEDT) X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Received: from ozlabs.org (bilbo.ozlabs.org [IPv6:2401:3900:2:1::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 47Hn9T6hDmzDqTk for ; Wed, 20 Nov 2019 13:45:17 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=ozlabs.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=ozlabs.org header.i=@ozlabs.org header.b="gZ/XgRaA"; dkim-atps=neutral Received: by ozlabs.org (Postfix, from userid 1023) id 47Hn9S71JRz9sPf; Wed, 20 Nov 2019 13:45:16 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ozlabs.org; s=201707; t=1574217916; bh=xZtP0SsbZdmx55fnbDR/jNe+X9ieeLPwSKs1pGlMxwU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=gZ/XgRaAjSGhpIjznqvRgP5K2gt2B350OBYoYbELSWMDHyXYcrWKQkNnKVV2xP475 JeZjYh99hd4bsdVn2bBJC+DSe0FWPguHG7UieHFYLaIhN52XPR0xwI//cGaROABUjN oVukKS2maTLq6lQXFPiR39C1vln7uzFc5KUNQa9/YHC+Icnu49PCfV8ckss8TY7aIG lHhyT+ouSe5qGan00r5RWc0WIsCqZLEDCq4OlMz20FCXfAbQX6MooYL+pX2tWyATBy y6wzMzFGWZpeKW7qhQK6WGPEeWKbCOlXkPQklsjZTOsk8SOr3aqMk2nP0phjTqGGkP YK09zLA0geauA== From: Jeremy Kerr To: petitboot@lists.ozlabs.org Subject: [PATCH 04/14] discover/grub2: Add support for UUID and label for 'search' command Date: Wed, 20 Nov 2019 10:42:56 +0800 Message-Id: <20191120024306.16526-5-jk@ozlabs.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191120024306.16526-1-jk@ozlabs.org> References: <20191120024306.16526-1-jk@ozlabs.org> MIME-Version: 1.0 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" This change adds support for searching by UUID and filesystem label. We still fall back to passthrough if the UUID is not found, but we now resolve to device ID strings. Signed-off-by: Jeremy Kerr --- discover/grub2/builtins.c | 55 +++++++++++++++++++++++++-- test/parser/Makefile.am | 2 + test/parser/test-grub2-search-label.c | 47 +++++++++++++++++++++++ test/parser/test-grub2-search-uuid.c | 55 +++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 test/parser/test-grub2-search-label.c create mode 100644 test/parser/test-grub2-search-uuid.c diff --git a/discover/grub2/builtins.c b/discover/grub2/builtins.c index ab6b0ec..7cac9f1 100644 --- a/discover/grub2/builtins.c +++ b/discover/grub2/builtins.c @@ -115,6 +115,21 @@ static const struct option search_options[] = { .has_arg = required_argument, .val = 's', }, + { + .name = "file", + .has_arg = no_argument, + .val = 'f', + }, + { + .name = "label", + .has_arg = no_argument, + .val = 'l', + }, + { + .name = "fs-uuid", + .has_arg = no_argument, + .val = 'u', + }, { 0 }, }; @@ -122,13 +137,23 @@ static int builtin_search(struct grub2_script *script, void *data __attribute__((unused)), int argc, char *argv[]) { - const char *env_var, *spec; + const char *env_var, *spec, *res; + struct discover_device *dev; + enum { + LOOKUP_UUID = 'u', + LOOKUP_LABEL = 'l', + LOOKUP_FILE = 'f', + } lookup_type; env_var = "root"; optind = 0; + /* Default to UUID, for backwards compat with earlier petitboot + * versions. This argument is non-optional in GRUB. */ + lookup_type = LOOKUP_UUID; + for (;;) { - int c = getopt_long(argc, argv, ":", search_options, NULL); + int c = getopt_long(argc, argv, ":flu", search_options, NULL); if (c == -1) break; @@ -136,6 +161,11 @@ static int builtin_search(struct grub2_script *script, case 's': env_var = optarg; break; + case LOOKUP_UUID: + case LOOKUP_LABEL: + case LOOKUP_FILE: + lookup_type = c; + break; case '?': case ':': break; @@ -149,8 +179,27 @@ static int builtin_search(struct grub2_script *script, return -1; spec = argv[optind]; + res = NULL; + + switch (lookup_type) { + case LOOKUP_UUID: + dev = device_lookup_by_uuid(script->ctx->handler, + spec); + res = dev ? dev->device->id : spec; + break; + case LOOKUP_LABEL: + dev = device_lookup_by_label(script->ctx->handler, + spec); + if (dev) + res = dev->device->id; + break; + case LOOKUP_FILE: + /* not yet implemented */ + break; + } - script_env_set(script, env_var, spec); + if (res) + script_env_set(script, env_var, res); return 0; } diff --git a/test/parser/Makefile.am b/test/parser/Makefile.am index df9c539..f5985d6 100644 --- a/test/parser/Makefile.am +++ b/test/parser/Makefile.am @@ -30,6 +30,8 @@ parser_TESTS = \ test/parser/test-grub2-single-line-if \ test/parser/test-grub2-pos-param \ test/parser/test-grub2-search-args \ + test/parser/test-grub2-search-uuid \ + test/parser/test-grub2-search-label \ test/parser/test-grub2-load-env \ test/parser/test-grub2-save-env \ test/parser/test-grub2-save-env-dash-f \ diff --git a/test/parser/test-grub2-search-label.c b/test/parser/test-grub2-search-label.c new file mode 100644 index 0000000..b9ee034 --- /dev/null +++ b/test/parser/test-grub2-search-label.c @@ -0,0 +1,47 @@ +/* check for grub2 search command, searching by partition label */ + +#include "parser-test.h" + +#if 0 /* PARSER_EMBEDDED_CONFIG */ + +# valid label +search --set=v1 --label testlabel + +v2=prev +# invalid label: does not alter v2 +search --set=v2 --label invalidlabel + +menuentry $v1 { + linux /vmlinux +} + +menuentry $v2 { + linux /vmlinux +} + +#endif + +void run_test(struct parser_test *test) +{ + struct discover_boot_option *opt; + struct discover_context *ctx; + struct discover_device *dev; + + ctx = test->ctx; + + dev = test_create_device(test, "testdev"); + dev->label = "testlabel"; + device_handler_add_device(test->handler, dev); + + test_read_conf_embedded(test, "/grub/grub.cfg"); + + test_run_parser(test, "grub2"); + + check_boot_option_count(ctx, 2); + + opt = get_boot_option(ctx, 0); + check_name(opt, "testdev"); + + opt = get_boot_option(ctx, 1); + check_name(opt, "prev"); +} diff --git a/test/parser/test-grub2-search-uuid.c b/test/parser/test-grub2-search-uuid.c new file mode 100644 index 0000000..7eacd1d --- /dev/null +++ b/test/parser/test-grub2-search-uuid.c @@ -0,0 +1,55 @@ +/* check for grub2 search command, searching by FS UUID */ + +#include "parser-test.h" + +#if 0 /* PARSER_EMBEDDED_CONFIG */ + +# valid UUID +search --set=v1 --fs-uuid ee0cc6fa-1dba-48f2-8f5b-19e4b8de8c37 + +# invalid UUID: will fall back to passing the UUID through +search --set=v2 --fs-uuid 92b0da57-6e04-4e54-960b-85e6bb060433 + +# no 'type' argument defaults to UUID search +search --set=v3 ee0cc6fa-1dba-48f2-8f5b-19e4b8de8c37 + +menuentry $v1 { + linux /vmlinux +} + +menuentry $v2 { + linux /vmlinux +} + +menuentry $v3 { + linux /vmlinux +} +#endif + +void run_test(struct parser_test *test) +{ + struct discover_boot_option *opt; + struct discover_context *ctx; + struct discover_device *dev; + + ctx = test->ctx; + + dev = test_create_device(test, "testdev"); + dev->uuid = "ee0cc6fa-1dba-48f2-8f5b-19e4b8de8c37"; + device_handler_add_device(test->handler, dev); + + test_read_conf_embedded(test, "/grub/grub.cfg"); + + test_run_parser(test, "grub2"); + + check_boot_option_count(ctx, 3); + + opt = get_boot_option(ctx, 0); + check_name(opt, dev->device->id); + + opt = get_boot_option(ctx, 1); + check_name(opt, "92b0da57-6e04-4e54-960b-85e6bb060433"); + + opt = get_boot_option(ctx, 2); + check_name(opt, dev->device->id); +}