• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/fstools/libubi/libubi-tiny.c

  1 /*
  2  * Copyright (C) 2007 Nokia Corporation.
  3  *
  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.
  7  *
  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
 11  * more details.
 12  *
 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
 16  */
 17 
 18 /*
 19  * An utility to delete UBI devices (detach MTD devices from UBI).
 20  *
 21  * Author: Artem Bityutskiy
 22  */
 23 
 24 #define PROGRAM_NAME    "ubidetach"
 25 #define VERSION "owrt-fstools"
 26 
 27 #include <sys/types.h>
 28 #include <sys/stat.h>
 29 #include <fcntl.h>
 30 #include <stdio.h>
 31 #include <stdint.h>
 32 #include <getopt.h>
 33 #include <stdlib.h>
 34 #include <string.h>
 35 #include <unistd.h>
 36 
 37 #include "libubi-tiny.h"
 38 
 39 #define DEFAULT_CTRL_DEV "/dev/ubi_ctrl"
 40 
 41 static int ubi_write(char *node, int fd, const void *buf, int len)
 42 {
 43         int ret;
 44 
 45         while (len) {
 46                 ret = write(fd, buf, len);
 47                 if (ret < 0) {
 48                         if (errno == EINTR) {
 49                                 fprintf(stderr, "do not interrupt me!");
 50                                 continue;
 51                         }
 52                         fprintf(stderr, "cannot write %d bytes to volume \"%s\"", len, node);
 53                         return -1;
 54                 }
 55 
 56                 if (ret == 0) {
 57                         fprintf(stderr, "cannot write %d bytes to volume \"%s\"", len, node);
 58                         return -1;
 59                 }
 60                 len -= ret;
 61                 buf += ret;
 62         }
 63 
 64         return 0;
 65 }
 66 
 67 static int update_volume(libubi_t libubi, struct ubi_vol_info *vol_info, char *node, char *img, int skip)
 68 {
 69         int err, fd, ifd;
 70         long long bytes;
 71         char *buf;
 72         struct stat st;
 73 
 74         buf = malloc(vol_info->leb_size);
 75         if (!buf) {
 76                 fprintf(stderr, "cannot allocate %d bytes of memory", vol_info->leb_size);
 77                 return -1;
 78         }
 79         err = stat(img, &st);
 80         if (err < 0) {
 81                 fprintf(stderr, "stat failed on \"%s\"", img);
 82                 goto out_free;
 83         }
 84 
 85         bytes = st.st_size - skip;
 86 
 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);
 90                 goto out_free;
 91         }
 92 
 93         fd = open(node, O_RDWR);
 94         if (fd == -1) {
 95                 fprintf(stderr, "cannot open UBI volume \"%s\"", node);
 96                 goto out_free;
 97         }
 98 
 99         ifd = open(img, O_RDONLY);
