From cca27d4c0819ae244b33639a19bec82cc2895704 Mon Sep 17 00:00:00 2001 From: Richard Titmuss Date: Wed, 18 Feb 2009 10:51:39 +0200 Subject: UBI: add ubirename utility Signed-off-by: Artem Bityutskiy --- ubi-utils/new-utils/Makefile | 2 +- ubi-utils/new-utils/include/libubi.h | 12 +++ ubi-utils/new-utils/src/libubi.c | 21 ++++++ ubi-utils/new-utils/src/ubirename.c | 141 +++++++++++++++++++++++++++++++++++ 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 ubi-utils/new-utils/src/ubirename.c diff --git a/ubi-utils/new-utils/Makefile b/ubi-utils/new-utils/Makefile index 6ae60b3..83751e6 100644 --- a/ubi-utils/new-utils/Makefile +++ b/ubi-utils/new-utils/Makefile @@ -9,7 +9,7 @@ CPPFLAGS += -Iinclude -Isrc -I$(KERNELHDR) LIBS = libubi libmtd libubigen libiniparser libscan TARGETS = ubiupdatevol ubimkvol ubirmvol ubicrc32 ubinfo ubiattach \ - ubidetach ubinize ubiformat + ubidetach ubinize ubiformat ubirename vpath %.c src diff --git a/ubi-utils/new-utils/include/libubi.h b/ubi-utils/new-utils/include/libubi.h index 4308bed..1299e81 100644 --- a/ubi-utils/new-utils/include/libubi.h +++ b/ubi-utils/new-utils/include/libubi.h @@ -264,6 +264,18 @@ int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req); */ int ubi_rmvol(libubi_t desc, const char *node, int vol_id); + +/** + * ubi_rnvols - rename UBI volumes. + * @desc: UBI library descriptor + * @node: name of the UBI character device to remove a volume from + * @rnvol: description of volumes to rename + * + * This function removes volume @vol_id from UBI device @node and returns %0 in + * case of success and %-1 in case of failure. + */ +int ubi_rnvols(libubi_t desc, const char *node, struct ubi_rnvol_req *rnvol); + /** * ubi_rsvol - re-size UBI volume. * @desc: UBI library descriptor diff --git a/ubi-utils/new-utils/src/libubi.c b/ubi-utils/new-utils/src/libubi.c index 88215d0..1aa66d8 100644 --- a/ubi-utils/new-utils/src/libubi.c +++ b/ubi-utils/new-utils/src/libubi.c @@ -947,6 +947,27 @@ out_close: return ret; } +int ubi_rnvols(libubi_t desc, const char *node, struct ubi_rnvol_req *rnvol) +{ + int fd, ret; + + fd = open(node, O_RDONLY); + if (fd == -1) + return -1; + ret = ioctl(fd, UBI_IOCRNVOL, rnvol); + if (ret == -1) + goto out_close; + +#ifdef UDEV_SETTLE_HACK + if (system("udevsettle") == -1) + return -1; +#endif + +out_close: + close(fd); + return ret; +} + int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes) { int fd, ret; diff --git a/ubi-utils/new-utils/src/ubirename.c b/ubi-utils/new-utils/src/ubirename.c new file mode 100644 index 0000000..8f33718 --- /dev/null +++ b/ubi-utils/new-utils/src/ubirename.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2008 Logitech. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * An utility to get rename UBI volumes. + * + * Author: Richard Titmuss + */ + +#include +#include +#include +#include +#include + +#include +#include "common.h" + +#define PROGRAM_VERSION "1.0" +#define PROGRAM_NAME "ubirename" + +static const char *usage = +"Usage: " PROGRAM_NAME " [ |...]\n\n" +"Example: " PROGRAM_NAME "/dev/ubi0 A B C D - rename volume A to B, and C to D\n\n" +"This utility allows re-naming several volumes in one go atomically.\n" +"For example, if you have volumes A and B, then you may rename A into B\n" +"and B into A at one go, and the operation will be atomic. This allows\n" +"implementing atomic UBI volumes upgrades. E.g., if you have volume A\n" +"and want to upgrade it atomically, you create a temporary volume B,\n" +"put your new data to B, then rename A to B and B to A, and then you\n" +"may remove old volume B.\n" +"It is also allowed to re-name multiple volumes at a time, but 16 max.\n" +"renames at once, which means you may specify up to 32 volume names.\n" +"If you have volumes A and B, and re-name A to B, bud do not re-name\n" +"B to something else in the same request, old volume B will be removed\n" +"and A will be renamed into B.\n"; + +static int get_vol_id(libubi_t libubi, struct ubi_dev_info *dev_info, + char *name) +{ + int err, i; + struct ubi_vol_info vol_info; + + for (i=dev_info->lowest_vol_id; i<=dev_info->highest_vol_id; i++) { + err = ubi_get_vol_info1(libubi, dev_info->dev_num, i, &vol_info); + if (err == -1) { + if (errno == ENOENT) + continue; + return -1; + } + + if (strcmp(name, vol_info.name) == 0) + return vol_info.vol_id; + } + + return -1; +} + +int main(int argc, char * const argv[]) +{ + int i, err; + int count = 0; + libubi_t libubi; + struct ubi_dev_info dev_info; + struct ubi_rnvol_req rnvol; + const char *node; + + if (argc < 3 || (argc & 1) == 1) { + errmsg("too few arguments"); + fprintf(stderr, "%s\n", usage); + return -1; + } + + if (argc > UBI_MAX_RNVOL + 2) { + errmsg("too many volumes to re-name, max. is %d", + UBI_MAX_RNVOL); + return -1; + } + + node = argv[1]; + libubi = libubi_open(1); + if (!libubi) + return sys_errmsg("cannot open libubi"); + + err = ubi_node_type(libubi, node); + if (err == 2) { + errmsg("\"%s\" is an UBI volume node, not an UBI device node", + node); + goto out_libubi; + } else if (err < 0) { + errmsg("\"%s\" is not an UBI device node", node); + goto out_libubi; + } + + err = ubi_get_dev_info(libubi, node, &dev_info); + if (err == -1) { + sys_errmsg("cannot get information about UBI device \"%s\"", node); + goto out_libubi; + } + + for (i = 2; i < argc; i += 2) { + err = get_vol_id(libubi, &dev_info, argv[i]); + if (err == -1) { + errmsg("\"%s\" volume not found", argv[i]); + goto out_libubi; + } + + rnvol.ents[count].vol_id = err; + rnvol.ents[count].name_len = strlen(argv[i + 1]); + strcpy(rnvol.ents[count++].name, argv[i + 1]); + } + + rnvol.count = count; + + err = ubi_rnvols(libubi, node, &rnvol); + if (err == -1) { + sys_errmsg("cannot rename volumes"); + goto out_libubi; + } + + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} -- cgit v1.2.3