summaryrefslogtreecommitdiff
path: root/ubi-utils/src
diff options
context:
space:
mode:
authorAdrian Hunter <ext-adrian.hunter@nokia.com>2007-03-21 11:53:25 +0200
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-03-29 17:17:18 +0300
commit9c37b558705b776e51f7d522f376de019a6ea203 (patch)
treea5f7a547feeb817be1b3ed7c9ac362d2344f4bda /ubi-utils/src
parentdb0fa8cfb0fae8c07c4c88f73bbc71176df36d7c (diff)
UBI-Utils: Convert to new ubi library
Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com>
Diffstat (limited to 'ubi-utils/src')
-rw-r--r--ubi-utils/src/libpfiflash.c2
-rw-r--r--ubi-utils/src/libubi.c917
-rw-r--r--ubi-utils/src/libubi_int.h129
-rw-r--r--ubi-utils/src/libubimirror.c10
-rw-r--r--ubi-utils/src/libubiold.c6
-rw-r--r--ubi-utils/src/libubiold_sysfs.c2
-rw-r--r--ubi-utils/src/pddcustomize.c2
-rw-r--r--ubi-utils/src/reader.c13
-rw-r--r--ubi-utils/src/ubimkvol.c33
-rw-r--r--ubi-utils/src/ubirmvol.c24
-rw-r--r--ubi-utils/src/ubiupdatevol.c46
11 files changed, 1129 insertions, 55 deletions
diff --git a/ubi-utils/src/libpfiflash.c b/ubi-utils/src/libpfiflash.c
index 4dfafea..4f1f5cd 100644
--- a/ubi-utils/src/libpfiflash.c
+++ b/ubi-utils/src/libpfiflash.c
@@ -36,7 +36,7 @@
#include <stdlib.h>
#include <sys/ioctl.h>
-#include <libubi.h>
+#include <libubiold.h>
#include <pfiflash.h>
#include <mtd/ubi-user.h> /* FIXME Is this ok here? */
diff --git a/ubi-utils/src/libubi.c b/ubi-utils/src/libubi.c
new file mode 100644
index 0000000..17ab4ee
--- /dev/null
+++ b/ubi-utils/src/libubi.c
@@ -0,0 +1,917 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2006
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Artem B. Bityutskiy
+ *
+ * UBI (Unsorted Block Images) library.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <limits.h>
+#include "libubi.h"
+#include "libubi_int.h"
+
+libubi_t libubi_open(void)
+{
+ int fd, version;
+ struct libubi *lib;
+
+ lib = calloc(1, sizeof(struct libubi));
+ if (!lib)
+ return NULL;
+
+ /* TODO: this must be discovered instead */
+ lib->sysfs = strdup("/sys");
+ if (!lib->sysfs)
+ goto error;
+
+ lib->sysfs_ubi = mkpath(lib->sysfs, SYSFS_UBI);
+ if (!lib->sysfs_ubi)
+ goto error;
+
+ /* Make sure UBI is present */
+ fd = open(lib->sysfs_ubi, O_RDONLY);
+ if (fd == -1)
+ goto error;
+ close(fd);
+
+ lib->ubi_dev = mkpath(lib->sysfs_ubi, UBI_DEV_NAME_PATT);
+ if (!lib->ubi_dev)
+ goto error;
+
+ lib->ubi_version = mkpath(lib->sysfs_ubi, UBI_VER);
+ if (!lib->ubi_version)
+ goto error;
+
+ lib->dev_dev = mkpath(lib->ubi_dev, DEV_DEV);
+ if (!lib->dev_dev)
+ goto error;
+
+ lib->dev_avail_ebs = mkpath(lib->ubi_dev, DEV_AVAIL_EBS);
+ if (!lib->dev_avail_ebs)
+ goto error;
+
+ lib->dev_total_ebs = mkpath(lib->ubi_dev, DEV_TOTAL_EBS);
+ if (!lib->dev_total_ebs)
+ goto error;
+
+ lib->dev_bad_count = mkpath(lib->ubi_dev, DEV_BAD_COUNT);
+ if (!lib->dev_bad_count)
+ goto error;
+
+ lib->dev_eb_size = mkpath(lib->ubi_dev, DEV_EB_SIZE);
+ if (!lib->dev_eb_size)
+ goto error;
+
+ lib->dev_max_ec = mkpath(lib->ubi_dev, DEV_MAX_EC);
+ if (!lib->dev_max_ec)
+ goto error;
+
+ lib->dev_bad_rsvd = mkpath(lib->ubi_dev, DEV_MAX_RSVD);
+ if (!lib->dev_bad_rsvd)
+ goto error;
+
+ lib->dev_max_vols = mkpath(lib->ubi_dev, DEV_MAX_VOLS);
+ if (!lib->dev_max_vols)
+ goto error;
+
+ lib->dev_min_io_size = mkpath(lib->ubi_dev, DEV_MIN_IO_SIZE);
+ if (!lib->dev_min_io_size)
+ goto error;
+
+ lib->ubi_vol = mkpath(lib->sysfs_ubi, UBI_VOL_NAME_PATT);
+ if (!lib->ubi_vol)
+ goto error;
+
+ lib->vol_type = mkpath(lib->ubi_vol, VOL_TYPE);
+ if (!lib->vol_type)
+ goto error;
+
+ lib->vol_dev = mkpath(lib->ubi_vol, VOL_DEV);
+ if (!lib->vol_dev)
+ goto error;
+
+ lib->vol_alignment = mkpath(lib->ubi_vol, VOL_ALIGNMENT);
+ if (!lib->vol_alignment)
+ goto error;
+
+ lib->vol_data_bytes = mkpath(lib->ubi_vol, VOL_DATA_BYTES);
+ if (!lib->vol_data_bytes)
+ goto error;
+
+ lib->vol_rsvd_ebs = mkpath(lib->ubi_vol, VOL_RSVD_EBS);
+ if (!lib->vol_rsvd_ebs)
+ goto error;
+
+ lib->vol_eb_size = mkpath(lib->ubi_vol, VOL_EB_SIZE);
+ if (!lib->vol_eb_size)
+ goto error;
+
+ lib->vol_corrupted = mkpath(lib->ubi_vol, VOL_CORRUPTED);
+ if (!lib->vol_corrupted)
+ goto error;
+
+ lib->vol_name = mkpath(lib->ubi_vol, VOL_NAME);
+ if (!lib->vol_name)
+ goto error;
+
+ if (read_int(lib->ubi_version, &version))
+ goto error;
+ if (version != LIBUBI_UBI_VERSION) {
+ fprintf(stderr, "LIBUBI: this library was made for UBI version "
+ "%d, but UBI version %d is detected\n",
+ LIBUBI_UBI_VERSION, version);
+ goto error;
+ }
+
+ return lib;
+
+error:
+ free(lib->vol_corrupted);
+ free(lib->vol_eb_size);
+ free(lib->vol_rsvd_ebs);
+ free(lib->vol_data_bytes);
+ free(lib->vol_alignment);
+ free(lib->vol_dev);
+ free(lib->vol_type);
+ free(lib->ubi_vol);
+ free(lib->dev_min_io_size);
+ free(lib->dev_max_vols);
+ free(lib->dev_bad_rsvd);
+ free(lib->dev_max_ec);
+ free(lib->dev_eb_size);
+ free(lib->dev_bad_count);
+ free(lib->dev_total_ebs);
+ free(lib->dev_avail_ebs);
+ free(lib->dev_dev);
+ free(lib->ubi_version);
+ free(lib->ubi_dev);
+ free(lib->sysfs_ubi);
+ free(lib->sysfs);
+ free(lib);
+ return NULL;
+}
+
+void libubi_close(libubi_t desc)
+{
+ struct libubi *lib = (struct libubi *)desc;
+
+ free(lib->vol_name);
+ free(lib->vol_corrupted);
+ free(lib->vol_eb_size);
+ free(lib->vol_rsvd_ebs);
+ free(lib->vol_data_bytes);
+ free(lib->vol_alignment);
+ free(lib->vol_dev);
+ free(lib->vol_type);
+ free(lib->ubi_vol);
+ free(lib->dev_min_io_size);
+ free(lib->dev_max_vols);
+ free(lib->dev_bad_rsvd);
+ free(lib->dev_max_ec);
+ free(lib->dev_eb_size);
+ free(lib->dev_bad_count);
+ free(lib->dev_total_ebs);
+ free(lib->dev_avail_ebs);
+ free(lib->dev_dev);
+ free(lib->ubi_version);
+ free(lib->ubi_dev);
+ free(lib->sysfs_ubi);
+ free(lib->sysfs);
+ free(lib);
+}
+
+int ubi_get_info(libubi_t desc, struct ubi_info *info)
+{
+ DIR *sysfs_ubi;
+ struct dirent *dirent;
+ struct libubi *lib = (struct libubi *)desc;
+
+ memset(info, '\0', sizeof(struct ubi_info));
+
+ /*
+ * We have to scan the UBI sysfs directory to identify how many UBI
+ * devices are present.
+ */
+ sysfs_ubi = opendir(lib->sysfs_ubi);
+ if (!sysfs_ubi)
+ return -1;
+
+ info->lowest_dev_num = INT_MAX;
+ while ((dirent = readdir(sysfs_ubi))) {
+ char *name = &dirent->d_name[0];
+ int dev_num, ret;
+
+ ret = sscanf(name, UBI_DEV_NAME_PATT, &dev_num);
+ if (ret == 1) {
+ info->dev_count += 1;
+ if (dev_num > info->highest_dev_num)
+ info->highest_dev_num = dev_num;
+ if (dev_num < info->lowest_dev_num)
+ info->lowest_dev_num = dev_num;
+ }
+ }
+
+ if (info->lowest_dev_num == INT_MAX)
+ info->lowest_dev_num = 0;
+
+ if (read_int(lib->ubi_version, &info->version))
+ goto close;
+
+ return closedir(sysfs_ubi);
+
+close:
+ closedir(sysfs_ubi);
+ return -1;
+}
+
+int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req)
+{
+ int fd, ret;
+ struct ubi_mkvol_req r;
+ size_t n;
+
+ desc = desc;
+ r.vol_id = req->vol_id;
+ r.alignment = req->alignment;
+ r.bytes = req->bytes;
+ r.vol_type = req->vol_type;
+
+ n = strlen(req->name);
+ if (n > UBI_MAX_VOLUME_NAME)
+ return -1;
+
+ strncpy(r.name, req->name, UBI_MAX_VOLUME_NAME + 1);
+ r.name_len = n;
+
+ fd = open(node, O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ ret = ioctl(fd, UBI_IOCMKVOL, &r);
+
+ if (!ret)
+ req->vol_id = r.vol_id;
+
+ close(fd);
+ return ret;
+}
+
+int ubi_rmvol(libubi_t desc, const char *node, int vol_id)
+{
+ int fd, ret;
+
+ desc = desc;
+ fd = open(node, O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ ret = ioctl(fd, UBI_IOCRMVOL, &vol_id);
+ close(fd);
+ return ret;
+}
+
+int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes)
+{
+ int fd, ret;
+ struct ubi_rsvol_req req;
+
+ desc = desc;
+ fd = open(node, O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ req.bytes = bytes;
+ req.vol_id = vol_id;
+
+ ret = ioctl(fd, UBI_IOCRSVOL, &req);
+ close(fd);
+ return ret;
+}
+
+int ubi_update_start(libubi_t desc, int fd, long long bytes)
+{
+ desc = desc;
+ if (ioctl(fd, UBI_IOCVOLUP, &bytes))
+ return -1;
+ return 0;
+}
+
+int ubi_get_dev_info(libubi_t desc, const char *node, struct ubi_dev_info *info)
+{
+ int dev_num;
+ struct libubi *lib = (struct libubi *)desc;
+
+ dev_num = find_dev_num(lib, node);
+ if (dev_num == -1)
+ return -1;
+
+ return ubi_get_dev_info1(desc, dev_num, info);
+}
+
+int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info)
+{
+ DIR *sysfs_ubi;
+ struct dirent *dirent;
+ struct libubi *lib = (struct libubi *)desc;
+
+ memset(info, '\0', sizeof(struct ubi_dev_info));
+ info->dev_num = dev_num;
+
+ sysfs_ubi = opendir(lib->sysfs_ubi);
+ if (!sysfs_ubi)
+ return -1;
+
+ info->lowest_vol_num = INT_MAX;
+ while ((dirent = readdir(sysfs_ubi))) {
+ char *name = &dirent->d_name[0];
+ int vol_id, ret, devno;
+
+ ret = sscanf(name, UBI_VOL_NAME_PATT, &devno, &vol_id);
+ if (ret == 2 && devno == dev_num) {
+ info->vol_count += 1;
+ if (vol_id > info->highest_vol_num)
+ info->highest_vol_num = vol_id;
+ if (vol_id < info->lowest_vol_num)
+ info->lowest_vol_num = vol_id;
+ }
+ }
+
+ closedir(sysfs_ubi);
+
+ if (info->lowest_vol_num == INT_MAX)
+ info->lowest_vol_num = 0;
+
+ if (dev_read_int(lib->dev_avail_ebs, dev_num, &info->avail_ebs))
+ return -1;
+ if (dev_read_int(lib->dev_total_ebs, dev_num, &info->total_ebs))
+ return -1;
+ if (dev_read_int(lib->dev_bad_count, dev_num, &info->bad_count))
+ return -1;
+ if (dev_read_int(lib->dev_eb_size, dev_num, &info->eb_size))
+ return -1;
+ if (dev_read_int(lib->dev_bad_rsvd, dev_num, &info->bad_rsvd))
+ return -1;
+ if (dev_read_ll(lib->dev_max_ec, dev_num, &info->max_ec))
+ return -1;
+ if (dev_read_int(lib->dev_max_vols, dev_num, &info->max_vol_count))
+ return -1;
+ if (dev_read_int(lib->dev_min_io_size, dev_num, &info->min_io_size))
+ return -1;
+
+ info->avail_bytes = info->avail_ebs * info->eb_size;
+ info->total_bytes = info->total_ebs * info->eb_size;
+
+ return 0;
+}
+
+int ubi_get_vol_info(libubi_t desc, const char *node, struct ubi_vol_info *info)
+{
+ int vol_id, dev_num;
+ struct libubi *lib = (struct libubi *)desc;
+
+ dev_num = find_dev_num_vol(lib, node);
+ if (dev_num == -1)
+ return -1;
+
+ vol_id = find_vol_num(lib, dev_num, node);
+ if (vol_id == -1)
+ return -1;
+
+ return ubi_get_vol_info1(desc, dev_num, vol_id, info);
+}
+
+int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id,
+ struct ubi_vol_info *info)
+{
+ int ret;
+ struct libubi *lib = (struct libubi *)desc;
+ char buf[50];
+
+ memset(info, '\0', sizeof(struct ubi_vol_info));
+ info->dev_num = dev_num;
+ info->vol_id = vol_id;
+
+ ret = vol_read_data(lib->vol_type, dev_num, vol_id, &buf[0], 50);
+ if (ret < 0)
+ return -1;
+
+ if (strncmp(&buf[0], "static\n", ret) == 0)
+ info->type = UBI_STATIC_VOLUME;
+ else if (strncmp(&buf[0], "dynamic\n", ret) == 0)
+ info->type = UBI_DYNAMIC_VOLUME;
+ else {
+ fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+ errno = EINVAL;
+ return -1;
+ }
+
+ ret = vol_read_int(lib->vol_alignment, dev_num, vol_id,
+ &info->alignment);
+ if (ret)
+ return -1;
+ ret = vol_read_ll(lib->vol_data_bytes, dev_num, vol_id,
+ &info->data_bytes);
+ if (ret)
+ return -1;
+ ret = vol_read_int(lib->vol_rsvd_ebs, dev_num, vol_id, &info->rsvd_ebs);
+ if (ret)
+ return -1;
+ ret = vol_read_int(lib->vol_eb_size, dev_num, vol_id, &info->eb_size);
+ if (ret)
+ return -1;
+ ret = vol_read_int(lib->vol_corrupted, dev_num, vol_id,
+ &info->corrupted);
+ if (ret)
+ return -1;
+ info->rsvd_bytes = info->eb_size * info->rsvd_ebs;
+
+ ret = vol_read_data(lib->vol_name, dev_num, vol_id, &info->name,
+ UBI_VOL_NAME_MAX + 2);
+ if (ret < 0)
+ return -1;
+
+ info->name[ret - 1] = '\0';
+
+ return 0;
+}
+
+/**
+ * read_int - read an 'int' value from a file.
+ *
+ * @file the file to read from
+ * @value the result is stored here
+ *
+ * This function returns %0 in case of success and %-1 in case of failure.
+ */
+static int read_int(const char *file, int *value)
+{
+ int fd, rd;
+ char buf[50];
+
+ fd = open(file, O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ rd = read(fd, &buf[0], 50);
+ if (rd == -1)
+ goto error;
+
+ if (sscanf(&buf[0], "%d\n", value) != 1) {
+ /* This must be a UBI bug */
+ fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+ errno = EINVAL;
+ goto error;
+ }
+
+ close(fd);
+ return 0;
+
+error:
+ close(fd);
+ return -1;
+}
+
+/**
+ * dev_read_int - read an 'int' value from an UBI device's sysfs file.
+ *
+ * @patt the file pattern to read from
+ * @dev_num UBI device number
+ * @value the result is stored here
+ *
+ * This function returns %0 in case of success and %-1 in case of failure.
+ */
+static int dev_read_int(const char *patt, int dev_num, int *value)
+{
+ int fd, rd;
+ char buf[50];
+ char file[strlen(patt) + 50];
+
+ sprintf(&file[0], patt, dev_num);
+ fd = open(&file[0], O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ rd = read(fd, &buf[0], 50);
+ if (rd == -1)
+ goto error;
+
+ if (sscanf(&buf[0], "%d\n", value) != 1) {
+ /* This must be a UBI bug */
+ fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+ errno = EINVAL;
+ goto error;
+ }
+
+ close(fd);
+ return 0;
+
+error:
+ close(fd);
+ return -1;
+}
+
+/**
+ * dev_read_ll - read a 'long long' value from an UBI device's sysfs file.
+ *
+ * @patt the file pattern to read from
+ * @dev_num UBI device number
+ * @value the result is stored here
+ *
+ * This function returns %0 in case of success and %-1 in case of failure.
+ */
+static int dev_read_ll(const char *patt, int dev_num, long long *value)
+{
+ int fd, rd;
+ char buf[50];
+ char file[strlen(patt) + 50];
+
+ sprintf(&file[0], patt, dev_num);
+ fd = open(&file[0], O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ rd = read(fd, &buf[0], 50);
+ if (rd == -1)
+ goto error;
+
+ if (sscanf(&buf[0], "%lld\n", value) != 1) {
+ /* This must be a UBI bug */
+ fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+ errno = EINVAL;
+ goto error;
+ }
+
+ close(fd);
+ return 0;
+
+error:
+ close(fd);
+ return -1;
+}
+
+/**
+ * dev_read_data - read data from an UBI device's sysfs file.
+ *
+ * @patt the file pattern to read from
+ * @dev_num UBI device number
+ * @buf buffer to read data to
+ * @buf_len buffer length
+ *
+ * This function returns number of read bytes in case of success and %-1 in
+ * case of failure.
+ */
+static int dev_read_data(const char *patt, int dev_num, void *buf, int buf_len)
+{
+ int fd, rd;
+ char file[strlen(patt) + 50];
+
+ sprintf(&file[0], patt, dev_num);
+ fd = open(&file[0], O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ rd = read(fd, buf, buf_len);
+ if (rd == -1) {
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+ return rd;
+}
+
+/**
+ * vol_read_int - read an 'int' value from an UBI volume's sysfs file.
+ *
+ * @patt the file pattern to read from
+ * @dev_num UBI device number
+ * @vol_id volume identifier
+ * @value the result is stored here
+ *
+ * This function returns %0 in case of success and %-1 in case of failure.
+ */
+static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value)
+{
+ int fd, rd;
+ char buf[50];
+ char file[strlen(patt) + 100];
+
+ sprintf(&file[0], patt, dev_num, vol_id);
+ fd = open(&file[0], O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ rd = read(fd, &buf[0], 50);
+ if (rd == -1)
+ goto error;
+
+ if (sscanf(&buf[0], "%d\n", value) != 1) {
+ /* This must be a UBI bug */
+ fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+ errno = EINVAL;
+ goto error;
+ }
+
+ close(fd);
+ return 0;
+
+error:
+ close(fd);
+ return -1;
+}
+
+/**
+ * vol_read_ll - read a 'long long' value from an UBI volume's sysfs file.
+ *
+ * @patt the file pattern to read from
+ * @dev_num UBI device number
+ * @vol_id volume identifier
+ * @value the result is stored here
+ *
+ * This function returns %0 in case of success and %-1 in case of failure.
+ */
+static int vol_read_ll(const char *patt, int dev_num, int vol_id,
+ long long *value)
+{
+ int fd, rd;
+ char buf[50];
+ char file[strlen(patt) + 100];
+
+ sprintf(&file[0], patt, dev_num, vol_id);
+ fd = open(&file[0], O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ rd = read(fd, &buf[0], 50);
+ if (rd == -1)
+ goto error;
+
+ if (sscanf(&buf[0], "%lld\n", value) != 1) {
+ /* This must be a UBI bug */
+ fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+ errno = EINVAL;
+ goto error;
+ }
+
+ close(fd);
+ return 0;
+
+error:
+ close(fd);
+ return -1;
+}
+
+/**
+ * vol_read_data - read data from an UBI volume's sysfs file.
+ *
+ * @patt the file pattern to read from
+ * @dev_num UBI device number
+ * @vol_id volume identifier
+ * @buf buffer to read to
+ * @buf_len buffer length
+ *
+ * This function returns number of read bytes in case of success and %-1 in
+ * case of failure.
+ */
+static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf,
+ int buf_len)
+{
+ int fd, rd;
+ char file[strlen(patt) + 100];
+
+ sprintf(&file[0], patt, dev_num, vol_id);
+ fd = open(&file[0], O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ rd = read(fd, buf, buf_len);
+ if (rd == -1) {
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+ return rd;
+}
+
+/**
+ * mkpath - compose full path from 2 given components.
+ *
+ * @path first component
+ * @name second component
+ *
+ * This function returns the resulting path in case of success and %NULL in
+ * case of failure.
+ */
+static char *mkpath(const char *path, const char *name)
+{
+ char *n;
+ int len1 = strlen(path);
+ int len2 = strlen(name);
+
+ n = malloc(len1 + len2 + 2);
+ if (!n)
+ return NULL;
+
+ memcpy(n, path, len1);
+ if (n[len1 - 1] != '/')
+ n[len1++] = '/';
+
+ memcpy(n + len1, name, len2 + 1);
+ return n;
+}
+
+/**
+ * find_dev_num - find UBI device number by its character device node.
+ *
+ * @lib UBI library descriptor
+ * @node UBI character device node name
+ *
+ * This function returns positive UBI device number in case of success and %-1
+ * in case of failure.
+ */
+static int find_dev_num(struct libubi *lib, const char *node)
+{
+ struct stat stat;
+ struct ubi_info info;
+ int i, major, minor;
+
+ if (lstat(node, &stat))
+ return -1;
+
+ if (!S_ISCHR(stat.st_mode)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ major = major(stat.st_rdev);
+ minor = minor(stat.st_rdev);
+
+ if (minor != 0) {
+ errno = -EINVAL;
+ return -1;
+ }
+
+ if (ubi_get_info((libubi_t *)lib, &info))
+ return -1;
+
+ for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) {
+ int major1, minor1, ret;
+ char buf[50];
+
+ ret = dev_read_data(lib->dev_dev, i, &buf[0], 50);
+ if (ret < 0)
+ return -1;
+
+ ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1);
+ if (ret != 2) {
+ fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (minor1 == minor && major1 == major)
+ return i;
+ }
+
+ errno = ENOENT;
+ return -1;
+}
+
+/**
+ * find_dev_num_vol - find UBI device number by volume character device node.
+ *
+ * @lib UBI library descriptor
+ * @node UBI character device node name
+ *
+ * This function returns positive UBI device number in case of success and %-1
+ * in case of failure.
+ */
+static int find_dev_num_vol(struct libubi *lib, const char *node)
+{
+ struct stat stat;
+ struct ubi_info info;
+ int i, major;
+
+ if (lstat(node, &stat))
+ return -1;
+
+ if (!S_ISCHR(stat.st_mode)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ major = major(stat.st_rdev);
+
+ if (minor(stat.st_rdev) == 0) {
+ errno = -EINVAL;
+ return -1;
+ }
+
+ if (ubi_get_info((libubi_t *)lib, &info))
+ return -1;
+
+ for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) {
+ int major1, minor1, ret;
+ char buf[50];
+
+ ret = dev_read_data(lib->dev_dev, i, &buf[0], 50);
+ if (ret < 0)
+ return -1;
+
+ ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1);
+ if (ret != 2) {
+ fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (major1 == major)
+ return i;
+ }
+
+ errno = ENOENT;
+ return -1;
+}
+
+/**
+ * find_vol_num - find UBI volume number by its character device node.
+ *
+ * @lib UBI library descriptor
+ * @dev_num UBI device number
+ * @node UBI volume character device node name
+ *
+ * This function returns positive UBI volume number in case of success and %-1
+ * in case of failure.
+ */
+static int find_vol_num(struct libubi *lib, int dev_num, const char *node)
+{
+ struct stat stat;
+ struct ubi_dev_info info;
+ int i, major, minor;
+
+ if (lstat(node, &stat))
+ return -1;
+
+ if (!S_ISCHR(stat.st_mode)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ major = major(stat.st_rdev);
+ minor = minor(stat.st_rdev);
+
+ if (minor == 0) {
+ errno = -EINVAL;
+ return -1;
+ }
+
+ if (ubi_get_dev_info1((libubi_t *)lib, dev_num, &info))
+ return -1;
+
+ for (i = info.lowest_vol_num; i <= info.highest_vol_num; i++) {
+ int major1, minor1, ret;
+ char buf[50];
+
+ ret = vol_read_data(lib->vol_dev, dev_num, i, &buf[0], 50);
+ if (ret < 0)
+ return -1;
+
+ ret = sscanf(&buf[0], "%d:%d\n", &major1, &minor1);
+ if (ret != 2) {
+ fprintf(stderr, "LIBUBI: bad value at sysfs file\n");
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (minor1 == minor && major1 == major)
+ return i;
+ }
+
+ errno = ENOENT;
+ return -1;
+}
diff --git a/ubi-utils/src/libubi_int.h b/ubi-utils/src/libubi_int.h
new file mode 100644
index 0000000..e68b791
--- /dev/null
+++ b/ubi-utils/src/libubi_int.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2006
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Artem B. Bityutskiy
+ *
+ * UBI (Unsorted Block Images) library.
+ */
+
+#ifndef __LIBUBI_INT_H__
+#define __LIBUBI_INT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * UBI heavily makes use of the sysfs file system to interact with users-pace.
+ * The below are pre-define UBI file and directory names.
+ */
+
+#define SYSFS_UBI "class/ubi"
+#define UBI_DEV_NAME_PATT "ubi%d"
+#define UBI_VER "version"
+#define DEV_DEV "dev"
+#define UBI_VOL_NAME_PATT "ubi%d_%d"
+#define DEV_AVAIL_EBS "avail_eraseblocks"
+#define DEV_TOTAL_EBS "total_eraseblocks"
+#define DEV_BAD_COUNT "bad_peb_count"
+#define DEV_EB_SIZE "eraseblock_size"
+#define DEV_MAX_EC "max_ec"
+#define DEV_MAX_RSVD "reserved_for_bad"
+#define DEV_MAX_VOLS "max_vol_count"
+#define DEV_MIN_IO_SIZE "min_io_size"
+#define VOL_TYPE "type"
+#define VOL_DEV "dev"
+#define VOL_ALIGNMENT "alignment"
+#define VOL_DATA_BYTES "data_bytes"
+#define VOL_RSVD_EBS "reserved_ebs"
+#define VOL_EB_SIZE "usable_eb_size"
+#define VOL_CORRUPTED "corrupted"
+#define VOL_NAME "name"
+
+/**
+ * libubi - UBI library description data structure.
+ *
+ * @sysfs sysfs file system path
+ * @sysfs_ubi UBI directory in sysfs
+ * @ubi_dev UBI device sysfs directory pattern
+ * @ubi_version UBI version file sysfs path
+ * @dev_dev UBI device's major/minor numbers file pattern
+ * @dev_avail_ebs count of available eraseblocks sysfs path pattern
+ * @dev_total_ebs total eraseblocks count sysfs path pattern
+ * @dev_bad_count count of bad eraseblocks sysfs path pattern
+ * @dev_eb_size size of UBI device's eraseblocks sysfs path pattern
+ * @dev_max_ec maximum erase counter sysfs path pattern
+ * @dev_bad_rsvd count of physical eraseblock reserved for bad eraseblocks
+ * handling
+ * @dev_max_vols maximum volumes number count sysfs path pattern
+ * @dev_min_io_size minimum I/O unit size sysfs path pattern
+ * @ubi_vol UBI volume sysfs directory pattern
+ * @vol_type volume type sysfs path pattern
+ * @vol_dev volume's major/minor numbers file pattern
+ * @vol_alignment volume alignment sysfs path pattern
+ * @vol_data_bytes volume data size sysfs path pattern
+ * @vol_rsvd_ebs volume reserved size sysfs path pattern
+ * @vol_eb_size volume eraseblock size sysfs path pattern
+ * @vol_corrupted volume corruption flag sysfs path pattern
+ * @vol_name volume name sysfs path pattern
+ */
+struct libubi
+{
+ char *sysfs;
+ char *sysfs_ubi;
+ char *ubi_dev;
+ char *ubi_version;
+ char *dev_dev;
+ char *dev_avail_ebs;
+ char *dev_total_ebs;
+ char *dev_bad_count;
+ char *dev_eb_size;
+ char *dev_max_ec;
+ char *dev_bad_rsvd;
+ char *dev_max_vols;
+ char *dev_min_io_size;
+ char *ubi_vol;
+ char *vol_type;
+ char *vol_dev;
+ char *vol_alignment;
+ char *vol_data_bytes;
+ char *vol_rsvd_ebs;
+ char *vol_eb_size;
+ char *vol_corrupted;
+ char *vol_name;
+ char *vol_max_count;
+};
+
+static int read_int(const char *file, int *value);
+static int dev_read_int(const char *patt, int dev_num, int *value);
+static int dev_read_ll(const char *patt, int dev_num, long long *value);
+static int dev_read_data(const char *patt, int dev_num, void *buf, int buf_len);
+static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value);
+static int vol_read_ll(const char *patt, int dev_num, int vol_id,
+ long long *value);
+static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf,
+ int buf_len);
+static char *mkpath(const char *path, const char *name);
+static int find_dev_num(struct libubi *lib, const char *node);
+static int find_dev_num_vol(struct libubi *lib, const char *node);
+static int find_vol_num(struct libubi *lib, int dev_num, const char *node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__LIBUBI_INT_H__ */
diff --git a/ubi-utils/src/libubimirror.c b/ubi-utils/src/libubimirror.c
index e5715fc..d8ea548 100644
--- a/ubi-utils/src/libubimirror.c
+++ b/ubi-utils/src/libubimirror.c
@@ -22,7 +22,7 @@
#include <memory.h>
#include <fcntl.h>
-#include <libubi.h>
+#include <libubiold.h>
#include "ubimirror.h"
#define COMPARE_BUF_SIZE (128 * 1024)
@@ -207,11 +207,11 @@ ubimirror(uint32_t devno, int seqnum, uint32_t *ids, ssize_t ids_size,
fd_out = -1;
}
err:
- if (ulib != NULL)
- ubi_close(&ulib);
- if (fd_in != -1)
- ubi_vol_close(fd_in);
if (fd_out != -1)
ubi_vol_close(fd_out);
+ if (fd_in != -1)
+ ubi_vol_close(fd_in);
+ if (ulib != NULL)
+ ubi_close(&ulib);
return rc;
}
diff --git a/ubi-utils/src/libubiold.c b/ubi-utils/src/libubiold.c
index da4919b..0ff8bae 100644
--- a/ubi-utils/src/libubiold.c
+++ b/ubi-utils/src/libubiold.c
@@ -36,9 +36,9 @@
#include <mtd/ubi-user.h>
#include <mtd/ubi-header.h>
-#include "libubi.h"
-#include "libubi_int.h"
-#include "libubi_sysfs.h"
+#include "libubiold.h"
+#include "libubiold_int.h"
+#include "libubiold_sysfs.h"
/**
* struct ubi_lib - UBI library descriptor.
diff --git a/ubi-utils/src/libubiold_sysfs.c b/ubi-utils/src/libubiold_sysfs.c
index 95fd3de..c4860f6 100644
--- a/ubi-utils/src/libubiold_sysfs.c
+++ b/ubi-utils/src/libubiold_sysfs.c
@@ -33,7 +33,7 @@
#include <stdarg.h>
#include "config.h"
-#include "libubi_int.h"
+#include "libubiold_int.h"
int
sysfs_read_data(const char *file, void *buf, int len)
diff --git a/ubi-utils/src/pddcustomize.c b/ubi-utils/src/pddcustomize.c
index 764f2e7..a86e942 100644
--- a/ubi-utils/src/pddcustomize.c
+++ b/ubi-utils/src/pddcustomize.c
@@ -41,7 +41,7 @@
#include "bootenv.h"
#include "error.h"
#include "example_ubi.h"
-#include "libubi.h"
+#include "libubiold.h"
#include "ubimirror.h"
#define PROGRAM_VERSION "1.4"
diff --git a/ubi-utils/src/reader.c b/ubi-utils/src/reader.c
index 7935a15..0ea8c6d 100644
--- a/ubi-utils/src/reader.c
+++ b/ubi-utils/src/reader.c
@@ -142,6 +142,7 @@ read_pfi_raw(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_raw_t* pfi_raw,
char tmp_str[PFI_KEYWORD_LEN];
bootenv_list_t raw_start_list = NULL;
pfi_raw_t res;
+ size_t size;
res = (pfi_raw_t) malloc(sizeof(struct pfi_raw));
if (!res)
@@ -178,8 +179,9 @@ read_pfi_raw(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_raw_t* pfi_raw,
}
rc = bootenv_list_to_num_vector(raw_start_list,
- (void *) &(res->starts_size),
- &(res->starts));
+ &size, &(res->starts));
+ res->starts_size = size;
+
if (rc != 0) {
EBUF_PFI("Cannot create numeric value array: %s", tmp_str);
goto err;
@@ -209,6 +211,7 @@ read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi,
bootenv_list_t ubi_name_list = NULL;
pfi_ubi_t res;
uint32_t i;
+ size_t size;
res = (pfi_ubi_t) calloc(1, sizeof(struct pfi_ubi));
if (!res)
@@ -247,8 +250,9 @@ read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi,
goto err;
}
- rc = bootenv_list_to_num_vector(ubi_id_list, (void *) &(res->ids_size),
+ rc = bootenv_list_to_num_vector(ubi_id_list, &size,
&(res->ids));
+ res->ids_size = size;
if (rc != 0) {
EBUF_PFI("Cannot create numeric value array: %s", tmp_str);
goto err;
@@ -299,8 +303,9 @@ read_pfi_ubi(pfi_header pfi_hd, FILE* fp_pfi __unused, pfi_ubi_t* pfi_ubi,
EBUF_PFI("Cannot translate PFI value: %s", tmp_str);
goto err;
}
- rc = bootenv_list_to_vector(ubi_name_list, (void *) &(res->names_size),
+ rc = bootenv_list_to_vector(ubi_name_list, &size,
&(tmp_names));
+ res->names_size = size;
if (rc != 0) {
EBUF_PFI("Cannot create string array: %s", tmp_str);
goto err;
diff --git a/ubi-utils/src/ubimkvol.c b/ubi-utils/src/ubimkvol.c
index 879dcb6..1368671 100644
--- a/ubi-utils/src/ubimkvol.c
+++ b/ubi-utils/src/ubimkvol.c
@@ -28,6 +28,7 @@
* 1.2 Reworked the user-interface to use argp.
* 1.3 Removed argp because we want to use uClibc.
* 1.4 Minor cleanups
+ * 1.5 Use a different libubi
*/
#include <stdio.h>
@@ -40,7 +41,7 @@
#include <config.h>
#include <libubi.h>
-#define PROGRAM_VERSION "1.4"
+#define PROGRAM_VERSION "1.5"
/*
* The variables below are set by command line arguments.
@@ -53,6 +54,7 @@ struct args {
int alignment;
char *name;
int nlen;
+ char node[256];
/* special stuff needed to get additional arguments */
char *arg1;
@@ -69,7 +71,7 @@ static struct args myargs = {
.nlen = 0,
};
-static int param_sanity_check(struct args *args, ubi_lib_t lib);
+static int param_sanity_check(struct args *args, libubi_t libubi);
static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\t"
BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n"
@@ -177,6 +179,7 @@ parse_opt(int argc, char **argv, struct args *args)
"\"%s\"\n", optarg);
goto out;
}
+ sprintf(args->node, "/dev/ubi%d", args->devn);
break;
case 'n': /* --volid=<volume id> */
args->vol_id = strtoul(optarg, &endp, 0);
@@ -224,7 +227,7 @@ parse_opt(int argc, char **argv, struct args *args)
return -1;
}
-static int param_sanity_check(struct args *args, ubi_lib_t lib)
+static int param_sanity_check(struct args *args, libubi_t libubi)
{
int err, len;
struct ubi_info ubi;
@@ -239,7 +242,7 @@ static int param_sanity_check(struct args *args, ubi_lib_t lib)
goto out;
}
- err = ubi_get_info(lib, &ubi);
+ err = ubi_get_info(libubi, &ubi);
if (err)
return -1;
@@ -264,7 +267,8 @@ out:
int main(int argc, char * const argv[])
{
int err;
- ubi_lib_t lib;
+ libubi_t libubi;
+ struct ubi_mkvol_request req;
err = parse_opt(argc, (char **)argv, &myargs);
if (err) {
@@ -278,21 +282,26 @@ int main(int argc, char * const argv[])
return -1;
}
- err = ubi_open(&lib);
- if (err) {
+ libubi = libubi_open();
+ if (libubi == NULL) {
perror("Cannot open libubi");
return -1;
}
- err = param_sanity_check(&myargs, lib);
+ err = param_sanity_check(&myargs, libubi);
if (err) {
perror("Input parameters check");
fprintf(stderr, "Use -h option for help\n");
goto out_libubi;
}
- err = ubi_mkvol(lib, myargs.devn, myargs.vol_id, myargs.vol_type,
- myargs.bytes, myargs.alignment, myargs.name);
+ req.vol_id = myargs.vol_id;
+ req.alignment = myargs.alignment;
+ req.bytes = myargs.bytes;
+ req.vol_type = myargs.vol_type;
+ req.name = myargs.name;
+
+ err = ubi_mkvol(libubi, myargs.node, &req);
if (err < 0) {
perror("Cannot create volume");
fprintf(stderr, " err=%d\n", err);
@@ -304,10 +313,10 @@ int main(int argc, char * const argv[])
"dynamic" : "static", name); */
myargs.vol_id = err;
- ubi_close(&lib);
+ libubi_close(libubi);
return 0;
out_libubi:
- ubi_close(&lib);
+ libubi_close(libubi);
return -1;
}
diff --git a/ubi-utils/src/ubirmvol.c b/ubi-utils/src/ubirmvol.c
index f458e8a..f32cbe0 100644
--- a/ubi-utils/src/ubirmvol.c
+++ b/ubi-utils/src/ubirmvol.c
@@ -25,6 +25,7 @@
* 1.1 Reworked the userinterface to use argp.
* 1.2 Removed argp because we want to use uClibc.
* 1.3 Minor cleanups
+ * 1.4 Use a different libubi
*/
#include <stdio.h>
@@ -37,7 +38,7 @@
#include <config.h>
#include <libubi.h>
-#define PROGRAM_VERSION "1.3"
+#define PROGRAM_VERSION "1.4"
/*
* The below variables are set by command line options.
@@ -45,6 +46,7 @@
struct args {
int devn;
int vol_id;
+ char node[256];
/* special stuff needed to get additional arguments */
char *arg1;
@@ -59,7 +61,7 @@ static struct args myargs = {
.options = NULL,
};
-static int param_sanity_check(struct args *args, ubi_lib_t lib);
+static int param_sanity_check(struct args *args, libubi_t libubi);
static char doc[] = "\nVersion: " PROGRAM_VERSION "\n\t"
BUILD_OS" "BUILD_CPU" at "__DATE__" "__TIME__"\n"
@@ -118,6 +120,7 @@ parse_opt(int argc, char **argv, struct args *args)
"\"%s\"\n", optarg);
goto out;
}
+ sprintf(args->node, "/dev/ubi%d", args->devn);
break;
case 'n': /* --volid=<volume id> */
args->vol_id = strtoul(optarg, &endp, 0);
@@ -156,7 +159,7 @@ parse_opt(int argc, char **argv, struct args *args)
return -1;
}
-static int param_sanity_check(struct args *args, ubi_lib_t lib)
+static int param_sanity_check(struct args *args, libubi_t libubi)
{
int err;
struct ubi_info ubi;
@@ -166,7 +169,7 @@ static int param_sanity_check(struct args *args, ubi_lib_t lib)
goto out;
}
- err = ubi_get_info(lib, &ubi);
+ err = ubi_get_info(libubi, &ubi);
if (err)
return -1;
@@ -185,7 +188,7 @@ out:
int main(int argc, char * const argv[])
{
int err, old_errno;
- ubi_lib_t lib;
+ libubi_t libubi;
err = parse_opt(argc, (char **)argv, &myargs);
if (err)
@@ -197,20 +200,20 @@ int main(int argc, char * const argv[])
return -1;
}
- err = ubi_open(&lib);
- if (err) {
+ libubi = libubi_open();
+ if (libubi == NULL) {
perror("Cannot open libubi");
return -1;
}
- err = param_sanity_check(&myargs, lib);
+ err = param_sanity_check(&myargs, libubi);
if (err) {
perror("Input parameters check");
fprintf(stderr, "Use -h option for help\n");
goto out_libubi;
}
- err = ubi_rmvol(lib, myargs.devn, myargs.vol_id);
+ err = ubi_rmvol(libubi, myargs.node, myargs.vol_id);
old_errno = errno;
if (err < 0) {
perror("Cannot remove volume");
@@ -218,9 +221,10 @@ int main(int argc, char * const argv[])
goto out_libubi;
}
+ libubi_close(libubi);
return 0;
out_libubi:
- ubi_close(&lib);
+ libubi_close(libubi);
return -1;
}
diff --git a/ubi-utils/src/ubiupdatevol.c b/ubi-utils/src/ubiupdatevol.c
index c0b4178..5401eb1 100644
--- a/ubi-utils/src/ubiupdatevol.c
+++ b/ubi-utils/src/ubiupdatevol.c
@@ -25,6 +25,7 @@
* 1.0 Reworked the userinterface to use argp.
* 1.1 Removed argp parsing because we want to use uClib.
* 1.2 Minor cleanups
+ * 1.3 Use a different libubi
*/
#include <errno.h>
@@ -36,14 +37,12 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <sys/ioctl.h>
#include <sys/stat.h>
-#include <sys/types.h>
#include <config.h>
#include <libubi.h>
-#define PROGRAM_VERSION "1.2"
+#define PROGRAM_VERSION "1.3"
#define MAXPATH 1024
#define BUFSIZE 128 * 1024
@@ -174,7 +173,7 @@ parse_opt(int argc, char **argv, struct args *args)
* some reason nothing is written. The volume is unusable after this.
*/
static int
-ubi_truncate_volume(struct args *args, int64_t bytes)
+ubi_truncate_volume(struct args *args, int64_t bytes,libubi_t libubi)
{
int rc, ofd;
char path[MAXPATH];
@@ -188,7 +187,7 @@ ubi_truncate_volume(struct args *args, int64_t bytes)
fprintf(stderr, "Cannot open volume %s\n", path);
exit(EXIT_FAILURE);
}
- rc = ioctl(ofd, UBI_IOCVOLUP, &bytes);
+ rc = ubi_update_start(libubi, ofd, bytes);
old_errno = errno;
if (rc < 0) {
perror("UBI volume update ioctl");
@@ -220,7 +219,7 @@ static ssize_t ubi_write(int fd, const void *buf, size_t count)
}
static int
-ubi_update_volume(struct args *args)
+ubi_update_volume(struct args *args, libubi_t libubi)
{
int rc, ofd;
FILE *ifp = NULL;
@@ -263,7 +262,7 @@ ubi_update_volume(struct args *args)
exit(EXIT_FAILURE);
}
- rc = ioctl(ofd, UBI_IOCVOLUP, &bytes);
+ rc = ubi_update_start(libubi, ofd, bytes);
old_errno = errno;
if (rc < 0) {
perror("UBI volume update ioctl");
@@ -304,24 +303,35 @@ int
main(int argc, char *argv[])
{
int rc;
+ libubi_t libubi;
parse_opt(argc, argv, &myargs);
+ libubi = libubi_open();
+ if (libubi == NULL) {
+ perror("Cannot open libubi");
+ return -1;
+ }
+
if (myargs.truncate) {
- rc = ubi_truncate_volume(&myargs, 0LL);
+ rc = ubi_truncate_volume(&myargs, 0LL, libubi);
if (rc < 0)
- exit(EXIT_FAILURE);
- exit(EXIT_SUCCESS);
+ goto out_libubi;
}
- if (myargs.broken_update) {
- rc = ubi_truncate_volume(&myargs, 1LL);
+ else if (myargs.broken_update) {
+ rc = ubi_truncate_volume(&myargs, 1LL, libubi);
if (rc < 0)
- exit(EXIT_FAILURE);
- exit(EXIT_SUCCESS);
+ goto out_libubi;
+ } else {
+ rc = ubi_update_volume(&myargs, libubi);
+ if (rc < 0)
+ goto out_libubi;
}
- rc = ubi_update_volume(&myargs);
- if (rc < 0)
- exit(EXIT_FAILURE);
- exit(EXIT_SUCCESS);
+ libubi_close(libubi);
+ return 0;
+
+out_libubi:
+ libubi_close(libubi);
+ return -1;
}