100         if (ifd == -1) {
101                 fprintf(stderr, "cannot open \"%s\"", img);
102                 goto out_close1;
103         }
104 
105         if (skip && lseek(ifd, skip, SEEK_CUR) == -1) {
106                 fprintf(stderr, "lseek input by %d failed", skip);
107                 goto out_close;
108         }
109 
110         err = ubi_update_start(libubi, fd, bytes);
111         if (err) {
112                 fprintf(stderr, "cannot start volume \"%s\" update", node);
113                 goto out_close;
114         }
115 
116         while (bytes) {
117                 ssize_t ret;
118                 int to_copy = vol_info->leb_size;
119                 if (to_copy > bytes)
120                         to_copy = bytes;
121 
122                 ret = read(ifd, buf, to_copy);
123                 if (ret <= 0) {
124                         if (errno == EINTR) {
125                                 fprintf(stderr, "do not interrupt me!");
126                                 continue;
127                         } else {
128                                 fprintf(stderr, "cannot read %d bytes from \"%s\"",
129                                                 to_copy, img);
130                                 goto out_close;
131                         }
132                 }
133 
134                 err = ubi_write(node, fd, buf, ret);
135                 if (err)
136                         goto out_close;
137                 bytes -= ret;
138         }
139 
140         close(ifd);
141         close(fd);
142         free(buf);
143         return 0;
144 
145 out_close:
146         close(ifd);
147 out_close1:
148         close(fd);
149 out_free:
150         free(buf);
151         return -1;
152 }
153 
154 int ubiattach(libubi_t libubi, char *mtd)
155 {
156         struct ubi_attach_request req = {
157                 .dev_num = UBI_DEV_NUM_AUTO,
158                 .mtd_num = -1,
159                 .vid_hdr_offset = 0,
160                 .max_beb_per1024 = 0,
161                 .mtd_dev_node = mtd,
162         };
163         int err = ubi_attach(libubi, DEFAULT_CTRL_DEV, &req);
164 
165         if (err) {
166                 fprintf(stderr, "cannot attach \"%s\"", mtd);
167                 return err;
168         }
169 
170         return 0;
171 }
172 
173 int ubidetach(libubi_t libubi, char *mtd)
174 {
175         return ubi_detach(libubi, DEFAULT_CTRL_DEV, mtd);
176 }
177 
178 int ubirsvol(libubi_t libubi, char *node, char *name, int bytes)
179 {
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);
183 
184         if (err) {
185                 fprintf(stderr, "cannot get information about UBI device \"%s\"",
186                         node);
187                 return -1;
188         }
189         err = ubi_get_vol_info1_nm(libubi, dev_info.dev_num, name, &vol_info);
190         if (err) {
191                 fprintf(stderr, "cannot find UBI volume \"%s\"", name);
192                 return -1;
193         }
194 
195         err = ubi_rsvol(libubi, node, vol_info.vol_id, bytes);
196         if (err) {
197                 fprintf(stderr, "cannot UBI resize volume");
198                 return -1;
199         }
200 
201         return 0;
202 }
203 
204 int ubirmvol(libubi_t libubi, char *node, char *name)
205 {
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);
209 
210         if (err) {
211                 fprintf(stderr, "cannot get information about UBI device \"%s\"",
212                         node);
213                 return -1;
214         }
215 
216         err = ubi_get_vol_info1_nm(libubi, dev_info.dev_num, name, &vol_info);
217         if (err) {
218                 fprintf(stderr, "cannot find UBI volume \"%s\"", name);
219                 return -1;
220         }
221 
222         err = ubi_rmvol(libubi, node, vol_info.vol_id);
223         if (err) {
224                 fprintf(stderr, "cannot UBI remove volume");
225                 return -1;
226         }
227 
228         return 0;
229 }
230 
231 int ubimkvol(libubi_t libubi, char *node, char *name, int maxavs)
232 {
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);
237 
238         if (err) {
239                 fprintf(stderr, "cannot get information about UBI device \"%s\"",
240                         node);
241                 return -1;
242         }
243 
244         if (dev_info.avail_bytes == 0) {
245                 fprintf(stderr, "UBI device does not have free logical eraseblocks");
246                 return -1;
247         }
248 
249         if (maxavs)
250                 printf("Set volume size to %lld\n", dev_info.avail_bytes);
251 
252         req.vol_id = UBI_VOL_NUM_AUTO;
253         req.alignment = 1;
254         req.bytes = dev_info.avail_bytes;
255         req.vol_type = UBI_DYNAMIC_VOLUME;
256         req.name = name;
257 
258         err = ubi_mkvol(libubi, node, &req);
259         if (err < 0) {
260                 fprintf(stderr, "cannot UBI create volume");
261                 return -1;
262         }
263 
264         /* Print information about the created device */
265         err = ubi_get_vol_info1(libubi, dev_info.dev_num, req.vol_id, &vol_info);
266         if (err) {
267                 fprintf(stderr, "cannot get information about newly created UBI volume");
268                 return -1;
269         }
270 
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);
278 
279         return 0;
280 }
281 
282 int ubiupdatevol(libubi_t libubi, char *node, char *file)
283 {
284         struct ubi_vol_info vol_info;
285         int err = ubi_get_vol_info(libubi, node, &vol_info);
286 
287         if (err) {
288                 fprintf(stderr, "cannot get information about UBI volume \"%s\"",
289                         node);
290                 return -1;
291         }
292 
293         return update_volume(libubi, &vol_info, node, file, 0);
294 }
295 
296 int ubitruncatevol(libubi_t libubi, char *node)
297 {
298         int err, fd;
299 
300         fd = open(node, O_RDWR);
301         if (fd == -1) {
302                 fprintf(stderr, "cannot open \"%s\"", node);
303                 return -1;
304         }
305 
306         err = ubi_update_start(libubi, fd, 0);
307         if (err) {
308                 fprintf(stderr, "cannot truncate volume \"%s\"", node);
309                 close(fd);
310                 return -1;
311         }
312 
313         close(fd);
314         return 0;
315 }
316 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt