mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: BAREBOX <barebox@lists.infradead.org>
Subject: [PATCH 4/5] commands: create createnv command
Date: Mon, 02 Jun 2025 15:28:38 +0200	[thread overview]
Message-ID: <20250602-createnv-v1-4-c3239ff875d5@pengutronix.de> (raw)
In-Reply-To: <20250602-createnv-v1-0-c3239ff875d5@pengutronix.de>

We want to move away from describing the barebox environment explicitly
in the device tree and instead motivate usage of GPT partitions for the
envrionment. This patch creates a createnv command to facilitate this.
It creates an environment partition on the specified device and if
necessary also a GPT partition table. In the simplest case a "createnv"
without arguments will create a partition on the device barebox itself
booted from. Both the device and the size of the partition can be
specified on the command line.

We can't create environment partitions on a device containing a MBR
partition table, so a MBR partitioned device won't be touched.

As an additional safety net the command will ask the user if altering
the partition table is really desired. This behaviour can be overwritten
by specifying -f on the command line.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/Kconfig    |  18 ++++++
 commands/Makefile   |   1 +
 commands/createnv.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 198 insertions(+)

diff --git a/commands/Kconfig b/commands/Kconfig
index 0f3155d123ab6eebd6a8b4585ff8c496318c9efe..27a935d4d2e55f0384a28ab1d8718c0cf90fb746 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -771,6 +771,24 @@ endmenu
 
 menu "Environment"
 
+config CMD_CREATENV
+	tristate
+	depends on PARTITION_DISK_EFI
+	select PARTITION_MANIPULATION
+	prompt "createnv"
+	help
+	  createnv - Create a barebox environment partition
+
+	  Usage: createnv [-sf] [device]
+
+	  Create a barebox environment partition.
+	  This creates a barebox environment partition and eventually
+	  a GPT partition table when it does not exist.
+
+	  Options:
+		-s <size>       specify partition size (default 1MiB)
+		-f      force. Do not ask
+
 config CMD_NV
 	depends on NVVAR
 	tristate
diff --git a/commands/Makefile b/commands/Makefile
index 8c2749b5ebddb5ef22691d2007f556af195b432b..2780a26dc2daf86ebdc11011fed0849bafaa982a 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -157,6 +157,7 @@ obj-$(CONFIG_CMD_BTHREAD)	+= bthread.o
 obj-$(CONFIG_CMD_UBSAN)		+= ubsan.o
 obj-$(CONFIG_CMD_SELFTEST)	+= selftest.o
 obj-$(CONFIG_CMD_TUTORIAL)	+= tutorial.o
+obj-$(CONFIG_CMD_CREATENV)	+= createnv.o
 obj-$(CONFIG_CMD_STACKSMASH)	+= stacksmash.o
 obj-$(CONFIG_CMD_PARTED)	+= parted.o
 obj-$(CONFIG_CMD_EFI_HANDLE_DUMP)	+= efi_handle_dump.o
