#include <libubox/blob.h>
#include <libubox/md5.h>
-#include "../fs-state.h"
+#include "libfstools.h"
#include "volume.h"
#define PATH_MAX 256
}
static int
-snapshot_info(void)
-{
- struct volume *v = volume_find("rootfs_data");
- struct file_header hdr = { 0 }, conf;
- int block = 0;
-
- if (!v)
- return -1;
-
- fprintf(stderr, "sectors:\t%llu, block_size:\t%dK\n", v->size / v->block_size, v->block_size / 1024);
- do {
- if (volume_read(v, &hdr, block * v->block_size, sizeof(struct file_header))) {
- fprintf(stderr, "scanning for next free block failed\n");
- return 0;
- }
-
- be32_to_hdr(&hdr);
-
- if (hdr.magic != OWRT)
- break;
-
- if (hdr.type == DATA)
- fprintf(stderr, "block %d:\tsnapshot entry, size: %d, sectors: %d, sequence: %d\n", block, hdr.length, pad_file_size(v, hdr.length) / v->block_size, hdr.seq);
- else if (hdr.type == CONF)
- fprintf(stderr, "block %d:\tvolatile entry, size: %d, sectors: %d, sequence: %d\n", block, hdr.length, pad_file_size(v, hdr.length) / v->block_size, hdr.seq);
-
- if (hdr.type == DATA && !valid_file_size(hdr.length))
- block += pad_file_size(v, hdr.length) / v->block_size;
- } while (hdr.type == DATA);
- block = config_find(v, &conf, &hdr);
- if (block > 0)
- fprintf(stderr, "block %d:\tsentinel entry, size: %d, sectors: %d, sequence: %d\n", block, hdr.length, pad_file_size(v, hdr.length) / v->block_size, hdr.seq);
-
- return 0;
-}
-
-static int
snapshot_write_file(struct volume *v, int block, char *file, uint32_t seq, uint32_t type)
{
uint32_t md5[4] = { 0 };
}
static int
-config_write(int argc, char **argv)
-{
- struct volume *v = volume_find("rootfs_data");
- int ret;
-
- if (!v)
- return -1;
-
- ret = volatile_write(v, 0);
- if (!ret)
- ret = sentinel_write(v, 0);
-
- return ret;
-}
-
-static int
-config_read(int argc, char **argv)
-{
- struct volume *v = volume_find("rootfs_data");
- struct file_header conf, sentinel;
- int next, block, ret = 0;
- uint32_t seq;
-
- if (!v)
- return -1;
-
- block = config_find(v, &conf, &sentinel);
- next = snapshot_next_free(v, &seq);
- if (is_config(&conf) && conf.seq == seq)
- block = next;
- else if (!is_config(&sentinel) || sentinel.seq != seq)
- return -1;
-
- unlink("/tmp/config.tar.gz");
- ret = snapshot_read_file(v, block, "/tmp/config.tar.gz", CONF);
-
- if (ret < 1)
- fprintf(stderr, "failed to read /tmp/config.tar.gz\n");
-
- return ret;
-}
-
-static int
-snapshot_write(int argc, char **argv)
-{
- struct volume *v = volume_find("rootfs_data");
- int block, ret;
- uint32_t seq;
-
- if (!v)
- return -1;
-
- block = snapshot_next_free(v, &seq);
- if (block < 0)
- block = 0;
-
- ret = snapshot_write_file(v, block, "/tmp/snapshot.tar.gz", seq + 1, DATA);
- if (ret)
- fprintf(stderr, "failed to write /tmp/snapshot.tar.gz\n");
- else
- fprintf(stderr, "wrote /tmp/snapshot.tar.gz\n");
-
- return ret;
-}
-
-static int
-snapshot_mark(int argc, char **argv)
-{
- __be32 owrt = cpu_to_be32(OWRT);
- struct volume *v;
- size_t sz;
- int fd;
-
- fprintf(stderr, "This will remove all snapshot data stored on the system. Are you sure? [N/y]\n");
- if (getchar() != 'y')
- return -1;
-
- v = volume_find("rootfs_data");
- if (!v) {
- fprintf(stderr, "no rootfs_data was found\n");
- return -1;
- }
-
- fd = open(v->blk, O_WRONLY);
- fprintf(stderr, "%s - marking with 0x%08x\n", v->blk, owrt);
- if (fd < 0) {
- fprintf(stderr, "opening %s failed\n", v->blk);
- return -1;
- }
-
- sz = write(fd, &owrt, sizeof(owrt));
- close(fd);
-
- if (sz != 1) {
- fprintf(stderr, "writing %s failed: %s\n", v->blk, strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-static int
-snapshot_read(int argc, char **argv)
-{
- struct volume *v = volume_find("rootfs_data");;
- int block = 0, ret = 0;
- char file[64];
-
- if (!v)
- return -1;
-
- if (argc > 1) {
- block = atoi(argv[1]);
- if (block >= (v->size / v->block_size)) {
- fprintf(stderr, "invalid block %d > %llu\n", block, v->size / v->block_size);
- goto out;
- }
- snprintf(file, sizeof(file), "/tmp/snapshot/block%d.tar.gz", block);
-
- ret = snapshot_read_file(v, block, file, DATA);
- goto out;
- }
-
- do {
- snprintf(file, sizeof(file), "/tmp/snapshot/block%d.tar.gz", block);
- block = snapshot_read_file(v, block, file, DATA);
- } while (block > 0);
-
-out:
- return ret;
-}
-
-static int
snapshot_sync(void)
{
struct volume *v = volume_find("rootfs_data");
return fopivot(overlay, rom);
}
-static int
-snapshot_mount(void)
+int
+mount_snapshot(void)
{
snapshot_sync();
setenv("SNAPSHOT", "magic", 1);
unsetenv("SNAPSHOT");
return -1;
}
-
-static struct backend_handler snapshot_handlers[] = {
-{
- .name = "config_read",
- .cli = config_read,
-}, {
- .name = "config_write",
- .cli = config_write,
-}, {
- .name = "read",
- .cli = snapshot_read,
-}, {
- .name = "write",
- .cli = snapshot_write,
-}, {
- .name = "mark",
- .cli = snapshot_mark,
-}};
-
-static struct backend snapshot_backend = {
- .name = "snapshot",
- .num_handlers = ARRAY_SIZE(snapshot_handlers),
- .handlers = snapshot_handlers,
- .mount = snapshot_mount,
- .info = snapshot_info,
-};
-BACKEND(snapshot_backend);