2 * Copyright (C) 2007 Nokia Corporation.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * An utility to delete UBI devices (detach MTD devices from UBI).
21 * Author: Artem Bityutskiy
24 #define PROGRAM_NAME "ubidetach"
25 #define VERSION "owrt-fstools"
27 #include <sys/types.h>
37 #include "libubi-tiny.h"
39 #define DEFAULT_CTRL_DEV "/dev/ubi_ctrl"
41 static int ubi_write(char *node, int fd, const void *buf, int len)
46 ret = write(fd, buf, len);
49 fprintf(stderr, "do not interrupt me!");
52 fprintf(stderr, "cannot write %d bytes to volume \"%s\"", len, node);
57 fprintf(stderr, "cannot write %d bytes to volume \"%s\"", len, node);
67 static int update_volume(libubi_t libubi, struct ubi_vol_info *vol_info, char *node, char *img, int skip)
74 buf = malloc(vol_info->leb_size);
76 fprintf(stderr, "cannot allocate %d bytes of memory", vol_info->leb_size);
81 fprintf(stderr, "stat failed on \"%s\"", img);
85 bytes = st.st_size - skip;
87 if (bytes > vol_info->rsvd_bytes) {
88 fprintf(stderr, "\"%s\" (size %lld) will not fit volume \"%s\" (size %lld)",
89 img, bytes, node, vol_info->rsvd_bytes);
93 fd = open(node, O_RDWR);
95 fprintf(stderr, "cannot open UBI volume \"%s\"", node);
99 ifd = open(img, O_RDONLY);
101 fprintf(stderr, "cannot open \"%s\"", img);
105 if (skip && lseek(ifd, skip, SEEK_CUR) == -1) {
106 fprintf(stderr, "lseek input by %d failed", skip);
110 err = ubi_update_start(libubi, fd, bytes);
112 fprintf(stderr, "cannot start volume \"%s\" update", node);
118 int to_copy = vol_info->leb_size;
122 ret = read(ifd, buf, to_copy);
124 if (errno == EINTR) {
125 fprintf(stderr, "do not interrupt me!");
128 fprintf(stderr, "cannot read %d bytes from \"%s\"",
134 err = ubi_write(node, fd, buf, ret);
154 int ubiattach(libubi_t libubi, char *mtd)
156 struct ubi_attach_request req = {
157 .dev_num = UBI_DEV_NUM_AUTO,
160 .max_beb_per1024 = 0,
163 int err = ubi_attach(libubi, DEFAULT_CTRL_DEV, &req);
166 fprintf(stderr, "cannot attach \"%s\"", mtd);
173 int ubidetach(libubi_t libubi, char *mtd)
175 return ubi_detach(libubi, DEFAULT_CTRL_DEV, mtd);
178 int ubirsvol(libubi_t libubi, char *node, char *name, int bytes)
180 struct ubi_dev_info dev_info;
181 struct ubi_vol_info vol_info;
182 int err = ubi_get_dev_info(libubi, node, &dev_info);
185 fprintf(stderr, "cannot get information about UBI device \"%s\"",
189 err = ubi_get_vol_info1_nm(libubi, dev_info.dev_num, name, &vol_info);
191 fprintf(stderr, "cannot find UBI volume \"%s\"", name);
195 err = ubi_rsvol(libubi, node, vol_info.vol_id, bytes);
197 fprintf(stderr, "cannot UBI resize volume");
204 int ubirmvol(libubi_t libubi, char *node, char *name)
206 struct ubi_dev_info dev_info;
207 struct ubi_vol_info vol_info;
208 int err = ubi_get_dev_info(libubi, node, &dev_info);
211 fprintf(stderr, "cannot get information about UBI device \"%s\"",
216 err = ubi_get_vol_info1_nm(libubi, dev_info.dev_num, name, &vol_info);
218 fprintf(stderr, "cannot find UBI volume \"%s\"", name);
222 err = ubi_rmvol(libubi, node, vol_info.vol_id);
224 fprintf(stderr, "cannot UBI remove volume");
231 int ubimkvol(libubi_t libubi, char *node, char *name, int maxavs)
233 struct ubi_dev_info dev_info;
234 struct ubi_vol_info vol_info;
235 struct ubi_mkvol_request req;
236 int err = ubi_get_dev_info(libubi, node, &dev_info);
239 fprintf(stderr, "cannot get information about UBI device \"%s\"",
244 if (dev_info.avail_bytes == 0) {
245 fprintf(stderr, "UBI device does not have free logical eraseblocks");
250 printf("Set volume size to %lld\n", dev_info.avail_bytes);
252 req.vol_id = UBI_VOL_NUM_AUTO;
254 req.bytes = dev_info.avail_bytes;
255 req.vol_type = UBI_DYNAMIC_VOLUME;
258 err = ubi_mkvol(libubi, node, &req);
260 fprintf(stderr, "cannot UBI create volume");
264 /* Print information about the created device */
265 err = ubi_get_vol_info1(libubi, dev_info.dev_num, req.vol_id, &vol_info);
267 fprintf(stderr, "cannot get information about newly created UBI volume");
271 printf("Volume ID %d, size %d LEBs (", vol_info.vol_id, vol_info.rsvd_lebs);
272 ubiutils_print_bytes(vol_info.rsvd_bytes, 0);
273 printf("), LEB size ");
274 ubiutils_print_bytes(vol_info.leb_size, 1);
275 printf(", %s, name \"%s\", alignment %d\n",
276 req.vol_type == UBI_DYNAMIC_VOLUME ? "dynamic" : "static",
277 vol_info.name, vol_info.alignment);
282 int ubiupdatevol(libubi_t libubi, char *node, char *file)
284 struct ubi_vol_info vol_info;
285 int err = ubi_get_vol_info(libubi, node, &vol_info);
288 fprintf(stderr, "cannot get information about UBI volume \"%s\"",
293 return update_volume(libubi, &vol_info, node, file, 0);
296 int ubitruncatevol(libubi_t libubi, char *node)
300 fd = open(node, O_RDWR);
302 fprintf(stderr, "cannot open \"%s\"", node);
306 err = ubi_update_start(libubi, fd, 0);
308 fprintf(stderr, "cannot truncate volume \"%s\"", node);