diff --git a/commands/createnv.c b/commands/createnv.c
new file mode 100644
index 0000000000000000000000000000000000000000..df03664be11251165287bd2291d09bee7408f553
--- /dev/null
+++ b/commands/createnv.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <command.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <partitions.h>
+#include <driver.h>
+#include <disks.h>
+#include <xfuncs.h>
+#include <getopt.h>
+#include <efi/partition.h>
+#include <bootsource.h>
+#include <linux/kstrtox.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <envfs.h>
+
+static int do_createnv(int argc, char *argv[])
+{
+	uint64_t start, size = SZ_1M;
+	struct cdev *cdev;
+	struct block_device *blk;
+	struct partition *part;
+	struct partition_desc *pdesc = NULL;
+	enum filetype filetype;
+	guid_t partition_barebox_env_guid = PARTITION_BAREBOX_ENVIRONMENT_GUID;
+	void *buf = NULL;
+	bool force = false;
+	int opt, ret;
+
+	while ((opt = getopt(argc, argv, "s:f")) > 0) {
+		switch (opt) {
+		case 's':
+			size = strtoull_suffix(optarg, NULL, 0);
+			break;
+		case 'f':
+			force = true;
+			break;
+		default:
+			return COMMAND_ERROR_USAGE;
+		}
+        }
+
+	argc -= optind;
+	argv += optind;
+
+	if (argc < 1) {
+		cdev = bootsource_of_cdev_find();
+		if (!cdev) {
+			printf("Cannot find bootsource cdev\n");
+			return COMMAND_ERROR;
+		}
+		ret = cdev_open(cdev, O_RDWR);
+		if (ret) {
+			printf("Cannot open %s: %pe\n", cdev->name, ERR_PTR(ret));
+			return COMMAND_ERROR;
+		}
+	} else {
+		cdev = cdev_open_by_path_name(argv[0], O_RDWR);
+		if (!cdev) {
+			printf("Cannot open %s\n", argv[0]);
+			return COMMAND_ERROR;
+		}
+	}
+
+	blk = cdev_get_block_device(cdev);
+	if (!blk) {
+		ret = -ENOENT;
+		goto err;
+	}
+
+	buf = xzalloc(2 * SECTOR_SIZE);
+
+	ret = cdev_read(cdev, buf, 2 * SECTOR_SIZE, 0, 0);
+	if (ret < 0) {
+		printf("Cannot read from %s: %pe\n", cdev->name, ERR_PTR(ret));
+		goto err;
+	}
+
+	filetype = file_detect_partition_table(buf, 2 * SECTOR_SIZE);
+
+	switch (filetype) {
+	case filetype_gpt:
+		pdesc = partition_table_read(blk);
+		if (!pdesc) {
+			printf("Cannot read partition table\n");
+			ret = -EINVAL;
+			goto err;
+		}
+		break;
+	case filetype_mbr:
+		printf("%s contains a DOS partition table. Cannot create a barebox environment here\n",
+		       cdev->name);
+		ret = -EINVAL;
+		goto err;
+	default:
+		printf("Will create a GPT on %s\n", cdev->name);
+		pdesc = partition_table_new(blk, "gpt");
+		break;
+	}
+
+	list_for_each_entry(part, &pdesc->partitions, list) {
+		if (guid_equal(&part->typeuuid, &partition_barebox_env_guid)) {
+			printf("%s already contains a barebox environment partition\n",
+			       cdev->name);
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
+	size >>= SECTOR_SHIFT;
+
+	ret = partition_find_free_space(pdesc, size, &start);
+	if (ret) {
+		printf("No free space available\n");
+		goto err;
+	}
+
+	ret = partition_create(pdesc, "barebox-environment", "bbenv", start, start + size - 1);
+	if (ret) {
+		printf("Creating partition failed: %pe\n", ERR_PTR(ret));
+		goto err;
+	}
+
+	printf("Will create a barebox environment partition of size %llu bytes on %s\n",
+	       size << SECTOR_SHIFT, cdev->name);
+
+	if (!force) {
+		char c;
+
+		printf("Do you wish to continue? (y/n)\n");
+
+		c = getchar();
+		if (c != 'y') {
+			ret = -EINTR;
+			goto err;
+		}
+	}
+
+	ret = partition_table_write(pdesc);
+	if (ret) {
+		printf("Cannot write partition table: %pe\n", ERR_PTR(ret));
+		goto err;
+	}
+
+	if (!default_environment_path_get()) {
+		char *path = xasprintf("/dev/%s.barebox-environment", cdev->name);
+		default_environment_path_set(path);
+		free(path);
+	}
+
+	printf("Created barebox environment partition on %s\n", cdev->name);
+
+	ret = 0;
+err:
+	if (pdesc)
+		partition_table_free(pdesc);
+
+	free(buf);
+	cdev_close(cdev);
+
+	return ret ? COMMAND_ERROR : 0;
+}
+
+BAREBOX_CMD_HELP_START(createnv)
+BAREBOX_CMD_HELP_TEXT("Create a barebox environment partition.")
+BAREBOX_CMD_HELP_TEXT("This creates a barebox environment partition and eventually")
+BAREBOX_CMD_HELP_TEXT("a GPT partition table when it does not exist.")
+BAREBOX_CMD_HELP_OPT("-s <size>", "specify partition size (default 1MiB)")
+BAREBOX_CMD_HELP_OPT("-f\t", "force. Do not ask")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(createnv)
+        .cmd            = do_createnv,
+        BAREBOX_CMD_DESC("Create a barebox environment partition")
+        BAREBOX_CMD_OPTS("[-sf] [device]")
+        BAREBOX_CMD_GROUP(CMD_GRP_CONSOLE)
+        BAREBOX_CMD_HELP(cmd_createnv_help)
+BAREBOX_CMD_END

-- 
2.39.5




  parent reply	other threads:[~2025-06-02 13:29 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-02 13:28 [PATCH 0/5] add createnv command to create environment partition Sascha Hauer
2025-06-02 13:28 ` [PATCH 1/5] partitions: efi: calculate instead of hardcode gpt header fields Sascha Hauer
2025-06-02 13:28 ` [PATCH 2/5] partitions: Start partitions at 8MiB offset Sascha Hauer
2025-06-02 22:16   ` Marco Felsch
2025-06-03  7:46     ` Sascha Hauer
2025-06-02 13:28 ` [PATCH 3/5] cdev: fix cdev_open_by_name() misuse Sascha Hauer
2025-06-02 13:28 ` Sascha Hauer [this message]
2025-06-02 13:48   ` [PATCH 4/5] commands: create createnv command Ahmad Fatoum
2025-06-02 14:50     ` Sascha Hauer
2025-06-02 13:28 ` [PATCH 5/5] mci: add option to detect non-removable cards during startup Sascha Hauer
2025-06-02 13:42   ` Ahmad Fatoum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250602-createnv-v1-4-c3239ff875d5@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox