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

Sources/fstools/ubi.c

  1 /*
  2  * Copyright (C) 2014 John Crispin <blogic@openwrt.org>
  3  *
  4  * This program is free software; you can redistribute it and/or modify
  5  * it under the terms of the GNU Lesser General Public License version 2.1
  6  * as published by the Free Software Foundation
  7  *
  8  * This program is distributed in the hope that it will be useful,
  9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11  * GNU General Public License for more details.
 12  */
 13 
 14 #include <sys/types.h>
 15 #include <sys/stat.h>
 16 #include <fcntl.h>
 17 #include <stdio.h>
 18 #include <stdint.h>
 19 #include <getopt.h>
 20 #include <stdlib.h>
 21 #include <string.h>
 22 #include <unistd.h>
 23 
 24 #include <libubox/ulog.h>
 25 
 26 #include "libubi/libubi-tiny.h"
 27 
 28 static int print_usage(void)
 29 {
 30         printf("ubi info\n");
 31         printf("ubi detach kernel|rootfs\n");
 32         printf("ubi kernel <image.kernel.ubi>\n");
 33         printf("ubi rootfs <image.rootfs.ubi>\n");
 34         printf("ubi overlay <image.rootfs-overlay.ubi>\n");
 35 
 36         return -1;
 37 }
 38 
 39 static int mtd_find_index(char *name)
 40 {
 41         FILE *fp = fopen("/proc/mtd", "r");
 42         char line[256];
 43         char *index = NULL;
 44 
 45         if (!fp)
 46                 return -1;
 47 
 48         while (!index && fgets(line, sizeof(line), fp)) {
 49                 if (strstr(line, name)) {
 50                         char *eol = strstr(line, ":");
 51 
 52                         if (!eol)
 53                                 continue;
 54 
 55                         *eol = '\0';
 56                         index = &line[3];
 57                 }
 58         }
 59 
 60         fclose(fp);
 61 
 62         if (!index)
 63                 return -1;
 64 
 65         return atoi(index);
 66 }
 67 
 68 static int mtd_find(char *name, char *ret)
 69 {
 70         int index = mtd_find_index(name);
 71         if (index < 0)
 72                 return -1;
 73 
 74         sprintf(ret, "/dev/mtd%d", index);
 75 
 76         return 0;
 77 }
 78 
 79 static int ubi_find(libubi_t libubi, char *name, char *ret)
 80 {
 81         int index = mtd_find_index(name);
 82         int ubi = 0;
 83 
 84         while (ubi_dev_present(libubi, ubi))
 85         {
 86                 struct ubi_dev_info info;
 87 
 88                 if (ubi_get_dev_info1(libubi, ubi++, &info))
 89                         continue;
 90 
 91                 if (info.mtd_num != index)
 92                         continue;
 93 
 94                 sprintf(ret, "/dev/ubi%d", info.dev_num);
 95 
 96                 return 0;
 97         }
 98 
 99         return -1;
100 }
101 
102 static int volume_find(libubi_t libubi, char *name, char *ret)
103 {
104         int index = mtd_find_index(name);
105         struct ubi_vol_info vol;
106         int ubi = 0;
107 
108         if (index < 0)
109                 return -1;
110 
111         if (mtd_num2ubi_dev(libubi, index, &ubi)) {
112                 ULOG_ERR("failed to get ubi node for %s\n", name);
113                 return -1;
114         }
115 
116         if (ubi_get_vol_info1_nm(libubi, ubi, name, &vol)) {
117                 ULOG_ERR("failed to get ubi volume info for %s\n", name);
118                 return -1;
119         }
120 
121         sprintf(ret, "/dev/ubi%d_%d", ubi, vol.vol_id);
122 
123         return 0;
124 }
125 
126 static int main_detach(char *type)
127 {
128         libubi_t libubi;
129         char mtd[64];
130         int err;
131 
132         if (!strcmp(type, "kernel"))
133                 err = mtd_find("kernel_ubi", mtd);
134         else if (!strcmp(type, "rootfs"))
135                 err = mtd_find("rootfs_ubi", mtd);
136         else
137                 return print_usage();
138 
139         if (err) {
140                 ULOG_ERR("MTD partition '%s_ubi' not found\n", type);
141                 return -1;
142         }
143 
144         libubi = libubi_open();
145         if (!libubi) {
146                 ULOG_ERR("cannot open libubi");
147                 return -1;
148         }
149 
150         err = ubidetach(libubi, mtd);
151         if (err) {
152                 ULOG_ERR("cannot detach \"%s\"", mtd);
153                 libubi_close(libubi);
154                 return -1;
155         }
156 
157         libubi_close(libubi);
158         return 0;
159 }
160 
161 static int main_image(char *partition, char *image, char *overlay)
162 {
163         libubi_t libubi;
164         struct stat s;
165         int err;
166         char mtd[64];
167         char _part[64];
168         char node[64];
169         char volume[64];
170         char _data[64];
171         char *data = NULL;
172 
173         if (stat(image, &s)) {
174                 ULOG_ERR("image not found %s\n", image);
175                 return -1;
176         }
177 
178         if (!strcmp(partition, "kernel"))
179                 err = mtd_find("kernel", _part);
180         else
181                 err = mtd_find("rootfs", _part);
182 
183         if (overlay && !mtd_find(overlay, _data))
184                 data = _data;
185 
186         libubi = libubi_open();
187         if (!libubi) {
188                 ULOG_ERR("cannot open libubi");
189                 return -1;
190         }
191 
192         if (!strcmp(partition, "kernel"))
193                 err = mtd_find("kernel_ubi", mtd);
194         else
195                 err = mtd_find("rootfs_ubi", mtd);
196         if (err) {
197                 ULOG_ERR("MTD partition '%s_ubi' not found\n", partition);
198                 libubi_close(libubi);
199                 return -1;
200         }
201 
202         if (!strcmp(partition, "kernel"))
203                 err = ubi_find(libubi, "kernel_ubi", node);
204         else
205                 err = ubi_find(libubi, "rootfs_ubi", node);
206         if (err) {
207                 ULOG_ERR("UBI volume '%s' not found\n", partition);
208                 libubi_close(libubi);
209                 return -1;
210         }
211 
212         err = ubidetach(libubi, mtd);
213         if (err) {
214                 ULOG_ERR("cannot detach \"%s\"", mtd);
215                 libubi_close(libubi);
216                 return -1;
217         }
218 
219         err = ubiattach(libubi, mtd);
220         if (err) {
221                 ULOG_ERR("cannot attach \"%s\"", mtd);
222                 libubi_close(libubi);
223                 return -1;
224         }
225 
226         if (data) {
227                 err = ubirmvol(libubi, node, overlay);
228                 if (err) {
229                         ULOG_ERR("cannot remove \"%s\"", node);
230                         libubi_close(libubi);
231                         return -1;
232                 }
233         }
234 
235         if (volume_find(libubi, partition, volume) < 0) {
236                 ULOG_ERR("UBI volume '%s' not found\n", partition);
237                 libubi_close(libubi);
238                 return -1;
239         }
240 
241         err = ubirsvol(libubi, node, partition, s.st_size);
242         if (err) {
243                 ULOG_ERR("cannot resize \"%s\"", partition);
244                 libubi_close(libubi);
245                 return -1;
246         }
247 
248         err = ubiupdatevol(libubi, volume, image);
249         if (err) {
250                 ULOG_ERR("cannot update \"%s\"", volume);
251                 libubi_close(libubi);
252                 return -1;
253         }
254 
255         if (overlay) {
256                 err = ubimkvol(libubi, node, overlay, 1);
257                 if (err) {
258                         ULOG_ERR("cannot make \"%s\"", overlay);
259                         libubi_close(libubi);
260                         return -1;
261                 }
262         }
263 
264         libubi_close(libubi);
265 
266         return err;
267 }
268 
269 static int main_info(void)
270 {
271         struct ubi_info info;
272         libubi_t libubi;
273         int i;
274 
275         libubi = libubi_open();
276         if (!libubi) {
277                 ULOG_ERR("cannot open libubi");
278                 return -1;
279         }
280 
281         if (ubi_get_info(libubi, &info)) {
282                 ULOG_ERR("failed to get info\n");
283                 libubi_close(libubi);
284                 return -1;
285         }
286 
287         for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) {
288                 struct ubi_dev_info dinfo;
289                 char ubi[64];
290                 int j;
291 
292                 sprintf(ubi, "/dev/ubi%d", i);
293                 if (ubi_get_dev_info(libubi, ubi, &dinfo))
294                         continue;
295                 printf("device - %s\n  size: %lldBytes\n  bad blocks: %d\n",
296                        &ubi[5], dinfo.total_bytes, dinfo.bad_count);
297                 for (j = dinfo.lowest_vol_id; j <= dinfo.highest_vol_id; j++) {
298                         struct ubi_vol_info vinfo;
299 
300                         sprintf(ubi, "/dev/ubi%d_%d", i, j);
301                         if (ubi_get_vol_info(libubi, ubi, &vinfo))
302                                 continue;
303                         printf("  volume - %s\n", &ubi[5]);
304                         printf("\tname: %s\n", vinfo.name);
305                         printf("\tsize: %lld\n", vinfo.data_bytes);
306                 }
307         }
308 
309         libubi_close(libubi);
310 
311         return 0;
312 }
313 
314 int main(int argc, char **argv)
315 {
316         if (argc > 1 && !strcmp(argv[1], "info"))
317                 return main_info();
318 
319         if (argc < 3)
320                 return print_usage();
321 
322         if (!strcmp(argv[1], "kernel")) {
323                 return main_image("kernel", argv[2], NULL);
324 
325         } else if (!strcmp(argv[1], "rootfs")) {
326                 return main_image("rootfs", argv[2], NULL);
327 
328         } else if (!strcmp(argv[1], "overlay")) {
329                 return main_image("rootfs", argv[2], "rootfs_data");
330 
331         } else if (!strcmp(argv[1], "detach")) {
332                 return main_detach(argv[2]);
333         }
334 
335         return -1;
336 }
337 
338 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt