diff options
author | Ryo Nakamura <upa@haeena.net> | 2024-02-20 15:12:05 +0900 |
---|---|---|
committer | Ryo Nakamura <upa@haeena.net> | 2024-02-20 15:12:05 +0900 |
commit | 0695c1e2e4b417763942c6311033b29922b9c778 (patch) | |
tree | 667a47efb542853ace58e26e9a2b7ad44c0afacc /src/checkpoint.c | |
parent | 692ea1d4e456f72aa61cc2827680cae4d810b1ce (diff) |
put magic code at the head of checkpoint
Diffstat (limited to 'src/checkpoint.c')
-rw-r--r-- | src/checkpoint.c | 74 |
1 files changed, 50 insertions, 24 deletions
diff --git a/src/checkpoint.c b/src/checkpoint.c index 906b02f..ee75c78 100644 --- a/src/checkpoint.c +++ b/src/checkpoint.c @@ -11,7 +11,7 @@ #include <checkpoint.h> -#define MSCP_CHECKPOINT_MAGIC 0x6d736370UL /* mscp in UTF-8 */ +#define MSCP_CHECKPOINT_MAGIC 0x7063736dUL /* mscp in ascii*/ #define MSCP_CHECKPOINT_VERSION 0x1 @@ -21,6 +21,11 @@ enum { OBJ_TYPE_CHUNK = 0x0C, }; +struct checkpoint_file_hdr { + uint32_t magic; + uint8_t version; +} __attribute__((packed)); + struct checkpoint_obj_hdr { uint8_t type; uint8_t rsv; @@ -30,10 +35,6 @@ struct checkpoint_obj_hdr { struct checkpoint_obj_meta { struct checkpoint_obj_hdr hdr; - - uint32_t magic; - uint8_t version; - uint16_t reserved; uint8_t direction; /* L2R or R2L */ char remote[0]; @@ -128,8 +129,9 @@ static int checkpoint_write_chunk(int fd, struct chunk *c) int checkpoint_save(const char *pathname, int dir, char *remote, pool *path_pool, pool *chunk_pool) { + struct checkpoint_file_hdr hdr; struct checkpoint_obj_meta meta; - struct iovec iov[2]; + struct iovec iov[3]; struct chunk *c; struct path *p; unsigned int i, nr_paths, nr_chunks; @@ -142,20 +144,24 @@ int checkpoint_save(const char *pathname, int dir, char *remote, pool *path_pool return -1; } + /* write file hdr */ + hdr.magic = htonl(MSCP_CHECKPOINT_MAGIC); + hdr.version = MSCP_CHECKPOINT_VERSION; + /* write meta */ memset(&meta, 0, sizeof(meta)); meta.hdr.type = OBJ_TYPE_META; meta.hdr.len = htons(sizeof(meta) + strlen(remote) + 1); - meta.magic = htonl(MSCP_CHECKPOINT_MAGIC); - meta.version = MSCP_CHECKPOINT_VERSION; meta.direction = dir; - iov[0].iov_base = &meta; - iov[0].iov_len = sizeof(meta); - iov[1].iov_base = remote; - iov[1].iov_len = strlen(remote) + 1; + iov[0].iov_base = &hdr; + iov[0].iov_len = sizeof(hdr); + iov[1].iov_base = &meta; + iov[1].iov_len = sizeof(meta); + iov[2].iov_base = remote; + iov[2].iov_len = strlen(remote) + 1; - if (writev(fd, iov, 2) < 0) { + if (writev(fd, iov, 3) < 0) { priv_set_errv("writev: %s", strerrno()); return -1; } @@ -190,17 +196,6 @@ static int checkpoint_load_meta(struct checkpoint_obj_hdr *hdr, char *remote, si { struct checkpoint_obj_meta *meta = (struct checkpoint_obj_meta *)hdr; - if (ntohl(meta->magic) != MSCP_CHECKPOINT_MAGIC) { - priv_set_errv("checkpoint: invalid megic code"); - return -1; - } - - if (meta->version != MSCP_CHECKPOINT_VERSION) { - priv_set_errv("checkpoint: unknown version %u", meta->version); - return -1; - } - pr_debug("checkpoint: version %u", meta->version); - if (len < ntohs(hdr->len) - sizeof(*meta)) { priv_set_errv("too short buffer"); return -1; @@ -314,6 +309,34 @@ static int checkpoint_read_obj(int fd, void *buf, size_t count) return 1; } +static int checkpoint_read_file_hdr(int fd) +{ + struct checkpoint_file_hdr hdr; + ssize_t ret; + + ret = read(fd, &hdr, sizeof(hdr)); + if (ret < 0) { + priv_set_errv("read: %s", strerrno()); + return -1; + } + if (ret < sizeof(hdr)) { + priv_set_errv("checkpoint truncated"); + return -1; + } + + if (ntohl(hdr.magic) != MSCP_CHECKPOINT_MAGIC) { + priv_set_errv("checkpoint: invalid megic code"); + return -1; + } + + if (hdr.version != MSCP_CHECKPOINT_VERSION) { + priv_set_errv("checkpoint: unknown version %u", hdr.version); + return -1; + } + + return 0; +} + static int checkpoint_load(const char *pathname, char *remote, size_t len, int *dir, pool *path_pool, pool *chunk_pool) { @@ -326,6 +349,9 @@ static int checkpoint_load(const char *pathname, char *remote, size_t len, int * return -1; } + if (checkpoint_read_file_hdr(fd) < 0) + return -1; + hdr = (struct checkpoint_obj_hdr *)buf; while ((ret = checkpoint_read_obj(fd, buf, sizeof(buf))) > 0) { switch (hdr->type) { |