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
);