From: Tobias Waldekranz <tobias@waldekranz.com>
To: barebox@lists.infradead.org
Subject: [PATCH 5/5] commands: dmsetup: Basic command set for dm device management
Date: Thu, 28 Aug 2025 17:05:30 +0200 [thread overview]
Message-ID: <20250828150637.2222474-6-tobias@waldekranz.com> (raw)
In-Reply-To: <20250828150637.2222474-1-tobias@waldekranz.com>
Modeled on dmsetup(8) from LVM2.
This lets the user create/remove arbitrary dm devices using the same
table file format used in Linux, and dump information about currently
configured devices.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
commands/Kconfig | 14 +++++
commands/Makefile | 1 +
commands/dmsetup.c | 145 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 160 insertions(+)
create mode 100644 commands/dmsetup.c
diff --git a/commands/Kconfig b/commands/Kconfig
index 1626912c30..219f626c3e 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -732,6 +732,20 @@ config CMD_PARTED
unit <unit> change display/input units
refresh refresh a partition table
+config CMD_DMSETUP
+ tristate
+ depends on DM_BLK
+ prompt "dmsetup"
+ help
+ dmsetup - low level interface to the device mapper
+
+ Compose virtual block devices from a table of mappings from
+ logical block addresses to various data sources, such as
+ linear ranges from other existing devices.
+
+ commands:
+ create <name> <table-file>
+
config CMD_UBI
tristate
default y if MTD_UBI
diff --git a/commands/Makefile b/commands/Makefile
index d9403b18d5..6b010fe30c 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -166,4 +166,5 @@ obj-$(CONFIG_CMD_STACKSMASH) += stacksmash.o
obj-$(CONFIG_CMD_PARTED) += parted.o
obj-$(CONFIG_CMD_EFI_HANDLE_DUMP) += efi_handle_dump.o
obj-$(CONFIG_CMD_HOST) += host.o
+obj-$(CONFIG_CMD_DMSETUP) += dmsetup.o
UBSAN_SANITIZE_ubsan.o := y
diff --git a/commands/dmsetup.c b/commands/dmsetup.c
new file mode 100644
index 0000000000..722aa6cbf0
--- /dev/null
+++ b/commands/dmsetup.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-FileCopyrightText: © 2025 Tobias Waldekranz <tobias@waldekranz.com>, Wires
+
+#include <command.h>
+#include <common.h>
+#include <dm.h>
+#include <libfile.h>
+
+static struct dm_device *dmsetup_find(const char *name)
+{
+ struct dm_device *dm;
+
+ dm = dm_find_by_name(name);
+ if (IS_ERR_OR_NULL(dm)) {
+ pr_err("Found no device named \"%s\"\n", name);
+ return NULL;
+ }
+
+ return dm;
+}
+
+static int dmsetup_remove(int argc, char *argv[])
+{
+ struct dm_device *dm;
+
+ if (argc != 1)
+ return COMMAND_ERROR_USAGE;
+
+ dm = dmsetup_find(argv[0]);
+ if (!dm)
+ return COMMAND_ERROR;
+
+ dm_destroy(dm);
+
+ pr_info("Removed %s\n", argv[0]);
+ return COMMAND_SUCCESS;
+}
+
+static int dmsetup_info_one(struct dm_device *dm, void *_n)
+{
+ int *n = _n;
+ char *str;
+
+ if (*n)
+ pr_info("\n");
+
+ str = dm_asprint(dm);
+ pr_info("%s", str);
+ free(str);
+ (*n)++;
+ return 0;
+}
+
+static int dmsetup_info(int argc, char *argv[])
+{
+ struct dm_device *dm;
+ int n = 0;
+
+ if (argc == 0) {
+ dm_foreach(dmsetup_info_one, &n);
+ if (n == 0)
+ pr_info("No devices found\n");
+ return COMMAND_SUCCESS;
+ }
+
+ if (argc != 1)
+ return COMMAND_ERROR_USAGE;
+
+ dm = dmsetup_find(argv[0]);
+ if (!dm)
+ return COMMAND_ERROR;
+
+ dmsetup_info_one(dm, &n);
+ return COMMAND_SUCCESS;
+}
+
+
+static int dmsetup_create(int argc, char *argv[])
+{
+ struct dm_device *dm;
+ char *table;
+
+ if (argc != 2)
+ return COMMAND_ERROR_USAGE;
+
+ table = read_file(argv[1], NULL);
+ if (!table) {
+ pr_err("Failed to read table from %s: %m\n", argv[1]);
+ return COMMAND_ERROR;
+ }
+
+ dm = dm_create(argv[0], table);
+ free(table);
+ if (IS_ERR_OR_NULL(dm)) {
+ pr_err("Failed to create %s: %s\n",
+ argv[0], strerror(-PTR_ERR(dm)));
+ return COMMAND_ERROR;
+ }
+
+ pr_info("Created %s\n", argv[0]);
+ return COMMAND_SUCCESS;
+}
+
+static int do_dmsetup(int argc, char *argv[])
+{
+ const char *cmd;
+
+ if (argc < 2)
+ return COMMAND_ERROR_USAGE;
+
+ cmd = argv[1];
+ argc -= 2;
+ argv += 2;
+
+ if (!strcmp(cmd, "create"))
+ return dmsetup_create(argc, argv);
+ else if (!strcmp(cmd, "info"))
+ return dmsetup_info(argc, argv);
+ else if (!strcmp(cmd, "remove"))
+ return dmsetup_remove(argc, argv);
+
+ printf("Unknown command: %s\n", cmd);
+ return -EINVAL;
+}
+
+BAREBOX_CMD_HELP_START(dmsetup)
+BAREBOX_CMD_HELP_TEXT("dmsetup - low level interface to the device mapper")
+BAREBOX_CMD_HELP_TEXT("")
+BAREBOX_CMD_HELP_TEXT("Compose virtual block devices from a table of mappings from")
+BAREBOX_CMD_HELP_TEXT("logical block addresses to various data sources, such as")
+BAREBOX_CMD_HELP_TEXT("linear ranges from other existing devices.")
+BAREBOX_CMD_HELP_TEXT("")
+BAREBOX_CMD_HELP_TEXT("commands:")
+BAREBOX_CMD_HELP_OPT("create <name> <table-file>", "Create new device")
+BAREBOX_CMD_HELP_OPT("info [<name>]", "Show device information")
+BAREBOX_CMD_HELP_OPT("remove <name>", "Remove device")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(dmsetup)
+ .cmd = do_dmsetup,
+ BAREBOX_CMD_DESC("low level interface to the device mapper")
+ BAREBOX_CMD_OPTS("<command> [args...]")
+ BAREBOX_CMD_GROUP(CMD_GRP_PART)
+ BAREBOX_CMD_HELP(cmd_dmsetup_help)
+BAREBOX_CMD_END
--
2.43.0
prev parent reply other threads:[~2025-08-28 17:29 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-28 15:05 [PATCH 0/5] dm: Initial work on a device mapper Tobias Waldekranz
2025-08-28 15:05 ` [PATCH 1/5] string: add strtok/strtokv Tobias Waldekranz
2025-08-28 15:05 ` [PATCH 2/5] dm: Add initial device mapper infrastructure Tobias Waldekranz
2025-08-28 15:05 ` [PATCH 3/5] dm: linear: Add linear target Tobias Waldekranz
2025-08-29 5:56 ` Ahmad Fatoum
2025-08-28 15:05 ` [PATCH 4/5] test: self: dm: Add test of " Tobias Waldekranz
2025-08-28 15:05 ` Tobias Waldekranz [this message]
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=20250828150637.2222474-6-tobias@waldekranz.com \
--to=tobias@waldekranz.com \
--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