From patchwork Thu Apr 10 14:43:40 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ezequiel Garcia X-Patchwork-Id: 338155 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 267FC140081 for ; Fri, 11 Apr 2014 02:16:36 +1000 (EST) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WYHcu-0007kM-Fl; Thu, 10 Apr 2014 16:14:57 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WYHcX-0005Fl-Hp; Thu, 10 Apr 2014 16:14:33 +0000 Received: from casper.infradead.org ([2001:770:15f::2]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WYHWr-000478-LY for linux-mtd@merlin.infradead.org; Thu, 10 Apr 2014 16:08:41 +0000 Received: from top.free-electrons.com ([176.31.233.9] helo=mail.free-electrons.com) by casper.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WYGDs-0002eW-CN for linux-mtd@lists.infradead.org; Thu, 10 Apr 2014 14:45:01 +0000 Received: by mail.free-electrons.com (Postfix, from userid 106) id 4115C7FC; Thu, 10 Apr 2014 16:44:16 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.3.2 Received: from localhost.localdomain (unknown [190.2.108.71]) by mail.free-electrons.com (Postfix) with ESMTPSA id 74E8C7A0; Thu, 10 Apr 2014 16:44:14 +0200 (CEST) From: Ezequiel Garcia To: Subject: [PATCH] ubiblock: Support UBI volume name or volume ID parameter passing Date: Thu, 10 Apr 2014 11:43:40 -0300 Message-Id: <1397141020-6363-1-git-send-email-ezequiel.garcia@free-electrons.com> X-Mailer: git-send-email 1.9.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140410_154500_461449_99612E18 X-CRM114-Status: GOOD ( 26.47 ) X-Spam-Score: -1.5 (-) X-Spam-Report: SpamAssassin version 3.3.2 on casper.infradead.org summary: Content analysis details: (-1.5 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.7 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) -0.3 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Richard Weinberger , Ezequiel Garcia , Artem Bityutskiy X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org In addition to the previous bevahior, this commit adds support for ubiblock to identify a UBI volume based on the volume name or ID. For example, the following command invocations are possible: $ ubiblock --create=/dev/ubi0_0 - create from UBI volume node $ ubiblock -r /dev/ubi0_0 - remove from UBI volume node $ ubiblock -c /dev/ubi0 -n 99 - create from UBI volume 99 from UBI device $ ubiblock -r /dev/ubi0 -N my_vol - remove from UBI volume named "my_vol" from UBI device The implementation assume there's device node file named as "/dev/ubi${%d}_${%d}", where the first integer is the UBI device number, and the second is the UBI volume ID. This device is not strictly required to exist for a given volume, so the implementation is a "best-effort". For this reason, the open_volume_by_id is implemented here instead of adding it to libubi. Signed-off-by: Ezequiel Garcia --- ubi-utils/ubiblock.c | 165 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 133 insertions(+), 32 deletions(-) diff --git a/ubi-utils/ubiblock.c b/ubi-utils/ubiblock.c index 1e12be8..a599576 100644 --- a/ubi-utils/ubiblock.c +++ b/ubi-utils/ubiblock.c @@ -34,49 +34,118 @@ #include #include "common.h" +enum operation { + UBIBLOCK_NONE, + UBIBLOCK_CREATE, + UBIBLOCK_REMOVE, +}; + struct args { + int vol_id; const char *node; - int create; + const char *name; + enum operation op; }; -static struct args args; +static struct args args = { + .op = UBIBLOCK_NONE, + .vol_id = -1, +}; static const char doc[] = PROGRAM_NAME " version " VERSION " - a tool to create/remove block device interface from UBI volumes."; static const char optionsstr[] = -"-c, --create create block on top of a volume\n" -"-r, --remove remove block from volume\n" -"-h, --help print help message\n" -"-V, --version print program version"; +"-c, --create= create block on top of a volume\n" +"-r, --remove= remove block from volume\n" +"-n, --vol_id= volume ID\n" +"-N, --name= volume name\n" +"-h, --help print help message\n" +"-V, --version print program version"; static const char usage[] = -"Usage: " PROGRAM_NAME " [-c,-r] \n" -"Example: " PROGRAM_NAME " --create /dev/ubi0_0"; +"Usage: " PROGRAM_NAME " [-c,-r] \n" +" [-n ] [--vol_id=]\n" +" [-N ] [--name=] [-h] [--help]\n\n" +"Example: " PROGRAM_NAME " --create=/dev/ubi0_0 - create from UBI volume node\n" +" " PROGRAM_NAME " -c /dev/ubi0 -n 1 - create from UBI volume 1 from UBI device\n" +" " PROGRAM_NAME " -r /dev/ubi0 -N my_vol - remove from UBI volume named \"my_vol\" from UBI device"; static const struct option long_options[] = { { .name = "create", .has_arg = 1, .flag = NULL, .val = 'c' }, { .name = "remove", .has_arg = 1, .flag = NULL, .val = 'r' }, + { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, + { .name = "name", .has_arg = 1, .flag = NULL, .val = 'N' }, { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, { NULL, 0, NULL, 0} }; -static int parse_opt(int argc, char * const argv[]) +static int param_sanity_check(libubi_t libubi) +{ + int err; + + if (args.op == UBIBLOCK_NONE) { + errmsg("please, specify a creation or removal operation"); + return -1; + } + + err = ubi_probe_node(libubi, args.node); + if (err == 2) { + /* UBI volume node, don't need volume ID or name */ + return 0; + } else if (err == 1) { + /* UBI device node, we need volume ID or name */ + ; + } else if (err < 0) { + if (errno == ENODEV) + errmsg("\"%s\" is not an UBI device node", args.node); + else + errmsg("error while probing \"%s\"", args.node); + return -1; + } + + if (args.vol_id == -1 && !args.name) { + errmsg("please, specify either volume ID or volume name"); + return -1; + } + + if (args.vol_id != -1 && args.name) { + errmsg("please, specify either volume ID or volume name, not both"); + return -1; + } + + return 0; +} + +static int parse_opt(libubi_t libubi, int argc, char * const argv[]) { while (1) { - int key; + int key, error = 0; - key = getopt_long(argc, argv, "c:r:h?V", long_options, NULL); + key = getopt_long(argc, argv, "n:N:c:r:h?V", long_options, NULL); if (key == -1) break; switch (key) { case 'c': - args.create = 1; + args.op = UBIBLOCK_CREATE; + args.node = optarg; + break; case 'r': + args.op = UBIBLOCK_REMOVE; args.node = optarg; break; + case 'n': + args.vol_id = simple_strtoul(optarg, &error); + if (error || args.vol_id < 0) { + errmsg("bad volume ID: " "\"%s\"", optarg); + return -1; + } + break; + case 'N': + args.name = optarg; + break; case 'h': case '?': printf("%s\n\n", doc); @@ -94,20 +163,52 @@ static int parse_opt(int argc, char * const argv[]) } } - if (!args.node) - return errmsg("invalid arguments (use -h for help)"); - + if (param_sanity_check(libubi)) + return -1; return 0; } -int main(int argc, char * const argv[]) +static int ubi_open_volume_by_id(libubi_t desc, const char *node, int vol_id, int mode) { + char file[256]; + struct ubi_dev_info dev_info; int err, fd; - libubi_t libubi; - err = parse_opt(argc, argv); + err = ubi_get_dev_info(desc, node, &dev_info); if (err) + return errmsg("cannot get information about UBI device \"%s\"", node); + + sprintf(file, "/dev/ubi%d_%d", dev_info.dev_num, vol_id); + fd = open(file, mode); + if (fd == -1) + errmsg("Failed to open '%s' volume device", file); + return fd; +} + +static int ubi_open_volume_by_name(libubi_t desc, const char *node, const char *name, int mode) +{ + struct ubi_dev_info dev_info; + struct ubi_vol_info vol_info; + int err; + + err = ubi_get_dev_info(desc, node, &dev_info); + if (err) { + errmsg("cannot get information about UBI device \"%s\"", node); + return -1; + } + + err = ubi_get_vol_info1_nm(desc, dev_info.dev_num, name, &vol_info); + if (err) { + errmsg("cannot find UBI volume \"%s\"", name); return -1; + } + return ubi_open_volume_by_id(desc, node, vol_info.vol_id, mode); +} + +int main(int argc, char * const argv[]) +{ + int err, fd; + libubi_t libubi; libubi = libubi_open(); if (!libubi) { @@ -116,26 +217,26 @@ int main(int argc, char * const argv[]) return sys_errmsg("cannot open libubi"); } - err = ubi_probe_node(libubi, args.node); - if (err == 1) { - errmsg("\"%s\" is an UBI device node, not an UBI volume node", - args.node); - goto out_libubi; - } else if (err < 0) { - if (errno == ENODEV) - errmsg("\"%s\" is not an UBI volume node", args.node); - else - sys_errmsg("error while probing \"%s\"", args.node); - goto out_libubi; + err = parse_opt(libubi, argc, argv); + if (err) + return -1; + + if (args.name) { + fd = ubi_open_volume_by_name(libubi, args.node, args.name, O_RDWR); + } else if (args.vol_id != -1) { + fd = ubi_open_volume_by_id(libubi, args.node, args.vol_id, O_RDWR); + } else { + fd = open(args.node, O_RDWR); + if (fd == -1) + errmsg("Failed to open '%s' volume device", args.node); } - fd = open(args.node, O_RDWR); if (fd == -1) { - sys_errmsg("cannot open UBI volume \"%s\"", args.node); + sys_errmsg("cannot open UBI volume device"); goto out_libubi; } - if (args.create) { + if (args.op == UBIBLOCK_CREATE) { err = ubi_vol_block_create(fd); if (err) { if (errno == ENOSYS)