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/mount.h> 15 #include <sys/types.h> 16 #include <sys/stat.h> 17 #include <sys/reboot.h> 18 #include <libubox/ulog.h> 19 20 #include <fcntl.h> 21 #include <dirent.h> 22 #include <stdint.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <unistd.h> 27 #include <getopt.h> 28 29 #include <mtd/ubi-user.h> 30 31 #include "libfstools/libfstools.h" 32 #include "libfstools/volume.h" 33 34 static int jffs2_mark(struct volume *v); 35 36 static int 37 ask_user(void) 38 { 39 ULOG_WARN("This will erase all settings and remove any installed packages. Are you sure? [N/y]\n"); 40 if (getchar() != 'y') 41 return -1; 42 return 0; 43 } 44 45 static int jffs2_reset(struct volume *v, int reset, int keep) 46 { 47 char *mp; 48 49 mp = find_mount_point(v->blk, 1); 50 if (mp) { 51 ULOG_INFO("%s is mounted as %s, only erasing files\n", v->blk, mp); 52 fs_state_set("/overlay", FS_STATE_PENDING); 53 overlay_delete(mp, keep); 54 mount(mp, "/", NULL, MS_REMOUNT, 0); 55 } else { 56 ULOG_INFO("%s is not mounted\n", v->blk); 57 return jffs2_mark(v); 58 } 59 60 if (reset) { 61 sync(); 62 sleep(2); 63 reboot(RB_AUTOBOOT); 64 while (1) 65 ; 66 } 67 68 return 0; 69 } 70 71 static int jffs2_mark(struct volume *v) 72 { 73 __u32 deadc0de = __cpu_to_be32(0xdeadc0de); 74 size_t sz; 75 int fd; 76 77 fd = open(v->blk, O_WRONLY); 78 ULOG_INFO("%s will be erased on next mount\n", v->blk); 79 if (!fd) { 80 ULOG_ERR("opening %s failed\n", v->blk); 81 return -1; 82 } 83 84 if (volume_identify(v) == FS_UBIFS) { 85 uint64_t llz = 0; 86 int ret = ioctl(fd, UBI_IOCVOLUP, &llz); 87 close(fd); 88 return ret; 89 } 90 91 sz = write(fd, &deadc0de, sizeof(deadc0de)); 92 close(fd); 93 94 if (sz != 4) { 95 ULOG_ERR("writing %s failed: %m\n", v->blk); 96 return -1; 97 } 98 99 return 0; 100 } 101 102 int main(int argc, char **argv) 103 { 104 struct volume *v; 105 int ch, yes = 0, reset = 0, keep = 0; 106 while ((ch = getopt(argc, argv, "yrk")) != -1) { 107 switch(ch) { 108 case 'y': 109 yes = 1; 110 break; 111 case 'r': 112 reset = 1; 113 break; 114 case 'k': 115 keep = 1; 116 break; 117 } 118 119 } 120 121 if (!yes && ask_user()) 122 return -1; 123 124 /* 125 * TODO: Currently this only checks if kernel supports OverlayFS. We 126 * should check if there is a mount point using it with rootfs_data 127 * as upperdir. 128 */ 129 if (find_filesystem("overlay")) { 130 ULOG_ERR("overlayfs not supported by kernel\n"); 131 return -1; 132 } 133 134 v = volume_find("rootfs_data"); 135 if (!v) { 136 ULOG_ERR("MTD partition 'rootfs_data' not found\n"); 137 return -1; 138 } 139 140 volume_init(v); 141 if (!strcmp(*argv, "jffs2mark")) 142 return jffs2_mark(v); 143 return jffs2_reset(v, reset, keep); 144 } 145
This page was automatically generated by LXR 0.3.1. • OpenWrt