static int jffs2_reset(struct volume *v, int reset) { char *mp; mp = find_mount_point(v->blk, 1); if (mp) { ULOG_INFO("%s is mounted as %s, only erasing files\n", v->blk, mp); fs_state_set("/overlay", FS_STATE_PENDING); overlay_delete(mp, false); mount(mp, "/", NULL, MS_REMOUNT, 0); } else { ULOG_INFO("%s is not mounted\n", v->blk); return jffs2_mark(v); } if (reset) { sync(); sleep(2); reboot(RB_AUTOBOOT); while (1) ; } return 0; }
int sentinel_write(struct volume *v, uint32_t _seq) { int ret, block; struct stat s; uint32_t seq; if (stat("/tmp/config.tar.gz", &s)) { ULOG_ERR("failed to stat /tmp/config.tar.gz\n"); return -1; } snapshot_next_free(v, &seq); if (_seq) seq = _seq; block = v->size / v->block_size; block -= pad_file_size(v, s.st_size) / v->block_size; if (block < 0) block = 0; ret = snapshot_write_file(v, block, "/tmp/config.tar.gz", seq, CONF); if (ret) ULOG_ERR("failed to write sentinel\n"); else ULOG_INFO("wrote /tmp/config.tar.gz sentinel\n"); return ret; }
static int snapshot_sync(struct volume *v) { struct file_header sentinel, conf; int next, block = 0; uint32_t seq; next = snapshot_next_free(v, &seq); block = config_find(v, &conf, &sentinel); if (is_config(&conf) && conf.seq != seq) { conf.magic = 0; volume_erase(v, next * v->block_size, 2 * v->block_size); } if (is_config(&sentinel) && (sentinel.seq != seq)) { sentinel.magic = 0; volume_erase(v, block * v->block_size, v->block_size); } if (!is_config(&conf) && !is_config(&sentinel)) { // ULOG_ERR("no config found\n"); } else if (((is_config(&conf) && is_config(&sentinel)) && (memcmp(conf.md5, sentinel.md5, sizeof(conf.md5)) || (conf.seq != sentinel.seq))) || (is_config(&conf) && !is_config(&sentinel))) { uint32_t seq; int next = snapshot_next_free(v, &seq); int ret = snapshot_read_file(v, next, "/tmp/config.tar.gz", CONF); if (ret > 0) { if (sentinel_write(v, conf.seq)) ULOG_ERR("failed to write sentinel data"); } } else if (!is_config(&conf) && is_config(&sentinel) && next) { int ret = snapshot_read_file(v, block, "/tmp/config.tar.gz", CONF); if (ret > 0) if (volatile_write(v, sentinel.seq)) ULOG_ERR("failed to write sentinel data"); } else ULOG_INFO("config in sync\n"); unlink("/tmp/config.tar.gz"); return 0; }
int volatile_write(struct volume *v, uint32_t _seq) { int block, ret; uint32_t seq; block = snapshot_next_free(v, &seq); if (_seq) seq = _seq; if (block < 0) block = 0; ret = snapshot_write_file(v, block, "/tmp/config.tar.gz", seq, CONF); if (ret) ULOG_ERR("failed to write /tmp/config.tar.gz\n"); else ULOG_INFO("wrote /tmp/config.tar.gz\n"); return ret; }
static int jffs2_mark(struct volume *v) { __u32 deadc0de = __cpu_to_be32(0xdeadc0de); size_t sz; int fd; fd = open(v->blk, O_WRONLY); ULOG_INFO("%s will be erased on next mount\n", v->blk); if (!fd) { ULOG_ERR("opening %s failed\n", v->blk); return -1; } sz = write(fd, &deadc0de, sizeof(deadc0de)); close(fd); if (sz != 4) { ULOG_ERR("writing %s failed: %s\n", v->blk, strerror(errno)); return -1; } return 0; }