X-Git-Url: http://git.archive.openwrt.org/?p=project%2Ffstools.git;a=blobdiff_plain;f=ubi.c;h=54f67b8058b104e1c53f0246e33336b0b2c2362b;hp=7cb8d62340e7f4dec7ac7da938a1ac3664edd4df;hb=6a8fae38791572d72d4241856b5704684a8ee7c6;hpb=f40b321cf8f273fae09e56075fe2f67b26cc2bd9 diff --git a/ubi.c b/ubi.c index 7cb8d62..54f67b8 100644 --- a/ubi.c +++ b/ubi.c @@ -21,8 +21,21 @@ #include #include +#include + #include "libubi/libubi-tiny.h" +static int print_usage(void) +{ + printf("ubi info\n"); + printf("ubi detach kernel|rootfs\n"); + printf("ubi kernel \n"); + printf("ubi rootfs \n"); + printf("ubi overlay \n"); + + return -1; +} + static int mtd_find_index(char *name) { FILE *fp = fopen("/proc/mtd", "r"); @@ -68,31 +81,22 @@ static int ubi_find(libubi_t libubi, char *name, char *ret) int index = mtd_find_index(name); int ubi = 0; - if (index < 0) - return -1; - - if (mtd_num2ubi_dev(libubi, index, &ubi)) { - fprintf(stderr, "failed to get ubi node for %s\n", name); - return -1; - } - sprintf(ret, "/dev/ubi%d", ubi); + while (ubi_dev_present(libubi, ubi)) + { + struct ubi_dev_info info; - return 0; -} - -static int ubi_find_mtd(libubi_t libubi, char *name, char *ret) -{ - struct ubi_dev_info info; + if (ubi_get_dev_info1(libubi, ubi++, &info)) + continue; - if (ubi_find(libubi, name, ret)) - return -1; + if (info.mtd_num != index) + continue; - if (ubi_get_dev_info(libubi, ret, &info)) - return -1; + sprintf(ret, "/dev/ubi%d", info.dev_num); - sprintf(ret, "/dev/mtd%d", info.mtd_num); + return 0; + } - return 0; + return -1; } static int volume_find(libubi_t libubi, char *name, char *ret) @@ -105,12 +109,12 @@ static int volume_find(libubi_t libubi, char *name, char *ret) return -1; if (mtd_num2ubi_dev(libubi, index, &ubi)) { - fprintf(stderr, "failed to get ubi node for %s\n", name); + ULOG_ERR("failed to get ubi node for %s\n", name); return -1; } if (ubi_get_vol_info1_nm(libubi, ubi, name, &vol)) { - fprintf(stderr, "failed to get ubi volume info for %s\n", name); + ULOG_ERR("failed to get ubi volume info for %s\n", name); return -1; } @@ -119,75 +123,129 @@ static int volume_find(libubi_t libubi, char *name, char *ret) return 0; } +static int main_detach(char *type) +{ + libubi_t libubi; + char mtd[64]; + int err; + + if (!strcmp(type, "kernel")) + err = mtd_find("kernel_ubi", mtd); + else if (!strcmp(type, "rootfs")) + err = mtd_find("rootfs_ubi", mtd); + else + return print_usage(); + + if (err) { + ULOG_ERR("MTD partition '%s_ubi' not found\n", type); + return -1; + } + + libubi = libubi_open(); + if (!libubi) { + ULOG_ERR("cannot open libubi"); + return -1; + } + + err = ubidetach(libubi, mtd); + if (err) { + ULOG_ERR("cannot detach \"%s\"", mtd); + return -1; + } + + return 0; +} + static int main_image(char *partition, char *image, char *overlay) { libubi_t libubi; + struct stat s; int err; char mtd[64]; - char part[64]; + char _part[64]; char node[64]; char volume[64]; char _data[64]; char *data = NULL; - if (mtd_find(partition, part)) { - fprintf(stderr, "failed to find mtd partition %s\n", partition); + if (stat(image, &s)) { + ULOG_ERR("image not found %s\n", image); return -1; } + + if (!strcmp(partition, "kernel")) + err = mtd_find("kernel", _part); + else + err = mtd_find("rootfs", _part); + if (overlay && !mtd_find(overlay, _data)) data = _data; libubi = libubi_open(); if (!libubi) { - fprintf(stderr, "cannot open libubi"); - return -1; - } - - if (ubi_find_mtd(libubi, partition, mtd)) { - fprintf(stderr, "failed to find mtd parent %s\n", partition); + ULOG_ERR("cannot open libubi"); return -1; } - if (ubi_find(libubi, partition, node)) { - fprintf(stderr, "failed to find ubi volume %s\n", partition); + if (!strcmp(partition, "kernel")) + err = mtd_find("kernel_ubi", mtd); + else + err = mtd_find("rootfs_ubi", mtd); + if (err) { + ULOG_ERR("MTD partition '%s_ubi' not found\n", partition); return -1; } - if (volume_find(libubi, partition, volume)) { - fprintf(stderr, "failed to find ubi volume %s\n", partition); + if (!strcmp(partition, "kernel")) + err = ubi_find(libubi, "kernel_ubi", node); + else + err = ubi_find(libubi, "rootfs_ubi", node); + if (err) { + ULOG_ERR("UBI volume '%s' not found\n", partition); return -1; } err = ubidetach(libubi, mtd); if (err) { - fprintf(stderr, "cannot detach \"%s\"", mtd); + ULOG_ERR("cannot detach \"%s\"", mtd); return -1; } err = ubiattach(libubi, mtd); if (err) { - fprintf(stderr, "cannot attach \"%s\"", mtd); + ULOG_ERR("cannot attach \"%s\"", mtd); return -1; } if (data) { err = ubirmvol(libubi, node, overlay); if (err) { - fprintf(stderr, "cannot remove \"%s\"", node); + ULOG_ERR("cannot remove \"%s\"", node); return -1; } } + if (volume_find(libubi, partition, volume) < 0) { + ULOG_ERR("UBI volume '%s' not found\n", partition); + return -1; + } + + err = ubirsvol(libubi, node, partition, s.st_size); + if (err) { + ULOG_ERR("cannot resize \"%s\"", partition); + return -1; + } + err = ubiupdatevol(libubi, volume, image); if (err) { - fprintf(stderr, "cannot update \"%s\"", volume); + ULOG_ERR("cannot update \"%s\"", volume); return -1; } if (overlay) { err = ubimkvol(libubi, node, overlay, 1); if (err) { - fprintf(stderr, "cannot make \"%s\"", node); + ULOG_ERR("cannot make \"%s\"", overlay); return -1; } } @@ -205,12 +263,12 @@ static int main_info(void) libubi = libubi_open(); if (!libubi) { - fprintf(stderr, "cannot open libubi"); + ULOG_ERR("cannot open libubi"); return -1; } if (ubi_get_info(libubi, &info)) { - fprintf(stderr, "failed to get info\n"); + ULOG_ERR("failed to get info\n"); return -1; } @@ -223,7 +281,7 @@ static int main_info(void) if (ubi_get_dev_info(libubi, ubi, &dinfo)) continue; printf("device - %s\n size: %lldBytes\n bad blocks: %d\n", - &ubi[5], dinfo.total_bytes, dinfo.bad_count); + &ubi[5], dinfo.total_bytes, dinfo.bad_count); for (j = dinfo.lowest_vol_id; j <= dinfo.highest_vol_id; j++) { struct ubi_vol_info vinfo; @@ -241,16 +299,6 @@ static int main_info(void) return 0; } -static int print_usage(void) -{ - printf("ubi info\n"); - printf("ubi kernel \n"); - printf("ubi rootfs \n"); - printf("ubi overlay \n"); - - return -1; -} - int main(int argc, char **argv) { if (argc > 1 && !strcmp(argv[1], "info")) @@ -267,6 +315,9 @@ int main(int argc, char **argv) } else if (!strcmp(argv[1], "overlay")) { return main_image("rootfs", argv[2], "rootfs_data"); + + } else if (!strcmp(argv[1], "detach")) { + return main_detach(argv[2]); } return -1;