From db0fa8cfb0fae8c07c4c88f73bbc71176df36d7c Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 21 Mar 2007 11:45:07 +0200 Subject: UBI-Utils: Rename old ubi library Signed-off-by: Adrian Hunter --- ubi-utils/inc/libubi.h | 310 ---------------- ubi-utils/inc/libubiold.h | 310 ++++++++++++++++ ubi-utils/src/libubi.c | 768 ---------------------------------------- ubi-utils/src/libubi_int.h | 119 ------- ubi-utils/src/libubi_sysfs.c | 232 ------------ ubi-utils/src/libubi_sysfs.h | 109 ------ ubi-utils/src/libubiold.c | 768 ++++++++++++++++++++++++++++++++++++++++ ubi-utils/src/libubiold_int.h | 119 +++++++ ubi-utils/src/libubiold_sysfs.c | 232 ++++++++++++ ubi-utils/src/libubiold_sysfs.h | 109 ++++++ 10 files changed, 1538 insertions(+), 1538 deletions(-) delete mode 100644 ubi-utils/inc/libubi.h create mode 100644 ubi-utils/inc/libubiold.h delete mode 100644 ubi-utils/src/libubi.c delete mode 100644 ubi-utils/src/libubi_int.h delete mode 100644 ubi-utils/src/libubi_sysfs.c delete mode 100644 ubi-utils/src/libubi_sysfs.h create mode 100644 ubi-utils/src/libubiold.c create mode 100644 ubi-utils/src/libubiold_int.h create mode 100644 ubi-utils/src/libubiold_sysfs.c create mode 100644 ubi-utils/src/libubiold_sysfs.h diff --git a/ubi-utils/inc/libubi.h b/ubi-utils/inc/libubi.h deleted file mode 100644 index f13d812..0000000 --- a/ubi-utils/inc/libubi.h +++ /dev/null @@ -1,310 +0,0 @@ -#ifndef __UBI_H__ -#define __UBI_H__ -/* - * 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. - */ - -/* - * UBI (Unsorted Block Images) library. - * @file libubi.h - * @author Artem B. Bityutskiy - * @author Additions: Oliver Lohmann - * @version 1.0 - */ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @section eh Error Handling - * The following error indication policy is used: in case of success, all - * library functions return 0, in case of failure they either return UBI error - * codes, or -1 if a system error occured; in the latter case the exact error - * code has to be in the errno variable. - * - * @def UBI_ENOTFOUND - * @brief UBI was not found in the system. - * @def UBI_EBUG - * @brief An error due to bug in kernel part of UBI in UBI library. - * @def UBI_EINVAL - * @brief Invalid argument. - * @def UBI_EMACS - * @brief Highest error value. - */ -#define UBI_ENOTFOUND 1 -#define UBI_EBUG 2 -#define UBI_EINVAL 3 -#define UBI_EMAX 4 - - -/** - * UBI library descriptor, vague for library users. - */ -typedef struct ubi_lib *ubi_lib_t; - -/** - * struct ubi_info - general information about UBI. - * - * @version UBI version - * @nlen_max maximum length of names of volumes - * @dev_count count UBI devices in the system - */ -struct ubi_info -{ - unsigned int version; - unsigned int nlen_max; - unsigned int dev_count; -}; - -/** - * struct ubi_dev_info - information about an UBI device - * - * @wear average number of erasures of flash erasable blocks - * @major major number of the corresponding character device - * @minor minor number of the corresponding character device - * @eb_size size of eraseblocks - * @total_ebs total count of eraseblocks - * @avail_ebs count of unused eraseblock available for new volumes - * @vol_count total count of volumes in this UBI device - */ -struct ubi_dev_info -{ - unsigned long long wear; - unsigned int major; - unsigned int minor; - unsigned int eb_size; - unsigned int total_ebs; - unsigned int avail_ebs; - unsigned int vol_count; -}; - -/** - * struct ubi_vol_info - information about an UBI volume - * - * @bytes volume size in bytes - * @eraseblocks volume size in eraseblocks - * @major major number of the corresponding character device - * @minor minor number of the corresponding character device - * @type volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) - * @dev_path device path to volume - * @name volume name - */ -struct ubi_vol_info -{ - unsigned long long bytes; - unsigned int eraseblocks; - unsigned int major; - unsigned int minor; - int type; - char *dev_path; - char *name; -}; - -/** - * ubi_mkvol - create a dynamic UBI volume. - * - * @desc UBI library descriptor - * @devn Number of UBI device to create new volume on - * @vol_id volume ID to assign to the new volume - * @vol_type volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) - * @bytes volume size in bytes - * @alignment volume alignment - * @name volume name - * - * This function creates new UBI volume. If @vol_id is %UBI_VOLN_AUTO, then - * volume number is assigned automatically. This function returns positive - * volume number of the new volume in case of success or %-1 in case of - * failure. - */ -int ubi_mkvol(ubi_lib_t desc, int devn, int vol_id, int vol_type, - long long bytes, int alignment, const char *name); - -/** - * ubi_rmvol - remove a volume. - * - * @desc UBI library descriptor - * @devn Number of UBI device to remove volume from - * @vol_id volume ID to remove - * - * This function returns zero in case of success or %-1 in case of failure. - */ -int ubi_rmvol(ubi_lib_t desc, int devn, int vol_id); - -/** - * ubi_get_info - get UBI information. - * - * @desc UBI library descriptor - * @ubi UBI information is returned here - * - * This function retrieves information about UBI and puts it to @ubi. Returns - * zero in case of success and %-1 in case of failure. - */ -int ubi_get_info(ubi_lib_t desc, struct ubi_info *ubi); - -/** - * ubi_vol_open - open a UBI volume - * - * @desc UBI library descriptor - * @devn Number of UBI device on which to open the volume - * @vol_id Number of UBI device on which to open the volume - * @flags Flags to pass to open() - * - * This function opens a UBI volume on a given UBI device. It returns - * the file descriptor of the opened volume device. In case of an - * error %-1 is returned and errno is set appropriately. - */ -int ubi_vol_open(ubi_lib_t desc, int devn, int vol_id, int flags); - -/** - * ubi_vol_close - close a UBI volume - * - * @vol_fd file descriptor of UBI volume to close - * - * This function closes the given UBI device. - */ -int ubi_vol_close(int vol_fd); - -/** - * ubi_vol_update - initiate volume update on a UBI volume - * @vol_fd File descriptor of UBI volume to update - * @bytes No. of bytes which shall be written. - * - * Initiates a volume update on a given volume. The caller must then - * actually write the appropriate number of bytes to the volume by - * calling write(). Returns 0 on success, else error. - */ -int ubi_vol_update(int vol_fd, unsigned long long bytes); - -/** - * ubi_vol_fopen_read - open a volume for reading, returning a FILE * - * @desc UBI library descriptor - * @devn UBI device number - * @vol_id volume ID to read - * - * Opens a volume for reading. Reading itself can then be performed - * with fread(). The stream can be closed with fclose(). Returns a - * stream on success, else NULL. - */ -FILE * -ubi_vol_fopen_read(ubi_lib_t desc, int devn, uint32_t vol_id); - -/** - * ubi_vol_fopen_update - open a volume for writing, returning a FILE * - * @desc UBI library descriptor - * @devn UBI device number - * @vol_id volume ID to update - * @bytes No. of bytes which shall be written. - * - * Initiates a volume update on a given volume. The caller must then - * actually write the appropriate number of bytes to the volume by - * calling fwrite(). The file can be closed with fclose(). Returns a - * stream on success, else NULL. - */ -FILE * -ubi_vol_fopen_update(ubi_lib_t desc, int devn, uint32_t vol_id, - unsigned long long bytes); - -/** - * ubi_vol_get_used_bytes - determine used bytes in a UBI volume - * @vol_fd File descriptor of UBI volume - * @bytes Pointer to result - * - * Returns 0 on success, else error. - */ -int ubi_vol_get_used_bytes(int vol_fd, unsigned long long *bytes); - -/** - * ubi_open - open UBI library. - * - * @desc A pointer to an UBI library descriptor - * - * Returns zero in case of success. - */ -int ubi_open(ubi_lib_t *desc); - -/** - * ubi_close - close UBI library. - * - * @desc A pointer to an UBI library descriptor - */ -int ubi_close(ubi_lib_t *desc); - - -/** - * ubi_perror - print UBI error. - * - * @prefix a prefix string to prepend to the error message - * @code error code - * - * If @code is %-1, this function calls 'perror()' - */ -void ubi_perror(const char *prefix, int code); - -/** - * ubi_set_cdev_pattern - set 'sprintf()'-like pattern of paths to UBI - * character devices. - * - * @desc UBI library descriptor - * @pattern the pattern to set - * - * The default UBI character device path is "/dev/ubi%u". - */ -int ubi_set_cdev_pattern(ubi_lib_t desc, const char *pattern); - -/** - * ubi_get_dev_info get information about an UBI device. - * - * @desc UBI library descriptor - * @devn UBI device number - * @di the requested information is returned here - */ -int ubi_get_dev_info(ubi_lib_t desc, unsigned int devn, - struct ubi_dev_info *di); - -/** - * ubi_set_vol_cdev_pattern - set 'sprintf()'-like pattµern ofpaths to UBI - * volume character devices. - * - * @desc UBI library descriptor - * @pattern the pattern to set - * - * The default UBI character device path is "/dev/ubi%u_%u". - */ -int ubi_set_vol_cdev_pattern(ubi_lib_t desc, const char *pattern); - -/** - * ubi_get_vol_info - get information about an UBI volume - * - * @desc UBI library descriptor - * @devn UBI device number the volume belongs to - * @vol_id the requested volume number - * @vi volume information is returned here - * - * Users must free the volume name string @vi->name. - */ -int ubi_get_vol_info(ubi_lib_t desc, unsigned int devn, unsigned int vol_id, - struct ubi_vol_info *vi); - -#ifdef __cplusplus -} -#endif - -#endif /* !__UBI_H__ */ diff --git a/ubi-utils/inc/libubiold.h b/ubi-utils/inc/libubiold.h new file mode 100644 index 0000000..f13d812 --- /dev/null +++ b/ubi-utils/inc/libubiold.h @@ -0,0 +1,310 @@ +#ifndef __UBI_H__ +#define __UBI_H__ +/* + * 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. + */ + +/* + * UBI (Unsorted Block Images) library. + * @file libubi.h + * @author Artem B. Bityutskiy + * @author Additions: Oliver Lohmann + * @version 1.0 + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @section eh Error Handling + * The following error indication policy is used: in case of success, all + * library functions return 0, in case of failure they either return UBI error + * codes, or -1 if a system error occured; in the latter case the exact error + * code has to be in the errno variable. + * + * @def UBI_ENOTFOUND + * @brief UBI was not found in the system. + * @def UBI_EBUG + * @brief An error due to bug in kernel part of UBI in UBI library. + * @def UBI_EINVAL + * @brief Invalid argument. + * @def UBI_EMACS + * @brief Highest error value. + */ +#define UBI_ENOTFOUND 1 +#define UBI_EBUG 2 +#define UBI_EINVAL 3 +#define UBI_EMAX 4 + + +/** + * UBI library descriptor, vague for library users. + */ +typedef struct ubi_lib *ubi_lib_t; + +/** + * struct ubi_info - general information about UBI. + * + * @version UBI version + * @nlen_max maximum length of names of volumes + * @dev_count count UBI devices in the system + */ +struct ubi_info +{ + unsigned int version; + unsigned int nlen_max; + unsigned int dev_count; +}; + +/** + * struct ubi_dev_info - information about an UBI device + * + * @wear average number of erasures of flash erasable blocks + * @major major number of the corresponding character device + * @minor minor number of the corresponding character device + * @eb_size size of eraseblocks + * @total_ebs total count of eraseblocks + * @avail_ebs count of unused eraseblock available for new volumes + * @vol_count total count of volumes in this UBI device + */ +struct ubi_dev_info +{ + unsigned long long wear; + unsigned int major; + unsigned int minor; + unsigned int eb_size; + unsigned int total_ebs; + unsigned int avail_ebs; + unsigned int vol_count; +}; + +/** + * struct ubi_vol_info - information about an UBI volume + * + * @bytes volume size in bytes + * @eraseblocks volume size in eraseblocks + * @major major number of the corresponding character device + * @minor minor number of the corresponding character device + * @type volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @dev_path device path to volume + * @name volume name + */ +struct ubi_vol_info +{ + unsigned long long bytes; + unsigned int eraseblocks; + unsigned int major; + unsigned int minor; + int type; + char *dev_path; + char *name; +}; + +/** + * ubi_mkvol - create a dynamic UBI volume. + * + * @desc UBI library descriptor + * @devn Number of UBI device to create new volume on + * @vol_id volume ID to assign to the new volume + * @vol_type volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @bytes volume size in bytes + * @alignment volume alignment + * @name volume name + * + * This function creates new UBI volume. If @vol_id is %UBI_VOLN_AUTO, then + * volume number is assigned automatically. This function returns positive + * volume number of the new volume in case of success or %-1 in case of + * failure. + */ +int ubi_mkvol(ubi_lib_t desc, int devn, int vol_id, int vol_type, + long long bytes, int alignment, const char *name); + +/** + * ubi_rmvol - remove a volume. + * + * @desc UBI library descriptor + * @devn Number of UBI device to remove volume from + * @vol_id volume ID to remove + * + * This function returns zero in case of success or %-1 in case of failure. + */ +int ubi_rmvol(ubi_lib_t desc, int devn, int vol_id); + +/** + * ubi_get_info - get UBI information. + * + * @desc UBI library descriptor + * @ubi UBI information is returned here + * + * This function retrieves information about UBI and puts it to @ubi. Returns + * zero in case of success and %-1 in case of failure. + */ +int ubi_get_info(ubi_lib_t desc, struct ubi_info *ubi); + +/** + * ubi_vol_open - open a UBI volume + * + * @desc UBI library descriptor + * @devn Number of UBI device on which to open the volume + * @vol_id Number of UBI device on which to open the volume + * @flags Flags to pass to open() + * + * This function opens a UBI volume on a given UBI device. It returns + * the file descriptor of the opened volume device. In case of an + * error %-1 is returned and errno is set appropriately. + */ +int ubi_vol_open(ubi_lib_t desc, int devn, int vol_id, int flags); + +/** + * ubi_vol_close - close a UBI volume + * + * @vol_fd file descriptor of UBI volume to close + * + * This function closes the given UBI device. + */ +int ubi_vol_close(int vol_fd); + +/** + * ubi_vol_update - initiate volume update on a UBI volume + * @vol_fd File descriptor of UBI volume to update + * @bytes No. of bytes which shall be written. + * + * Initiates a volume update on a given volume. The caller must then + * actually write the appropriate number of bytes to the volume by + * calling write(). Returns 0 on success, else error. + */ +int ubi_vol_update(int vol_fd, unsigned long long bytes); + +/** + * ubi_vol_fopen_read - open a volume for reading, returning a FILE * + * @desc UBI library descriptor + * @devn UBI device number + * @vol_id volume ID to read + * + * Opens a volume for reading. Reading itself can then be performed + * with fread(). The stream can be closed with fclose(). Returns a + * stream on success, else NULL. + */ +FILE * +ubi_vol_fopen_read(ubi_lib_t desc, int devn, uint32_t vol_id); + +/** + * ubi_vol_fopen_update - open a volume for writing, returning a FILE * + * @desc UBI library descriptor + * @devn UBI device number + * @vol_id volume ID to update + * @bytes No. of bytes which shall be written. + * + * Initiates a volume update on a given volume. The caller must then + * actually write the appropriate number of bytes to the volume by + * calling fwrite(). The file can be closed with fclose(). Returns a + * stream on success, else NULL. + */ +FILE * +ubi_vol_fopen_update(ubi_lib_t desc, int devn, uint32_t vol_id, + unsigned long long bytes); + +/** + * ubi_vol_get_used_bytes - determine used bytes in a UBI volume + * @vol_fd File descriptor of UBI volume + * @bytes Pointer to result + * + * Returns 0 on success, else error. + */ +int ubi_vol_get_used_bytes(int vol_fd, unsigned long long *bytes); + +/** + * ubi_open - open UBI library. + * + * @desc A pointer to an UBI library descriptor + * + * Returns zero in case of success. + */ +int ubi_open(ubi_lib_t *desc); + +/** + * ubi_close - close UBI library. + * + * @desc A pointer to an UBI library descriptor + */ +int ubi_close(ubi_lib_t *desc); + + +/** + * ubi_perror - print UBI error. + * + * @prefix a prefix string to prepend to the error message + * @code error code + * + * If @code is %-1, this function calls 'perror()' + */ +void ubi_perror(const char *prefix, int code); + +/** + * ubi_set_cdev_pattern - set 'sprintf()'-like pattern of paths to UBI + * character devices. + * + * @desc UBI library descriptor + * @pattern the pattern to set + * + * The default UBI character device path is "/dev/ubi%u". + */ +int ubi_set_cdev_pattern(ubi_lib_t desc, const char *pattern); + +/** + * ubi_get_dev_info get information about an UBI device. + * + * @desc UBI library descriptor + * @devn UBI device number + * @di the requested information is returned here + */ +int ubi_get_dev_info(ubi_lib_t desc, unsigned int devn, + struct ubi_dev_info *di); + +/** + * ubi_set_vol_cdev_pattern - set 'sprintf()'-like pattµern ofpaths to UBI + * volume character devices. + * + * @desc UBI library descriptor + * @pattern the pattern to set + * + * The default UBI character device path is "/dev/ubi%u_%u". + */ +int ubi_set_vol_cdev_pattern(ubi_lib_t desc, const char *pattern); + +/** + * ubi_get_vol_info - get information about an UBI volume + * + * @desc UBI library descriptor + * @devn UBI device number the volume belongs to + * @vol_id the requested volume number + * @vi volume information is returned here + * + * Users must free the volume name string @vi->name. + */ +int ubi_get_vol_info(ubi_lib_t desc, unsigned int devn, unsigned int vol_id, + struct ubi_vol_info *vi); + +#ifdef __cplusplus +} +#endif + +#endif /* !__UBI_H__ */ diff --git a/ubi-utils/src/libubi.c b/ubi-utils/src/libubi.c deleted file mode 100644 index da4919b..0000000 --- a/ubi-utils/src/libubi.c +++ /dev/null @@ -1,768 +0,0 @@ -/* - * 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. - */ - -/* - * UBI (Unsorted Block Images) library. - * - * Author: Artem B. Bityutskiy - * Oliver Lohmann - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libubi.h" -#include "libubi_int.h" -#include "libubi_sysfs.h" - -/** - * struct ubi_lib - UBI library descriptor. - * - * @ubi general UBI information - * - * @sysfs_root sysfs root directory - * @ubi_root UBI root directory in sysfs - * - * @version full path to the "UBI version" sysfs file - * - * @cdev_path path pattern to UBI character devices - * @cdev_path_len maximum length of the @cdev_path string after substitution - * @udev_path path to sysfs directories corresponding to UBI devices - * @wear_path path to sysfs file containing UBI wear information - * @vol_count_path path to sysfs file containing the number of volumes in an - * UBI device - * @tot_ebs_path path to sysfs file containing the total number of - * eraseblock on an UBI device - * @avail_ebs_path path to sysfs file containing the number of unused - * eraseblocks on an UBI device, available for new volumes - * @eb_size_path path to sysfs file containing size of UBI eraseblocks - * @nums_path path to sysfs file containing major and minor number of an - * UBI device - * @vol_cdev_path path to UBI volume character devices - * @vdev_path path to sysfs directories corresponding to UBI volume - * devices - * @vol_nums_path path to sysfs file containing major and minor number of an - * UBI volume device - * @vol_bytes_path path to sysfs file containing size of an UBI volume device - * in bytes - * @vol_ebs_path path to sysfs file containing the number of eraseblocks in - * an UBI volume device - * @vol_type_path path to sysfs file containing type of an UBI volume - * @vol_name_path @FIXME: Describe me. - * - * This structure is created and initialized by 'ubi_init()' and is passed to - * all UBI library calls. - */ -struct ubi_lib -{ - struct ubi_info ubi; - - char *sysfs_root; - char *ubi_root; - - char *version; - char *cdev_path; - int cdev_path_len; - char *udev_path; - char *wear_path; - char *vol_count_path; - char *tot_ebs_path; - char *avail_ebs_path; - char *eb_size_path; - char *nums_path; - int vol_cdev_path_len; - char *vol_cdev_path; - char *vdev_path; - char *vol_nums_path; - char *vol_bytes_path; - char *vol_ebs_path; - char *vol_type_path; - char *vol_name_path; -}; - - -/** - * mkpath - compose full path from 2 given components. - * - * @path first component @name second component - * - * Returns the resulting path in case of success and %NULL in case of failure. - * Callers have to take care the resulting path is freed. - */ -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; -} - - -static int -get_ubi_info(ubi_lib_t desc, struct ubi_info *ubi) -{ - int err; - int dev_count = 0; - char *path; - struct stat stat; - - err = sysfs_read_int(desc->version, (int*) &ubi->version); - if (err) - return -1; - - /* Calculate number of UBI devices */ - while (!err) { - char dir[20]; - - sprintf(&dir[0], "ubi%d", dev_count); - path = mkpath(desc->ubi_root, dir); - if (!path) - return ENOMEM; - - err = lstat(path, &stat); - if (err == 0) - dev_count += 1; - free(path); - } - - if (errno != ENOENT) - return -1; - - if (dev_count == 0) { - ubi_err("no UBI devices found"); - errno = EINVAL; - return -1; - } - - errno = 0; - ubi->dev_count = dev_count; - return 0; -} - -void -ubi_dump_handler(ubi_lib_t desc) -{ - ubi_lib_t d = desc; - printf( "UBI Library Descriptor:\n" - "ubi_root: %s\n" - "version: %s\n" - "cdev_path: %s\n" - "udev_path: %s\n" - "wear_path: %s\n" - "vol_count_path: %s\n" - "tot_ebs_path: %s\n" - "avail_ebs_path: %s\n" - "eb_size_path: %s\n" - "nums_path: %s\n" - "vol_cdev_path: %s\n" - "vdev_path: %s\n" - "vol_nums_path: %s\n" - "vol_bytes_path: %s\n" - "vol_ebs_path: %s\n" - "vol_type_path: %s\n" - "vol_name_path: %s\n" - "cdev_path_len: %d\n\n", - d->ubi_root, d->version, d->cdev_path, d->udev_path, - d->wear_path, d->vol_count_path, d->tot_ebs_path, - d->avail_ebs_path, d->eb_size_path, d->nums_path, - d->vol_cdev_path, d->vdev_path, d->vol_nums_path, - d->vol_bytes_path, d->vol_ebs_path, d->vol_type_path, - d->vol_name_path, d->cdev_path_len); -} - -int -ubi_set_cdev_pattern(ubi_lib_t desc, const char *pattern) -{ - char *patt; - - patt = strdup(pattern); - if (!patt) { - ubi_err("cannot allocate memory"); - return -1; - } - - if (desc->cdev_path) - free(desc->cdev_path); - - desc->cdev_path = patt; - desc->cdev_path_len = strlen(patt) + 1 + UBI_MAX_ID_SIZE; - - ubi_dbg("ubi dev pattern is now \"%s\"", patt); - - return 0; -} - -int -ubi_set_vol_cdev_pattern(ubi_lib_t desc, const char *pattern) -{ - char *patt; - - patt = strdup(pattern); - if (!patt) { - ubi_err("cannot allocate memory"); - return -1; - } - - free(desc->vol_cdev_path); - desc->vol_cdev_path = patt; - desc->vol_cdev_path_len = strlen(patt) + 1 + 2 * UBI_MAX_ID_SIZE; - - ubi_dbg("ubi volume dev pattern is now \"%s\"", patt); - - return 0; -} - -int -ubi_open(ubi_lib_t *desc) -{ - int err = -1; - ubi_lib_t res; - struct stat stat; - - res = calloc(1, sizeof(struct ubi_lib)); - if (!res) { - ubi_err("cannot allocate memory"); - return -1; - } - - res->cdev_path = NULL; - err = ubi_set_cdev_pattern(res, UBI_CDEV_PATH); - if (err) - goto error; - - /* TODO: this actually has to be discovered */ - res->sysfs_root = strdup(UBI_SYSFS_ROOT); - if (!res->sysfs_root) - goto error; - - res->ubi_root = mkpath(res->sysfs_root, UBI_ROOT); - if (!res->ubi_root) - goto error; - - res->version = mkpath(res->ubi_root, UBI_VER); - if (!res->version) - goto error; - - res->udev_path = mkpath(res->ubi_root, "ubi%d/"); - if (!res->udev_path) - goto error; - - res->wear_path = mkpath(res->udev_path, UBI_WEAR); - if (!res->wear_path) - goto error; - - res->vol_count_path = mkpath(res->udev_path, UBI_VOL_COUNT); - if (!res->vol_count_path) - goto error; - - res->tot_ebs_path = mkpath(res->udev_path, UBI_AVAIL_EBS); - if (!res->tot_ebs_path) - goto error; - - res->avail_ebs_path = mkpath(res->udev_path, UBI_TOT_EBS); - if (!res->avail_ebs_path) - goto error; - - res->eb_size_path = mkpath(res->udev_path, UBI_EB_SIZE); - if (!res->eb_size_path) - goto error; - - res->nums_path = mkpath(res->udev_path, UBI_NUMS); - if (!res->nums_path) - goto error; - - err = ubi_set_vol_cdev_pattern(res, UBI_VOL_CDEV_PATH); - if (err) - goto error; - - res->vdev_path = mkpath(res->ubi_root, "ubi%d_%d/"); - if (!res->vdev_path) - goto error; - - res->vol_nums_path = mkpath(res->vdev_path, UBI_NUMS); - if (!res->vol_nums_path) - goto error; - - res->vol_bytes_path = mkpath(res->vdev_path, UBI_VBYTES); - if (!res->vol_bytes_path) - goto error; - - res->vol_ebs_path = mkpath(res->vdev_path, UBI_VEBS); - if (!res->vol_ebs_path) - goto error; - - res->vol_type_path = mkpath(res->vdev_path, UBI_VTYPE); - if (!res->vol_type_path) - goto error; - - res->vol_name_path = mkpath(res->vdev_path, UBI_VNAME); - if (!res->vol_name_path) - goto error; - - /* Check if UBI exists in the system */ - err = lstat(res->ubi_root, &stat); - if (err) { - perror("lstat"); - fprintf(stderr, "%s\n", res->ubi_root); - err = UBI_ENOTFOUND; - goto error; - } - - err = get_ubi_info(res, &res->ubi); - if (err) - goto error; - - *desc = res; - - ubi_dbg("opened library successfully."); - - return 0; - -error: - ubi_close(&res); - - if (err == -1 && errno == ENOMEM) - ubi_err("Cannot allocate memory"); - - return err; -} - -int -ubi_close(ubi_lib_t *desc) -{ - ubi_lib_t tmp = *desc; - - free(tmp->vol_name_path); - free(tmp->vol_type_path); - free(tmp->vol_ebs_path); - free(tmp->vol_bytes_path); - free(tmp->vol_nums_path); - free(tmp->vdev_path); - free(tmp->vol_cdev_path); - free(tmp->nums_path); - free(tmp->eb_size_path); - free(tmp->avail_ebs_path); - free(tmp->tot_ebs_path); - free(tmp->vol_count_path); - free(tmp->wear_path); - free(tmp->udev_path); - free(tmp->cdev_path); - free(tmp->version); - free(tmp->ubi_root); - free(tmp->sysfs_root); - free(tmp); - - *desc = NULL; - - return 0; -} - -void -ubi_perror(const char *prefix, int code) -{ - if (code == 0) - return; - - fprintf(stderr, "%s: ", prefix); - - switch (code) { - case UBI_ENOTFOUND: - fprintf(stderr, "UBI was not found in system\n"); - break; - case UBI_EBUG: - fprintf(stderr, "an UBI or UBI library bug\n"); - break; - case UBI_EINVAL: - fprintf(stderr, "invalid parameter\n"); - break; - case -1: - perror(prefix); - break; - default: - ubi_err("unknown error code %d", code); - break; - } -} - -int -ubi_get_dev_info(ubi_lib_t desc, unsigned int devn, struct ubi_dev_info *di) -{ - int err; - - if (devn >= desc->ubi.dev_count) { - ubi_err("bad device number, max is %d\n", - desc->ubi.dev_count - 1); - return UBI_EINVAL; - } - - err = sysfs_read_dev_subst(desc->nums_path, &di->major, - &di->minor, 1, devn); - if (err) - return -1; - - err = sysfs_read_ull_subst(desc->wear_path, &di->wear, 1, devn); - if (err) - return -1; - - err = sysfs_read_uint_subst(desc->vol_count_path, - &di->vol_count, 1, devn); - if (err) - return -1; - - err = sysfs_read_uint_subst(desc->eb_size_path, &di->eb_size, 1, devn); - if (err) - return -1; - - err = sysfs_read_uint_subst(desc->tot_ebs_path, &di->total_ebs, 1, devn); - if (err) - return -1; - - err = sysfs_read_uint_subst(desc->avail_ebs_path, - &di->avail_ebs, 1, devn); - if (err) - return -1; - -#if 0 - ubi_dbg("major:minor %d:%d, wear %llu, EB size %d, " - "vol. count %d, tot. EBs %d, avail. EBs %d", - di->major, di->minor, di->wear, di->eb_size, - di->vol_count, di->total_ebs, di->avail_ebs); -#endif - - return err; -} - -int -ubi_get_vol_info(ubi_lib_t desc, unsigned int devn, unsigned int vol_id, - struct ubi_vol_info *req) -{ - int err; - int len; - char buf1[10]; - char buf2[UBI_MAX_VOLUME_NAME]; - - err = sysfs_read_dev_subst(desc->vol_nums_path, &req->major, - &req->minor, 2, devn, vol_id); - if (err) - return -1; - - err = sysfs_read_ull_subst(desc->vol_bytes_path, - &req->bytes, 2, devn, vol_id); - if (err) - return -1; - - err = sysfs_read_uint_subst(desc->vol_ebs_path, - &req->eraseblocks, 2, devn, vol_id); - if (err) - return -1; - - len = sysfs_read_data_subst(desc->vol_type_path, &buf1[0], - 10, 2, devn, vol_id); - if (len == -1) - return -1; - - if (buf1[len - 1] != '\n') { - ubi_err("bad volume type"); - return UBI_EBUG; - } - - if (!strncmp(&buf1[0], "static", sizeof("static") - 1)) { - req->type = UBI_STATIC_VOLUME; - } else if (!strncmp(&buf1[0], "dynamic", sizeof("dynamic") - 1)) { - req->type = UBI_DYNAMIC_VOLUME; - } else { - ubi_err("bad type %s", &buf1[0]); - return -1; - } - - len = sysfs_read_data_subst(desc->vol_name_path, &buf2[0], - UBI_MAX_VOLUME_NAME, 2, devn, vol_id); - if (len == -1) - return -1; - - if (buf2[len - 1] != '\n') { - ubi_err("bad volume name"); - return UBI_EBUG; - } - - req->name = malloc(len); - if (!req->name) { - ubi_err("cannot allocate memory"); - return -1; - } - - memcpy(req->name, &buf2[0], len - 1); - req->name[len - 1] = '\0'; - - return 0; -} - -/** - * ubi_cdev_open - open a UBI device - * - * @desc UBI library descriptor - * @devn Number of UBI device to open - * @flags Flags to pass to open() - * - * This function opens a UBI device by number and returns a file - * descriptor. In case of an error %-1 is returned and errno is set - * appropriately. - */ -static int -ubi_cdev_open(ubi_lib_t desc, int devn, int flags) -{ - char *buf; - int fd; - - ubi_dbg("desc=%p, devn=%d, flags=%08x\n", desc, devn, flags); - - if (desc == NULL) { - ubi_err("desc is NULL\n"); - return -1; - } - if (desc->vol_cdev_path_len == 0) { - ubi_err("path_len == 0\n"); - return -1; - } - buf = malloc(desc->cdev_path_len); - - sprintf(buf, desc->cdev_path, devn); - - fd = open(buf, flags); - if (fd == -1) - ubi_dbg("cannot open %s", buf); - - free(buf); - return fd; -} - -/** - * ubi_cdev_close - close a UBI device - * - * @dev_fd file descriptor of UBI device to close - * - * This function closes the given UBI device. - */ -static int -ubi_cdev_close(int dev_fd) -{ - return close(dev_fd); -} - -/** - * @size is now in bytes. - */ -int -ubi_mkvol(ubi_lib_t desc, int devn, int vol_id, int vol_type, - long long bytes, int alignment, const char *name) -{ - int fd; - int err; - struct ubi_mkvol_req req; - size_t n; - - n = strlen(name); - if (n > UBI_MAX_VOLUME_NAME) - return -1; - - if ((fd = ubi_cdev_open(desc, devn, O_RDWR)) == -1) - return -1; - - req.vol_id = vol_id; - req.bytes = bytes; - req.vol_type = vol_type; - req.alignment = alignment; - - strncpy(req.name, name, UBI_MAX_VOLUME_NAME + 1); - req.name_len = n; - - /* printf("DBG: %s(vol_id=%d, bytes=%lld, type=%d, alig=%d, nlen=%d, " - "name=%s)\n", __func__, vol_id, bytes, vol_type, alignment, - strlen(name), name);*/ - - err = ioctl(fd, UBI_IOCMKVOL, &req); - if (err < 0) { - ubi_err("ioctl returned %d errno=%d\n", err, errno); - goto out_close; - } - - ubi_dbg("created volume %d, size %lld, name \"%s\" " - "at UBI dev %d\n", vol_id, bytes, name, devn); - - close(fd); - return err; - out_close: - ubi_cdev_close(fd); - return err; -} - -int -ubi_rmvol(ubi_lib_t desc, int devn, int vol_id) -{ - int fd; - int err; - - if ((fd = ubi_cdev_open(desc, devn, O_RDWR)) == -1) - return -1; - - err = ioctl(fd, UBI_IOCRMVOL, &vol_id); - if (err < 0) - goto out_close; - - ubi_dbg("removed volume %d", vol_id); - - out_close: - ubi_cdev_close(fd); - return err; -} - -int -ubi_get_info(ubi_lib_t desc, struct ubi_info *ubi) -{ - memcpy(ubi, &desc->ubi, sizeof(struct ubi_info)); - return 0; -} - - -int -ubi_vol_open(ubi_lib_t desc, int devn, int vol_id, int flags) -{ - char *buf; - int fd; - - ubi_dbg("desc=%p, devn=%d, vol_id=%d, flags=%08x\n", - desc, devn, vol_id, flags); - - if (desc == NULL) { - ubi_err("desc is NULL\n"); - return -1; - } - if (desc->vol_cdev_path_len == 0) { - ubi_err("path_len == 0\n"); - return -1; - } - buf = malloc(desc->cdev_path_len); - - sprintf(buf, desc->vol_cdev_path, devn, vol_id); - - fd = open(buf, flags); - if (fd == -1) - ubi_dbg("cannot open %s", buf); - - free(buf); - return fd; -} - -int -ubi_vol_close(int vol_fd) -{ - return close(vol_fd); -} - - -int -ubi_vol_update(int vol_fd, unsigned long long bytes) -{ - int err; - - err = ioctl(vol_fd, UBI_IOCVOLUP, &bytes); - if (err) { - ubi_err("%s failure calling update ioctl\n" - " IOCTL(%08lx) err=%d errno=%d\n", - __func__, (long unsigned int)UBI_IOCVOLUP, err, errno); - } - return err; -} - -FILE * -ubi_vol_fopen_read(ubi_lib_t desc, int devn, uint32_t vol_id) -{ - FILE *fp; - int fd; - - fd = ubi_vol_open(desc, devn, vol_id, O_RDONLY); - if (fd == -1) - return NULL; - - fp = fdopen(fd, "r"); - if (fp == NULL) - ubi_vol_close(fd); - - return fp; -} - -FILE * -ubi_vol_fopen_update(ubi_lib_t desc, int devn, uint32_t vol_id, - unsigned long long bytes) -{ - FILE *fp; - int fd; - int err; - - fd = ubi_vol_open(desc, devn, vol_id, O_RDWR); - if (fd == -1) - return NULL; - - fp = fdopen(fd, "r+"); - if (fp == NULL) { - printf("DBG: %s(errno=%d)\n", __func__, errno); - ubi_vol_close(fd); - return NULL; - } - err = ubi_vol_update(fd, bytes); - if (err < 0) { - printf("DBG: %s() fd=%d err=%d\n", __func__, fd, err); - fclose(fp); - return NULL; - } - return fp; -} - -int -ubi_vol_get_used_bytes(int vol_fd, unsigned long long *bytes) -{ - off_t res; - - res = lseek(vol_fd, 0, SEEK_END); - if (res == (off_t)-1) - return -1; - *bytes = (unsigned long long) res; - res = lseek(vol_fd, 0, SEEK_SET); - return res == (off_t)-1 ? -1 : 0; -} diff --git a/ubi-utils/src/libubi_int.h b/ubi-utils/src/libubi_int.h deleted file mode 100644 index 830a682..0000000 --- a/ubi-utils/src/libubi_int.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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. - */ - -/* - * UBI (Unsorted Block Images) library. - * - * Author: Artem B. Bityutskiy - */ - -#ifndef __UBI_INT_H__ -#define __UBI_INT_H__ -/* - * Enable/disable UBI library debugging messages. - */ -#undef UBILIB_DEBUG - -/* - * UBI library error message. - */ -#define ubi_err(fmt, ...) do { \ - fprintf(stderr, "UBI Library Error at %s: ", __func__); \ - fprintf(stderr, fmt, ##__VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } while (0) - -#ifdef UBILIB_DEBUG -#define ubi_dbg(fmt, ...) do { \ - fprintf(stderr, "UBI Debug: %s: ", __func__); \ - fprintf(stderr, fmt, ##__VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } while (0) - -#else -#define ubi_dbg(fmt, ...) do { } while (0) -#endif - -/** - * SYSFS Entries. - * - * @def UBI_ROOT - * @brief Name of the root UBI directory in sysfs. - * - * @def UBI_NLEN_MAX - * @brief Name of syfs file containing the maximum UBI volume name length. - * - * @def UBI_VER - * @brief Name of sysfs file containing UBI version. - * - * @def UBI_WEAR - * @brief Name of sysfs file containing wear level of an UBI device. - * - * @def UBI_VOL_COUNT - * @brief Name of sysfs file contaning the of volume on an UBI device - * - * @def UBI_TOT_EBS - * @brief Name of sysfs file contaning the total number of - * eraseblocks on an UBI device. - * - * @def UBI_AVAIL_EBS - * @brief Name of sysfs file contaning the number of unused eraseblocks on - * an UBI device. - * - * @def UBI_EB_SIZE - * @brief Name of sysfs file containing size of UBI eraseblocks. - * - * @def UBI_NUMS - * @brief Name of sysfs file containing major and minor numbers - * of an UBI device or an UBI volume device. - * - * @def UBI_VBYTES - * @brief Name of sysfs file containing size of an UBI volume device in - * bytes. - * - * @def UBI_VEBS - * @brief Name of sysfs file containing size of an UBI volume device in - * eraseblocks. - * - * @def UBI_VTYPE - * @brief Name of sysfs file containing type of an UBI volume device. - * - * @def UBI_VNAME - * @brief Name of sysfs file containing name of an UBI volume device. - **/ -#define UBI_ROOT "ubi" -#define UBI_NLEN_MAX "volume_name_max" -#define UBI_VER "version" -#define UBI_WEAR "wear" -#define UBI_VOL_COUNT "volumes_count" -#define UBI_TOT_EBS "total_eraseblocks" -#define UBI_AVAIL_EBS "avail_eraseblocks" -#define UBI_EB_SIZE "eraseblock_size" -#define UBI_NUMS "dev" -#define UBI_VBYTES "bytes" -#define UBI_VEBS "eraseblocks" -#define UBI_VTYPE "type" -#define UBI_VNAME "name" - -#define UBI_CDEV_PATH "/dev/ubi%d" -#define UBI_VOL_CDEV_PATH "/dev/ubi%d_%d" -#define UBI_SYSFS_ROOT "/sys/class" - -#define UBI_MAX_ID_SIZE 9 - -#endif /* !__UBI_INT_H__ */ diff --git a/ubi-utils/src/libubi_sysfs.c b/ubi-utils/src/libubi_sysfs.c deleted file mode 100644 index 95fd3de..0000000 --- a/ubi-utils/src/libubi_sysfs.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * 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. - */ - -/* - * UBI (Unsorted Block Images) library. - * - * Author: Artem B. Bityutskiy - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "libubi_int.h" - -int -sysfs_read_data(const char *file, void *buf, int len) -{ - int fd; - ssize_t rd; - - fd = open(file, O_RDONLY); - if (fd == -1) { - ubi_err("cannot open file %s", file); - return -1; - } - - rd = read(fd, buf, len); - if (rd == -1) - ubi_err("cannot read file %s", file); - - close(fd); - - return rd; -} - -int -sysfs_read_data_subst(const char *patt, void *buf, int len, int n, ...) -{ - va_list args; - char buf1[strlen(patt) + 20 * n]; - - va_start(args, n); - vsprintf(&buf1[0], patt, args); - va_end(args); - - return sysfs_read_data(&buf1[0], buf, len); -} - -int -sysfs_read_dev(const char *file, unsigned int *major, unsigned int *minor) -{ - int fd; - int ret; - ssize_t rd; - int err = -1; - char buf[40]; - - fd = open(file, O_RDONLY); - if (fd == -1) { - ubi_err("cannot open file %s", file); - return -1; - } - - rd = read(fd, &buf[0], 20); - if (rd == -1) { - ubi_err("cannot read file %s", file); - goto error; - } - if (rd < 4) { - ubi_err("bad contents of file %s:", file); - goto error; - } - - err = -1; - if (buf[rd -1] != '\n') { - ubi_err("bad contents of file %s", file); - goto error; - } - - ret = sscanf(&buf[0], "%d:%d\n", major, minor); - if (ret != 2) { - ubi_err("bad contents of file %s", file); - goto error; - } - - err = 0; - -error: - close(fd); - - return err; -} - -int -sysfs_read_dev_subst(const char *patt, unsigned int *major, - unsigned int *minor, int n, ...) -{ - va_list args; - char buf[strlen(patt) + 20 * n]; - - va_start(args, n); - vsprintf(&buf[0], patt, args); - va_end(args); - - return sysfs_read_dev(&buf[0], major, minor); -} - -static int -sysfs_read_ull(const char *file __unused, unsigned long long *num __unused) -{ - return 0; -} - -int -sysfs_read_ull_subst(const char *patt, unsigned long long *num, int n, ...) -{ - va_list args; - char buf[strlen(patt) + 20 * n]; - - va_start(args, n); - vsprintf(&buf[0], patt, args); - va_end(args); - - return sysfs_read_ull(&buf[0], num); -} - -static int -sysfs_read_uint(const char *file __unused, unsigned int *num __unused) -{ - return 0; -} - -int -sysfs_read_uint_subst(const char *patt, unsigned int *num, int n, ...) -{ - va_list args; - char buf[strlen(patt) + 20 * n]; - - va_start(args, n); - vsprintf(&buf[0], patt, args); - va_end(args); - - return sysfs_read_uint(&buf[0], num); -} - -int -sysfs_read_ll(const char *file, long long *num) -{ - int fd; - ssize_t rd; - int err = -1; - char buf[20]; - char *endptr; - - fd = open(file, O_RDONLY); - if (fd == -1) - return -1; - - rd = read(fd, &buf[0], 20); - if (rd == -1) - goto out; - - if (rd < 2) { - ubi_err("bad contents in file %s: \"%c%c...\"", - file, buf[0], buf[1]); - goto out_errno; - } - - *num = strtoll(&buf[0], &endptr, 10); - if (endptr == &buf[0] || *endptr != '\n') { - ubi_err("bad contents in file %s: \"%c%c...\"", - file, buf[0], buf[1]); - goto out_errno; - } - - if (*num < 0) { - ubi_err("bad number in file %s: %lld", file, *num); - goto out_errno; - } - - err = 0; - -out_errno: - errno = EINVAL; - -out: - close(fd); - return err; -} - -int -sysfs_read_int(const char *file, int *num) -{ - int err; - long long res = 0; - - err = sysfs_read_ll(file, &res); - if (err) - return err; - - if (res < 0 || res > INT_MAX) { - ubi_err("bad number in file %s: %lld", file, res); - errno = EINVAL; - return -1; - } - - *num = res; - return 0; -} diff --git a/ubi-utils/src/libubi_sysfs.h b/ubi-utils/src/libubi_sysfs.h deleted file mode 100644 index 2fb6072..0000000 --- a/ubi-utils/src/libubi_sysfs.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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. - */ - -/* - * UBI (Unsorted Block Images) library. - * - * Author: Artem B. Bityutskiy - */ - -/** - * sysfs_read_data - read data from a sysfs file. - * - * @file path to the file to read from - * @buf furrer where to store read data - * @len length of provided buffer @buf - * - * This function returns the number of read bytes or -1 in case of error. - */ -int sysfs_read_data(const char *file, void *buf, int len); - -/** - * sysfs_read_data_subst - form path to a sysfs file and read data from it. - * - * @patt path to the file to read from - * @buf furrer where to store read data - * @len length of provided buffer @buf - * @n number of parameters to substitute to @patt - * - * This function forms path to a sysfs file by means of substituting parameters - * to @patt and then reads @len bytes from this file and stores the read data - * to @buf. This function returns the number of read bytes or -1 in case of - * error. - */ -int sysfs_read_data_subst(const char *patt, void *buf, int len, int n, ...); - -/** - * sysfs_read_dev - read major and minor number from a sysfs file. - * - * @file path to the file to read from - * @major major number is returned here - * @minor minor number is returned here - */ -int sysfs_read_dev(const char *file, unsigned int *major, - unsigned int *minor); -/** - * sysfs_read_dev_subst - for path to a file and read major and minor number - * from it. - * - * @patt pattern of the path to the file to read from - * @major major number is returned here - * @minor minor number is returned here - * @n number of arguments to substitute - * - * This function substitures arguments to the @patt file path pattern and reads - * major and minor numbers from the resulting file. - */ -int sysfs_read_dev_subst(const char *patt, unsigned int *major, - unsigned int *minor, int n, ...); - -/** - * sysfs_read_ull_subst - form path to a sysfs file and read an unsigned long - * long value from there. - * - * @patt pattern of file path - * @num the read value is returned here - * @n number of parameters to substitute - * - * - * This function first forms the path to a sysfs file by means of substituting - * passed parameters to the @patt string, and then read an 'unsigned long long' - * value from this file. - */ -int sysfs_read_ull_subst(const char *patt, unsigned long long *num, - int n, ...); - -/** - * sysfs_read_uint_subst - the same as 'sysfs_read_uint_subst()' but reads an - * unsigned int value. - */ -int sysfs_read_uint_subst(const char *patt, unsigned int *num, - int n, ...); - -/** - * sysfs_read_ll - read a long long integer from an UBI sysfs file. - * - * @file file name from where to read - * @num the result is returned here - */ -int sysfs_read_ll(const char *file, long long *num); - -/** - * sysfs_read_int - the same as 'sysfs_read_ll()' but reads an 'int' value. - */ -int sysfs_read_int(const char *file, int *num); diff --git a/ubi-utils/src/libubiold.c b/ubi-utils/src/libubiold.c new file mode 100644 index 0000000..da4919b --- /dev/null +++ b/ubi-utils/src/libubiold.c @@ -0,0 +1,768 @@ +/* + * 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. + */ + +/* + * UBI (Unsorted Block Images) library. + * + * Author: Artem B. Bityutskiy + * Oliver Lohmann + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libubi.h" +#include "libubi_int.h" +#include "libubi_sysfs.h" + +/** + * struct ubi_lib - UBI library descriptor. + * + * @ubi general UBI information + * + * @sysfs_root sysfs root directory + * @ubi_root UBI root directory in sysfs + * + * @version full path to the "UBI version" sysfs file + * + * @cdev_path path pattern to UBI character devices + * @cdev_path_len maximum length of the @cdev_path string after substitution + * @udev_path path to sysfs directories corresponding to UBI devices + * @wear_path path to sysfs file containing UBI wear information + * @vol_count_path path to sysfs file containing the number of volumes in an + * UBI device + * @tot_ebs_path path to sysfs file containing the total number of + * eraseblock on an UBI device + * @avail_ebs_path path to sysfs file containing the number of unused + * eraseblocks on an UBI device, available for new volumes + * @eb_size_path path to sysfs file containing size of UBI eraseblocks + * @nums_path path to sysfs file containing major and minor number of an + * UBI device + * @vol_cdev_path path to UBI volume character devices + * @vdev_path path to sysfs directories corresponding to UBI volume + * devices + * @vol_nums_path path to sysfs file containing major and minor number of an + * UBI volume device + * @vol_bytes_path path to sysfs file containing size of an UBI volume device + * in bytes + * @vol_ebs_path path to sysfs file containing the number of eraseblocks in + * an UBI volume device + * @vol_type_path path to sysfs file containing type of an UBI volume + * @vol_name_path @FIXME: Describe me. + * + * This structure is created and initialized by 'ubi_init()' and is passed to + * all UBI library calls. + */ +struct ubi_lib +{ + struct ubi_info ubi; + + char *sysfs_root; + char *ubi_root; + + char *version; + char *cdev_path; + int cdev_path_len; + char *udev_path; + char *wear_path; + char *vol_count_path; + char *tot_ebs_path; + char *avail_ebs_path; + char *eb_size_path; + char *nums_path; + int vol_cdev_path_len; + char *vol_cdev_path; + char *vdev_path; + char *vol_nums_path; + char *vol_bytes_path; + char *vol_ebs_path; + char *vol_type_path; + char *vol_name_path; +}; + + +/** + * mkpath - compose full path from 2 given components. + * + * @path first component @name second component + * + * Returns the resulting path in case of success and %NULL in case of failure. + * Callers have to take care the resulting path is freed. + */ +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; +} + + +static int +get_ubi_info(ubi_lib_t desc, struct ubi_info *ubi) +{ + int err; + int dev_count = 0; + char *path; + struct stat stat; + + err = sysfs_read_int(desc->version, (int*) &ubi->version); + if (err) + return -1; + + /* Calculate number of UBI devices */ + while (!err) { + char dir[20]; + + sprintf(&dir[0], "ubi%d", dev_count); + path = mkpath(desc->ubi_root, dir); + if (!path) + return ENOMEM; + + err = lstat(path, &stat); + if (err == 0) + dev_count += 1; + free(path); + } + + if (errno != ENOENT) + return -1; + + if (dev_count == 0) { + ubi_err("no UBI devices found"); + errno = EINVAL; + return -1; + } + + errno = 0; + ubi->dev_count = dev_count; + return 0; +} + +void +ubi_dump_handler(ubi_lib_t desc) +{ + ubi_lib_t d = desc; + printf( "UBI Library Descriptor:\n" + "ubi_root: %s\n" + "version: %s\n" + "cdev_path: %s\n" + "udev_path: %s\n" + "wear_path: %s\n" + "vol_count_path: %s\n" + "tot_ebs_path: %s\n" + "avail_ebs_path: %s\n" + "eb_size_path: %s\n" + "nums_path: %s\n" + "vol_cdev_path: %s\n" + "vdev_path: %s\n" + "vol_nums_path: %s\n" + "vol_bytes_path: %s\n" + "vol_ebs_path: %s\n" + "vol_type_path: %s\n" + "vol_name_path: %s\n" + "cdev_path_len: %d\n\n", + d->ubi_root, d->version, d->cdev_path, d->udev_path, + d->wear_path, d->vol_count_path, d->tot_ebs_path, + d->avail_ebs_path, d->eb_size_path, d->nums_path, + d->vol_cdev_path, d->vdev_path, d->vol_nums_path, + d->vol_bytes_path, d->vol_ebs_path, d->vol_type_path, + d->vol_name_path, d->cdev_path_len); +} + +int +ubi_set_cdev_pattern(ubi_lib_t desc, const char *pattern) +{ + char *patt; + + patt = strdup(pattern); + if (!patt) { + ubi_err("cannot allocate memory"); + return -1; + } + + if (desc->cdev_path) + free(desc->cdev_path); + + desc->cdev_path = patt; + desc->cdev_path_len = strlen(patt) + 1 + UBI_MAX_ID_SIZE; + + ubi_dbg("ubi dev pattern is now \"%s\"", patt); + + return 0; +} + +int +ubi_set_vol_cdev_pattern(ubi_lib_t desc, const char *pattern) +{ + char *patt; + + patt = strdup(pattern); + if (!patt) { + ubi_err("cannot allocate memory"); + return -1; + } + + free(desc->vol_cdev_path); + desc->vol_cdev_path = patt; + desc->vol_cdev_path_len = strlen(patt) + 1 + 2 * UBI_MAX_ID_SIZE; + + ubi_dbg("ubi volume dev pattern is now \"%s\"", patt); + + return 0; +} + +int +ubi_open(ubi_lib_t *desc) +{ + int err = -1; + ubi_lib_t res; + struct stat stat; + + res = calloc(1, sizeof(struct ubi_lib)); + if (!res) { + ubi_err("cannot allocate memory"); + return -1; + } + + res->cdev_path = NULL; + err = ubi_set_cdev_pattern(res, UBI_CDEV_PATH); + if (err) + goto error; + + /* TODO: this actually has to be discovered */ + res->sysfs_root = strdup(UBI_SYSFS_ROOT); + if (!res->sysfs_root) + goto error; + + res->ubi_root = mkpath(res->sysfs_root, UBI_ROOT); + if (!res->ubi_root) + goto error; + + res->version = mkpath(res->ubi_root, UBI_VER); + if (!res->version) + goto error; + + res->udev_path = mkpath(res->ubi_root, "ubi%d/"); + if (!res->udev_path) + goto error; + + res->wear_path = mkpath(res->udev_path, UBI_WEAR); + if (!res->wear_path) + goto error; + + res->vol_count_path = mkpath(res->udev_path, UBI_VOL_COUNT); + if (!res->vol_count_path) + goto error; + + res->tot_ebs_path = mkpath(res->udev_path, UBI_AVAIL_EBS); + if (!res->tot_ebs_path) + goto error; + + res->avail_ebs_path = mkpath(res->udev_path, UBI_TOT_EBS); + if (!res->avail_ebs_path) + goto error; + + res->eb_size_path = mkpath(res->udev_path, UBI_EB_SIZE); + if (!res->eb_size_path) + goto error; + + res->nums_path = mkpath(res->udev_path, UBI_NUMS); + if (!res->nums_path) + goto error; + + err = ubi_set_vol_cdev_pattern(res, UBI_VOL_CDEV_PATH); + if (err) + goto error; + + res->vdev_path = mkpath(res->ubi_root, "ubi%d_%d/"); + if (!res->vdev_path) + goto error; + + res->vol_nums_path = mkpath(res->vdev_path, UBI_NUMS); + if (!res->vol_nums_path) + goto error; + + res->vol_bytes_path = mkpath(res->vdev_path, UBI_VBYTES); + if (!res->vol_bytes_path) + goto error; + + res->vol_ebs_path = mkpath(res->vdev_path, UBI_VEBS); + if (!res->vol_ebs_path) + goto error; + + res->vol_type_path = mkpath(res->vdev_path, UBI_VTYPE); + if (!res->vol_type_path) + goto error; + + res->vol_name_path = mkpath(res->vdev_path, UBI_VNAME); + if (!res->vol_name_path) + goto error; + + /* Check if UBI exists in the system */ + err = lstat(res->ubi_root, &stat); + if (err) { + perror("lstat"); + fprintf(stderr, "%s\n", res->ubi_root); + err = UBI_ENOTFOUND; + goto error; + } + + err = get_ubi_info(res, &res->ubi); + if (err) + goto error; + + *desc = res; + + ubi_dbg("opened library successfully."); + + return 0; + +error: + ubi_close(&res); + + if (err == -1 && errno == ENOMEM) + ubi_err("Cannot allocate memory"); + + return err; +} + +int +ubi_close(ubi_lib_t *desc) +{ + ubi_lib_t tmp = *desc; + + free(tmp->vol_name_path); + free(tmp->vol_type_path); + free(tmp->vol_ebs_path); + free(tmp->vol_bytes_path); + free(tmp->vol_nums_path); + free(tmp->vdev_path); + free(tmp->vol_cdev_path); + free(tmp->nums_path); + free(tmp->eb_size_path); + free(tmp->avail_ebs_path); + free(tmp->tot_ebs_path); + free(tmp->vol_count_path); + free(tmp->wear_path); + free(tmp->udev_path); + free(tmp->cdev_path); + free(tmp->version); + free(tmp->ubi_root); + free(tmp->sysfs_root); + free(tmp); + + *desc = NULL; + + return 0; +} + +void +ubi_perror(const char *prefix, int code) +{ + if (code == 0) + return; + + fprintf(stderr, "%s: ", prefix); + + switch (code) { + case UBI_ENOTFOUND: + fprintf(stderr, "UBI was not found in system\n"); + break; + case UBI_EBUG: + fprintf(stderr, "an UBI or UBI library bug\n"); + break; + case UBI_EINVAL: + fprintf(stderr, "invalid parameter\n"); + break; + case -1: + perror(prefix); + break; + default: + ubi_err("unknown error code %d", code); + break; + } +} + +int +ubi_get_dev_info(ubi_lib_t desc, unsigned int devn, struct ubi_dev_info *di) +{ + int err; + + if (devn >= desc->ubi.dev_count) { + ubi_err("bad device number, max is %d\n", + desc->ubi.dev_count - 1); + return UBI_EINVAL; + } + + err = sysfs_read_dev_subst(desc->nums_path, &di->major, + &di->minor, 1, devn); + if (err) + return -1; + + err = sysfs_read_ull_subst(desc->wear_path, &di->wear, 1, devn); + if (err) + return -1; + + err = sysfs_read_uint_subst(desc->vol_count_path, + &di->vol_count, 1, devn); + if (err) + return -1; + + err = sysfs_read_uint_subst(desc->eb_size_path, &di->eb_size, 1, devn); + if (err) + return -1; + + err = sysfs_read_uint_subst(desc->tot_ebs_path, &di->total_ebs, 1, devn); + if (err) + return -1; + + err = sysfs_read_uint_subst(desc->avail_ebs_path, + &di->avail_ebs, 1, devn); + if (err) + return -1; + +#if 0 + ubi_dbg("major:minor %d:%d, wear %llu, EB size %d, " + "vol. count %d, tot. EBs %d, avail. EBs %d", + di->major, di->minor, di->wear, di->eb_size, + di->vol_count, di->total_ebs, di->avail_ebs); +#endif + + return err; +} + +int +ubi_get_vol_info(ubi_lib_t desc, unsigned int devn, unsigned int vol_id, + struct ubi_vol_info *req) +{ + int err; + int len; + char buf1[10]; + char buf2[UBI_MAX_VOLUME_NAME]; + + err = sysfs_read_dev_subst(desc->vol_nums_path, &req->major, + &req->minor, 2, devn, vol_id); + if (err) + return -1; + + err = sysfs_read_ull_subst(desc->vol_bytes_path, + &req->bytes, 2, devn, vol_id); + if (err) + return -1; + + err = sysfs_read_uint_subst(desc->vol_ebs_path, + &req->eraseblocks, 2, devn, vol_id); + if (err) + return -1; + + len = sysfs_read_data_subst(desc->vol_type_path, &buf1[0], + 10, 2, devn, vol_id); + if (len == -1) + return -1; + + if (buf1[len - 1] != '\n') { + ubi_err("bad volume type"); + return UBI_EBUG; + } + + if (!strncmp(&buf1[0], "static", sizeof("static") - 1)) { + req->type = UBI_STATIC_VOLUME; + } else if (!strncmp(&buf1[0], "dynamic", sizeof("dynamic") - 1)) { + req->type = UBI_DYNAMIC_VOLUME; + } else { + ubi_err("bad type %s", &buf1[0]); + return -1; + } + + len = sysfs_read_data_subst(desc->vol_name_path, &buf2[0], + UBI_MAX_VOLUME_NAME, 2, devn, vol_id); + if (len == -1) + return -1; + + if (buf2[len - 1] != '\n') { + ubi_err("bad volume name"); + return UBI_EBUG; + } + + req->name = malloc(len); + if (!req->name) { + ubi_err("cannot allocate memory"); + return -1; + } + + memcpy(req->name, &buf2[0], len - 1); + req->name[len - 1] = '\0'; + + return 0; +} + +/** + * ubi_cdev_open - open a UBI device + * + * @desc UBI library descriptor + * @devn Number of UBI device to open + * @flags Flags to pass to open() + * + * This function opens a UBI device by number and returns a file + * descriptor. In case of an error %-1 is returned and errno is set + * appropriately. + */ +static int +ubi_cdev_open(ubi_lib_t desc, int devn, int flags) +{ + char *buf; + int fd; + + ubi_dbg("desc=%p, devn=%d, flags=%08x\n", desc, devn, flags); + + if (desc == NULL) { + ubi_err("desc is NULL\n"); + return -1; + } + if (desc->vol_cdev_path_len == 0) { + ubi_err("path_len == 0\n"); + return -1; + } + buf = malloc(desc->cdev_path_len); + + sprintf(buf, desc->cdev_path, devn); + + fd = open(buf, flags); + if (fd == -1) + ubi_dbg("cannot open %s", buf); + + free(buf); + return fd; +} + +/** + * ubi_cdev_close - close a UBI device + * + * @dev_fd file descriptor of UBI device to close + * + * This function closes the given UBI device. + */ +static int +ubi_cdev_close(int dev_fd) +{ + return close(dev_fd); +} + +/** + * @size is now in bytes. + */ +int +ubi_mkvol(ubi_lib_t desc, int devn, int vol_id, int vol_type, + long long bytes, int alignment, const char *name) +{ + int fd; + int err; + struct ubi_mkvol_req req; + size_t n; + + n = strlen(name); + if (n > UBI_MAX_VOLUME_NAME) + return -1; + + if ((fd = ubi_cdev_open(desc, devn, O_RDWR)) == -1) + return -1; + + req.vol_id = vol_id; + req.bytes = bytes; + req.vol_type = vol_type; + req.alignment = alignment; + + strncpy(req.name, name, UBI_MAX_VOLUME_NAME + 1); + req.name_len = n; + + /* printf("DBG: %s(vol_id=%d, bytes=%lld, type=%d, alig=%d, nlen=%d, " + "name=%s)\n", __func__, vol_id, bytes, vol_type, alignment, + strlen(name), name);*/ + + err = ioctl(fd, UBI_IOCMKVOL, &req); + if (err < 0) { + ubi_err("ioctl returned %d errno=%d\n", err, errno); + goto out_close; + } + + ubi_dbg("created volume %d, size %lld, name \"%s\" " + "at UBI dev %d\n", vol_id, bytes, name, devn); + + close(fd); + return err; + out_close: + ubi_cdev_close(fd); + return err; +} + +int +ubi_rmvol(ubi_lib_t desc, int devn, int vol_id) +{ + int fd; + int err; + + if ((fd = ubi_cdev_open(desc, devn, O_RDWR)) == -1) + return -1; + + err = ioctl(fd, UBI_IOCRMVOL, &vol_id); + if (err < 0) + goto out_close; + + ubi_dbg("removed volume %d", vol_id); + + out_close: + ubi_cdev_close(fd); + return err; +} + +int +ubi_get_info(ubi_lib_t desc, struct ubi_info *ubi) +{ + memcpy(ubi, &desc->ubi, sizeof(struct ubi_info)); + return 0; +} + + +int +ubi_vol_open(ubi_lib_t desc, int devn, int vol_id, int flags) +{ + char *buf; + int fd; + + ubi_dbg("desc=%p, devn=%d, vol_id=%d, flags=%08x\n", + desc, devn, vol_id, flags); + + if (desc == NULL) { + ubi_err("desc is NULL\n"); + return -1; + } + if (desc->vol_cdev_path_len == 0) { + ubi_err("path_len == 0\n"); + return -1; + } + buf = malloc(desc->cdev_path_len); + + sprintf(buf, desc->vol_cdev_path, devn, vol_id); + + fd = open(buf, flags); + if (fd == -1) + ubi_dbg("cannot open %s", buf); + + free(buf); + return fd; +} + +int +ubi_vol_close(int vol_fd) +{ + return close(vol_fd); +} + + +int +ubi_vol_update(int vol_fd, unsigned long long bytes) +{ + int err; + + err = ioctl(vol_fd, UBI_IOCVOLUP, &bytes); + if (err) { + ubi_err("%s failure calling update ioctl\n" + " IOCTL(%08lx) err=%d errno=%d\n", + __func__, (long unsigned int)UBI_IOCVOLUP, err, errno); + } + return err; +} + +FILE * +ubi_vol_fopen_read(ubi_lib_t desc, int devn, uint32_t vol_id) +{ + FILE *fp; + int fd; + + fd = ubi_vol_open(desc, devn, vol_id, O_RDONLY); + if (fd == -1) + return NULL; + + fp = fdopen(fd, "r"); + if (fp == NULL) + ubi_vol_close(fd); + + return fp; +} + +FILE * +ubi_vol_fopen_update(ubi_lib_t desc, int devn, uint32_t vol_id, + unsigned long long bytes) +{ + FILE *fp; + int fd; + int err; + + fd = ubi_vol_open(desc, devn, vol_id, O_RDWR); + if (fd == -1) + return NULL; + + fp = fdopen(fd, "r+"); + if (fp == NULL) { + printf("DBG: %s(errno=%d)\n", __func__, errno); + ubi_vol_close(fd); + return NULL; + } + err = ubi_vol_update(fd, bytes); + if (err < 0) { + printf("DBG: %s() fd=%d err=%d\n", __func__, fd, err); + fclose(fp); + return NULL; + } + return fp; +} + +int +ubi_vol_get_used_bytes(int vol_fd, unsigned long long *bytes) +{ + off_t res; + + res = lseek(vol_fd, 0, SEEK_END); + if (res == (off_t)-1) + return -1; + *bytes = (unsigned long long) res; + res = lseek(vol_fd, 0, SEEK_SET); + return res == (off_t)-1 ? -1 : 0; +} diff --git a/ubi-utils/src/libubiold_int.h b/ubi-utils/src/libubiold_int.h new file mode 100644 index 0000000..830a682 --- /dev/null +++ b/ubi-utils/src/libubiold_int.h @@ -0,0 +1,119 @@ +/* + * 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. + */ + +/* + * UBI (Unsorted Block Images) library. + * + * Author: Artem B. Bityutskiy + */ + +#ifndef __UBI_INT_H__ +#define __UBI_INT_H__ +/* + * Enable/disable UBI library debugging messages. + */ +#undef UBILIB_DEBUG + +/* + * UBI library error message. + */ +#define ubi_err(fmt, ...) do { \ + fprintf(stderr, "UBI Library Error at %s: ", __func__); \ + fprintf(stderr, fmt, ##__VA_ARGS__); \ + fprintf(stderr, "\n"); \ + } while (0) + +#ifdef UBILIB_DEBUG +#define ubi_dbg(fmt, ...) do { \ + fprintf(stderr, "UBI Debug: %s: ", __func__); \ + fprintf(stderr, fmt, ##__VA_ARGS__); \ + fprintf(stderr, "\n"); \ + } while (0) + +#else +#define ubi_dbg(fmt, ...) do { } while (0) +#endif + +/** + * SYSFS Entries. + * + * @def UBI_ROOT + * @brief Name of the root UBI directory in sysfs. + * + * @def UBI_NLEN_MAX + * @brief Name of syfs file containing the maximum UBI volume name length. + * + * @def UBI_VER + * @brief Name of sysfs file containing UBI version. + * + * @def UBI_WEAR + * @brief Name of sysfs file containing wear level of an UBI device. + * + * @def UBI_VOL_COUNT + * @brief Name of sysfs file contaning the of volume on an UBI device + * + * @def UBI_TOT_EBS + * @brief Name of sysfs file contaning the total number of + * eraseblocks on an UBI device. + * + * @def UBI_AVAIL_EBS + * @brief Name of sysfs file contaning the number of unused eraseblocks on + * an UBI device. + * + * @def UBI_EB_SIZE + * @brief Name of sysfs file containing size of UBI eraseblocks. + * + * @def UBI_NUMS + * @brief Name of sysfs file containing major and minor numbers + * of an UBI device or an UBI volume device. + * + * @def UBI_VBYTES + * @brief Name of sysfs file containing size of an UBI volume device in + * bytes. + * + * @def UBI_VEBS + * @brief Name of sysfs file containing size of an UBI volume device in + * eraseblocks. + * + * @def UBI_VTYPE + * @brief Name of sysfs file containing type of an UBI volume device. + * + * @def UBI_VNAME + * @brief Name of sysfs file containing name of an UBI volume device. + **/ +#define UBI_ROOT "ubi" +#define UBI_NLEN_MAX "volume_name_max" +#define UBI_VER "version" +#define UBI_WEAR "wear" +#define UBI_VOL_COUNT "volumes_count" +#define UBI_TOT_EBS "total_eraseblocks" +#define UBI_AVAIL_EBS "avail_eraseblocks" +#define UBI_EB_SIZE "eraseblock_size" +#define UBI_NUMS "dev" +#define UBI_VBYTES "bytes" +#define UBI_VEBS "eraseblocks" +#define UBI_VTYPE "type" +#define UBI_VNAME "name" + +#define UBI_CDEV_PATH "/dev/ubi%d" +#define UBI_VOL_CDEV_PATH "/dev/ubi%d_%d" +#define UBI_SYSFS_ROOT "/sys/class" + +#define UBI_MAX_ID_SIZE 9 + +#endif /* !__UBI_INT_H__ */ diff --git a/ubi-utils/src/libubiold_sysfs.c b/ubi-utils/src/libubiold_sysfs.c new file mode 100644 index 0000000..95fd3de --- /dev/null +++ b/ubi-utils/src/libubiold_sysfs.c @@ -0,0 +1,232 @@ +/* + * 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. + */ + +/* + * UBI (Unsorted Block Images) library. + * + * Author: Artem B. Bityutskiy + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "libubi_int.h" + +int +sysfs_read_data(const char *file, void *buf, int len) +{ + int fd; + ssize_t rd; + + fd = open(file, O_RDONLY); + if (fd == -1) { + ubi_err("cannot open file %s", file); + return -1; + } + + rd = read(fd, buf, len); + if (rd == -1) + ubi_err("cannot read file %s", file); + + close(fd); + + return rd; +} + +int +sysfs_read_data_subst(const char *patt, void *buf, int len, int n, ...) +{ + va_list args; + char buf1[strlen(patt) + 20 * n]; + + va_start(args, n); + vsprintf(&buf1[0], patt, args); + va_end(args); + + return sysfs_read_data(&buf1[0], buf, len); +} + +int +sysfs_read_dev(const char *file, unsigned int *major, unsigned int *minor) +{ + int fd; + int ret; + ssize_t rd; + int err = -1; + char buf[40]; + + fd = open(file, O_RDONLY); + if (fd == -1) { + ubi_err("cannot open file %s", file); + return -1; + } + + rd = read(fd, &buf[0], 20); + if (rd == -1) { + ubi_err("cannot read file %s", file); + goto error; + } + if (rd < 4) { + ubi_err("bad contents of file %s:", file); + goto error; + } + + err = -1; + if (buf[rd -1] != '\n') { + ubi_err("bad contents of file %s", file); + goto error; + } + + ret = sscanf(&buf[0], "%d:%d\n", major, minor); + if (ret != 2) { + ubi_err("bad contents of file %s", file); + goto error; + } + + err = 0; + +error: + close(fd); + + return err; +} + +int +sysfs_read_dev_subst(const char *patt, unsigned int *major, + unsigned int *minor, int n, ...) +{ + va_list args; + char buf[strlen(patt) + 20 * n]; + + va_start(args, n); + vsprintf(&buf[0], patt, args); + va_end(args); + + return sysfs_read_dev(&buf[0], major, minor); +} + +static int +sysfs_read_ull(const char *file __unused, unsigned long long *num __unused) +{ + return 0; +} + +int +sysfs_read_ull_subst(const char *patt, unsigned long long *num, int n, ...) +{ + va_list args; + char buf[strlen(patt) + 20 * n]; + + va_start(args, n); + vsprintf(&buf[0], patt, args); + va_end(args); + + return sysfs_read_ull(&buf[0], num); +} + +static int +sysfs_read_uint(const char *file __unused, unsigned int *num __unused) +{ + return 0; +} + +int +sysfs_read_uint_subst(const char *patt, unsigned int *num, int n, ...) +{ + va_list args; + char buf[strlen(patt) + 20 * n]; + + va_start(args, n); + vsprintf(&buf[0], patt, args); + va_end(args); + + return sysfs_read_uint(&buf[0], num); +} + +int +sysfs_read_ll(const char *file, long long *num) +{ + int fd; + ssize_t rd; + int err = -1; + char buf[20]; + char *endptr; + + fd = open(file, O_RDONLY); + if (fd == -1) + return -1; + + rd = read(fd, &buf[0], 20); + if (rd == -1) + goto out; + + if (rd < 2) { + ubi_err("bad contents in file %s: \"%c%c...\"", + file, buf[0], buf[1]); + goto out_errno; + } + + *num = strtoll(&buf[0], &endptr, 10); + if (endptr == &buf[0] || *endptr != '\n') { + ubi_err("bad contents in file %s: \"%c%c...\"", + file, buf[0], buf[1]); + goto out_errno; + } + + if (*num < 0) { + ubi_err("bad number in file %s: %lld", file, *num); + goto out_errno; + } + + err = 0; + +out_errno: + errno = EINVAL; + +out: + close(fd); + return err; +} + +int +sysfs_read_int(const char *file, int *num) +{ + int err; + long long res = 0; + + err = sysfs_read_ll(file, &res); + if (err) + return err; + + if (res < 0 || res > INT_MAX) { + ubi_err("bad number in file %s: %lld", file, res); + errno = EINVAL; + return -1; + } + + *num = res; + return 0; +} diff --git a/ubi-utils/src/libubiold_sysfs.h b/ubi-utils/src/libubiold_sysfs.h new file mode 100644 index 0000000..2fb6072 --- /dev/null +++ b/ubi-utils/src/libubiold_sysfs.h @@ -0,0 +1,109 @@ +/* + * 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. + */ + +/* + * UBI (Unsorted Block Images) library. + * + * Author: Artem B. Bityutskiy + */ + +/** + * sysfs_read_data - read data from a sysfs file. + * + * @file path to the file to read from + * @buf furrer where to store read data + * @len length of provided buffer @buf + * + * This function returns the number of read bytes or -1 in case of error. + */ +int sysfs_read_data(const char *file, void *buf, int len); + +/** + * sysfs_read_data_subst - form path to a sysfs file and read data from it. + * + * @patt path to the file to read from + * @buf furrer where to store read data + * @len length of provided buffer @buf + * @n number of parameters to substitute to @patt + * + * This function forms path to a sysfs file by means of substituting parameters + * to @patt and then reads @len bytes from this file and stores the read data + * to @buf. This function returns the number of read bytes or -1 in case of + * error. + */ +int sysfs_read_data_subst(const char *patt, void *buf, int len, int n, ...); + +/** + * sysfs_read_dev - read major and minor number from a sysfs file. + * + * @file path to the file to read from + * @major major number is returned here + * @minor minor number is returned here + */ +int sysfs_read_dev(const char *file, unsigned int *major, + unsigned int *minor); +/** + * sysfs_read_dev_subst - for path to a file and read major and minor number + * from it. + * + * @patt pattern of the path to the file to read from + * @major major number is returned here + * @minor minor number is returned here + * @n number of arguments to substitute + * + * This function substitures arguments to the @patt file path pattern and reads + * major and minor numbers from the resulting file. + */ +int sysfs_read_dev_subst(const char *patt, unsigned int *major, + unsigned int *minor, int n, ...); + +/** + * sysfs_read_ull_subst - form path to a sysfs file and read an unsigned long + * long value from there. + * + * @patt pattern of file path + * @num the read value is returned here + * @n number of parameters to substitute + * + * + * This function first forms the path to a sysfs file by means of substituting + * passed parameters to the @patt string, and then read an 'unsigned long long' + * value from this file. + */ +int sysfs_read_ull_subst(const char *patt, unsigned long long *num, + int n, ...); + +/** + * sysfs_read_uint_subst - the same as 'sysfs_read_uint_subst()' but reads an + * unsigned int value. + */ +int sysfs_read_uint_subst(const char *patt, unsigned int *num, + int n, ...); + +/** + * sysfs_read_ll - read a long long integer from an UBI sysfs file. + * + * @file file name from where to read + * @num the result is returned here + */ +int sysfs_read_ll(const char *file, long long *num); + +/** + * sysfs_read_int - the same as 'sysfs_read_ll()' but reads an 'int' value. + */ +int sysfs_read_int(const char *file, int *num); -- cgit v1.2.3