summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Titmuss <richard_titmuss@eu.logitech.com>2009-02-18 10:51:39 +0200
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-02-18 10:52:57 +0200
commitcca27d4c0819ae244b33639a19bec82cc2895704 (patch)
tree513085e3c1907845543e7a72ba160afbea88e4bd
parent822385dca7fd9816acf6227759ecea6b12f0fce4 (diff)
UBI: add ubirename utility
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
-rw-r--r--ubi-utils/new-utils/Makefile2
-rw-r--r--ubi-utils/new-utils/include/libubi.h12
-rw-r--r--ubi-utils/new-utils/src/libubi.c21
-rw-r--r--ubi-utils/new-utils/src/ubirename.c141
4 files changed, 175 insertions, 1 deletions
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 <stdio.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libubi.h>
+#include "common.h"
+
+#define PROGRAM_VERSION "1.0"
+#define PROGRAM_NAME "ubirename"
+
+static const char *usage =
+"Usage: " PROGRAM_NAME " <UBI device node file name> [<old name> <new 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;
+}