[Sheepdog] [PATCH 1/3] sheep: make jounaling functions support normal files
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Mon Oct 17 16:05:40 CEST 2011
The current implementation of Sheepdog journaling only supports
objects. This patch extend it.
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
sheep/Makefile.am | 3 +-
sheep/journal.c | 310 ++++++++++++++++++++++++++++++++++++++++
sheep/sheep.c | 2 -
sheep/sheep_priv.h | 62 +--------
sheep/store.c | 403 +---------------------------------------------------
5 files changed, 322 insertions(+), 458 deletions(-)
create mode 100644 sheep/journal.c
diff --git a/sheep/Makefile.am b/sheep/Makefile.am
index ad92ea0..2b9d58f 100644
--- a/sheep/Makefile.am
+++ b/sheep/Makefile.am
@@ -23,7 +23,8 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include $(libcpg_CFLAGS) $
sbin_PROGRAMS = sheep
-sheep_SOURCES = sheep.c group.c sdnet.c store.c vdi.c work.c cluster/corosync.c
+sheep_SOURCES = sheep.c group.c sdnet.c store.c vdi.c work.c journal.c \
+ cluster/corosync.c
sheep_LDADD = $(libcpg_LIBS) $(libcfg_LIBS) ../lib/libsheepdog.a -lpthread
sheep_DEPENDENCIES = ../lib/libsheepdog.a
diff --git a/sheep/journal.c b/sheep/journal.c
new file mode 100644
index 0000000..19ac259
--- /dev/null
+++ b/sheep/journal.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2009-2011 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include "sheep_priv.h"
+
+#define JRNL_END_MARK 0x87654321UL
+#define IS_END_MARK_SET(var) (var == JRNL_END_MARK)
+
+/* Journal header for data object */
+struct jrnl_head {
+ uint64_t offset;
+ uint64_t size;
+ char target_path[256];
+};
+
+struct jrnl_descriptor {
+ struct jrnl_head head;
+ void *data;
+ int fd; /* Open file fd */
+ int target_fd;
+ char path[256];
+};
+
+/* Journal APIs */
+static int jrnl_open(struct jrnl_descriptor *jd, const char *path)
+{
+ strcpy(jd->path, path);
+ jd->fd = open(path, O_RDONLY);
+
+ if (jd->fd < 0) {
+ eprintf("failed to open %s, %s\n", jd->path, strerror(errno));
+ if (errno == ENOENT)
+ return SD_RES_NO_OBJ;
+ else
+ return SD_RES_UNKNOWN;
+ }
+
+ return SD_RES_SUCCESS;
+}
+
+static int jrnl_close(struct jrnl_descriptor *jd)
+{
+ close(jd->fd);
+ jd->fd = -1;
+
+ return 0;
+}
+
+static int jrnl_create(struct jrnl_descriptor *jd, const char *jrnl_dir)
+{
+ snprintf(jd->path, sizeof(jd->path), "%sXXXXXX", jrnl_dir);
+ jd->fd = mkostemp(jd->path, O_SYNC);
+
+ if (jd->fd < 0) {
+ eprintf("failed to create %s, %s\n", jd->path, strerror(errno));
+ return SD_RES_UNKNOWN;
+ }
+
+ return SD_RES_SUCCESS;
+}
+
+static int jrnl_remove(struct jrnl_descriptor *jd)
+{
+ int ret;
+
+ ret = unlink(jd->path);
+ if (ret) {
+ eprintf("failed to remove %s, %m\n", jd->path);
+ ret = SD_RES_EIO;
+ } else
+ ret = SD_RES_SUCCESS;
+
+ return ret;
+}
+
+static int jrnl_has_end_mark(struct jrnl_descriptor *jd)
+{
+ ssize_t ret;
+ uint32_t end_mark = 0;
+ struct jrnl_head *head = (struct jrnl_head *) &jd->head;
+
+ ret = pread64(jd->fd, &end_mark, sizeof(end_mark),
+ sizeof(*head) + head->size);
+
+ return IS_END_MARK_SET(end_mark);
+}
+
+static int jrnl_write_header(struct jrnl_descriptor *jd)
+{
+ ssize_t ret;
+ struct jrnl_head *head = (struct jrnl_head *) &jd->head;
+
+ ret = pwrite64(jd->fd, head, sizeof(*head), 0);
+
+ if (ret != sizeof(*head)) {
+ if (errno == ENOSPC)
+ ret = SD_RES_NO_SPACE;
+ else
+ ret = SD_RES_EIO;
+ } else
+ ret = SD_RES_SUCCESS;
+
+ return ret;
+}
+
+static int jrnl_write_data(struct jrnl_descriptor *jd)
+{
+ ssize_t ret;
+ struct jrnl_head *head = (struct jrnl_head *) &jd->head;
+
+ ret = pwrite64(jd->fd, jd->data, head->size, sizeof(*head));
+
+ if (ret != head->size) {
+ if (errno == ENOSPC)
+ ret = SD_RES_NO_SPACE;
+ else
+ ret = SD_RES_EIO;
+ } else
+ ret = SD_RES_SUCCESS;
+
+ return ret;
+}
+
+static int jrnl_write_end_mark(struct jrnl_descriptor *jd)
+{
+ ssize_t retsize;
+ int ret;
+ uint32_t end_mark = JRNL_END_MARK;
+ struct jrnl_head *head = (struct jrnl_head *) &jd->head;
+
+ retsize = pwrite64(jd->fd, &end_mark, sizeof(end_mark),
+ sizeof(*head) + head->size);
+
+ if (retsize != sizeof(end_mark)) {
+ if (errno == ENOSPC)
+ ret = SD_RES_NO_SPACE;
+ else
+ ret = SD_RES_EIO;
+ } else
+ ret = SD_RES_SUCCESS;
+
+ return ret;
+}
+
+static int jrnl_apply_to_target_object(struct jrnl_descriptor *jd)
+{
+ char *buf = NULL;
+ int buf_len, res = 0;
+ ssize_t retsize;
+
+ /* FIXME: handle larger size */
+ buf_len = (1 << 22);
+ buf = zalloc(buf_len);
+ if (!buf) {
+ eprintf("failed to allocate memory\n");
+ return SD_RES_NO_MEM;
+ }
+
+ /* Flush out journal to disk (vdi object) */
+ retsize = pread64(jd->fd, &jd->head, sizeof(jd->head), 0);
+ retsize = pread64(jd->fd, buf, jd->head.size, sizeof(jd->head));
+ retsize = pwrite64(jd->target_fd, buf, jd->head.size, jd->head.offset);
+ if (retsize != jd->head.size) {
+ if (errno == ENOSPC)
+ res = SD_RES_NO_SPACE;
+ else
+ res = SD_RES_EIO;
+ }
+
+ /* Clean up */
+ free(buf);
+
+ return res;
+}
+
+static int jrnl_commit_data(struct jrnl_descriptor *jd)
+{
+ int ret = 0;
+ ssize_t retsize;
+ struct jrnl_head *head = (struct jrnl_head *) &jd->head;
+
+ retsize = pwrite64(jd->target_fd, jd->data, head->size, head->offset);
+ if (retsize != head->size) {
+ if (errno == ENOSPC)
+ ret = SD_RES_NO_SPACE;
+ else
+ ret = SD_RES_EIO;
+ }
+
+ return ret;
+}
+
+/*
+ * We cannot use this function for concurrent write operations
+ */
+int jrnl_perform(int fd, void *buf, size_t count, off_t offset,
+ const char *path, const char *jrnl_dir)
+{
+ int ret;
+ struct jrnl_descriptor jd;
+
+ memset(&jd, 0, sizeof(jd));
+ jd.target_fd = fd;
+
+ jd.head.offset = offset;
+ jd.head.size = count;
+ strcpy(jd.head.target_path, path);
+
+ jd.data = buf;
+
+ ret = jrnl_create(&jd, jrnl_dir);
+ if (ret)
+ goto out;
+
+ ret = jrnl_write_header(&jd);
+ if (ret)
+ goto out;
+
+ ret = jrnl_write_data(&jd);
+ if (ret)
+ goto out;
+
+ ret = jrnl_write_end_mark(&jd);
+ if (ret)
+ goto out;
+
+ ret = jrnl_commit_data(&jd);
+ if (ret)
+ goto out;
+
+ ret = jrnl_close(&jd);
+ if (ret)
+ goto out;
+
+ ret = jrnl_remove(&jd);
+
+out:
+ return ret;
+}
+
+int jrnl_recover(const char *jrnl_dir)
+{
+ DIR *dir;
+ struct dirent *d;
+ char jrnl_file_path[PATH_MAX];
+
+ eprintf("Openning the directory %s.\n", jrnl_dir);
+ dir = opendir(jrnl_dir);
+ if (!dir)
+ return -1;
+
+ vprintf(SDOG_NOTICE, "start jrnl_recovery.\n");
+ while ((d = readdir(dir))) {
+ int ret;
+ struct jrnl_descriptor jd;
+
+ if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
+ continue;
+
+ snprintf(jrnl_file_path, sizeof(jrnl_file_path), "%s%s",
+ jrnl_dir, d->d_name);
+ ret = jrnl_open(&jd, jrnl_file_path);
+ if (ret) {
+ eprintf("Unable to open the journal file, %s, for reading.\n",
+ jrnl_file_path);
+ goto end_while_3;
+ }
+ if (!jrnl_has_end_mark(&jd))
+ goto end_while_2;
+ jd.target_fd = open(jd.head.target_path, O_SYNC | O_RDWR);
+ if (ret) {
+ eprintf("Unable to open the object file, %s, to recover.\n",
+ jd.head.target_path);
+ goto end_while_2;
+ }
+ ret = jrnl_apply_to_target_object(&jd);
+ if (ret)
+ eprintf("Unable to recover the object, %s.\n",
+ jd.head.target_path);
+
+ close(jd.target_fd);
+ jd.target_fd = -1;
+end_while_2:
+ jrnl_close(&jd);
+end_while_3:
+ vprintf(SDOG_INFO, "recovered the object in journal, %s\n",
+ jrnl_file_path);
+ jrnl_remove(&jd);
+ }
+ closedir(dir);
+ vprintf(SDOG_NOTICE, "end jrnl_recovery.\n");
+
+ return 0;
+}
diff --git a/sheep/sheep.c b/sheep/sheep.c
index 27859ca..0deac09 100644
--- a/sheep/sheep.c
+++ b/sheep/sheep.c
@@ -185,8 +185,6 @@ int main(int argc, char **argv)
if (ret)
exit(1);
- jrnl_recover();
-
ret = init_event(EPOLL_SIZE);
if (ret)
exit(1);
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index e2fcb40..cccb986 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -242,65 +242,9 @@ int get_sheep_fd(uint8_t *addr, uint16_t port, int node_idx,
uint32_t epoch, int worker_idx);
/* Journal */
-#define JRNL_TYPE_VDI 0
-#define JRNL_MAX_TYPES 1
-
-#define SET_END_MARK 1UL
-#define UNSET_END_MARK 0UL
-#define IS_END_MARK_SET(var) (var == 1UL)
-
-/* Journal header for data object */
-struct jrnl_vdi_head {
- uint32_t jh_type;
- uint32_t pad;
- uint64_t jh_offset;
- uint64_t jh_size;
-};
-
-struct jrnl_file_desc {
- uint32_t jf_epoch; /* epoch */
- uint64_t jf_oid; /* Object id */
- int jf_fd; /* Open file fd */
- int jf_target_fd;
-} jrnl_file_desc_t;
-
-struct jrnl_descriptor {
- void *jd_head;
- void *jd_data;
- int jd_end_mark;
- struct jrnl_file_desc jd_jfd;
-#define jdf_epoch jd_jfd.jf_epoch
-#define jdf_oid jd_jfd.jf_oid
-#define jdf_fd jd_jfd.jf_fd
-#define jdf_target_fd jd_jfd.jf_target_fd
-} jrnl_desc_t;
-
-struct jrnl_handler {
- int (*has_end_mark)(struct jrnl_descriptor *jd);
- int (*write_header)(struct jrnl_descriptor *jd);
- int (*write_data)(struct jrnl_descriptor *jd);
- int (*write_end_mark)(struct jrnl_descriptor *jd);
- int (*apply_to_target_object)(struct jrnl_file_desc *jfd);
- int (*commit_data)(struct jrnl_descriptor *jd);
-};
-
-inline uint32_t jrnl_get_type(struct jrnl_descriptor *jd);
-int jrnl_get_type_from_file(struct jrnl_file_desc *jfd, uint32_t *jrnl_type);
-int jrnl_exists(struct jrnl_file_desc *jfd);
-int jrnl_update_epoch_store(uint32_t epoch);
-int jrnl_open(struct jrnl_file_desc *jfd, int aflags);
-int jrnl_create(struct jrnl_file_desc *jfd);
-int jrnl_remove(struct jrnl_file_desc *jfd);
-inline int jrnl_close(struct jrnl_file_desc *jfd);
-
-inline int jrnl_has_end_mark(struct jrnl_descriptor *jd);
-inline int jrnl_write_header(struct jrnl_descriptor *jd);
-inline int jrnl_write_data(struct jrnl_descriptor *jd);
-inline int jrnl_write_end_mark(struct jrnl_descriptor *jd);
-inline int jrnl_apply_to_target_object(struct jrnl_file_desc *jfd);
-inline int jrnl_commit_data(struct jrnl_descriptor *jd);
-int jrnl_perform(struct jrnl_descriptor *jd);
-int jrnl_recover(void);
+int jrnl_perform(int fd, void *buf, size_t count, off_t offset,
+ const char *path, const char *jrnl_dir);
+int jrnl_recover(const char *jrnl_dir);
static inline int is_myself(uint8_t *addr, uint16_t port)
{
diff --git a/sheep/store.c b/sheep/store.c
index abaab9f..8eb2d5b 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -35,26 +35,6 @@ static char *jrnl_path;
static mode_t def_dmode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
static mode_t def_fmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
-/* Journal internal data structures */
-/* Journal Handlers for Data Object */
-static int jrnl_vdi_has_end_mark(struct jrnl_descriptor *jd);
-static int jrnl_vdi_write_header(struct jrnl_descriptor *jd);
-static int jrnl_vdi_write_data(struct jrnl_descriptor *jd);
-static int jrnl_vdi_write_end_mark(struct jrnl_descriptor *jd);
-static int jrnl_vdi_apply_to_target_object(struct jrnl_file_desc *jfd);
-static int jrnl_vdi_commit_data(struct jrnl_descriptor *jd);
-
-static struct jrnl_handler jrnl_handlers[JRNL_MAX_TYPES] = {
- {
- .has_end_mark = jrnl_vdi_has_end_mark,
- .write_header = jrnl_vdi_write_header,
- .write_data = jrnl_vdi_write_data,
- .write_end_mark = jrnl_vdi_write_end_mark,
- .apply_to_target_object = jrnl_vdi_apply_to_target_object,
- .commit_data = jrnl_vdi_commit_data
- }
-};
-
static int obj_cmp(const void *oid1, const void *oid2)
{
const uint64_t hval1 = fnv_64a_buf((void *)oid1, sizeof(uint64_t), FNV1A_64_INIT);
@@ -565,8 +545,6 @@ static int store_queue_request_local(struct request *req, uint32_t epoch)
uint64_t oid = hdr->oid;
uint32_t opcode = hdr->opcode;
char path[1024], *buf = NULL;
- struct jrnl_descriptor jd;
- struct jrnl_vdi_head jh;
dprintf("%x, %" PRIx64" , %u\n", opcode, oid, epoch);
@@ -703,20 +681,10 @@ static int store_queue_request_local(struct request *req, uint32_t epoch)
}
if (is_vdi_obj(oid)) {
- jd.jdf_epoch = epoch;
- jd.jdf_oid = oid;
- jd.jdf_target_fd = fd;
-
- memset(&jh, 0, sizeof(jh));
- jh.jh_type = JRNL_TYPE_VDI;
- jh.jh_offset = hdr->offset;
- jh.jh_size = hdr->data_length;
-
- jd.jd_head = &jh;
- jd.jd_data = req->data;
- jd.jd_end_mark = SET_END_MARK;
-
- ret = jrnl_perform(&jd);
+ snprintf(path, sizeof(path), "%s%08u/%016" PRIx64, obj_path,
+ epoch, oid);
+ ret = jrnl_perform(fd, req->data, hdr->data_length,
+ hdr->offset, path, jrnl_path);
if (ret)
goto out;
} else {
@@ -2028,10 +1996,13 @@ static int init_jrnl_path(const char *base_path)
/* Error during directory creation */
if (ret)
return ret;
+
/* If journal is newly created */
if (new)
return 0;
+ jrnl_recover(jrnl_path);
+
return 0;
}
@@ -2087,363 +2058,3 @@ int get_global_nr_copies(uint32_t *copies)
{
return attr(epoch_path, ANAME_COPIES, copies, sizeof(*copies), 0);
}
-
-/* Journal APIs */
-int jrnl_exists(struct jrnl_file_desc *jfd)
-{
- int ret;
- char path[1024];
- struct stat s;
-
- snprintf(path, sizeof(path), "%s%08u/%016" PRIx64, jrnl_path,
- jfd->jf_epoch, jfd->jf_oid);
-
- ret = stat(path, &s);
- if (ret)
- return 1;
-
- return 0;
-}
-
-int jrnl_update_epoch_store(uint32_t epoch)
-{
- char new[1024];
- struct stat s;
-
- snprintf(new, sizeof(new), "%s%08u/", jrnl_path, epoch);
- if (stat(new, &s) < 0)
- if (errno == ENOENT)
- mkdir(new, def_dmode);
-
- return 0;
-}
-
-int jrnl_open(struct jrnl_file_desc *jfd, int aflags)
-{
- char path[1024];
- int flags = aflags;
- int fd, ret;
-
-
- jrnl_update_epoch_store(jfd->jf_epoch);
- snprintf(path, sizeof(path), "%s%08u/%016" PRIx64, jrnl_path,
- jfd->jf_epoch, jfd->jf_oid);
-
- fd = open(path, flags, def_fmode);
- if (fd < 0) {
- eprintf("failed to open %s, %s\n", path, strerror(errno));
- if (errno == ENOENT)
- ret = SD_RES_NO_OBJ;
- else
- ret = SD_RES_UNKNOWN;
- } else {
- jfd->jf_fd = fd;
- ret = SD_RES_SUCCESS;
- }
-
- return ret;
-}
-
-int jrnl_close(struct jrnl_file_desc *jfd)
-{
- close(jfd->jf_fd);
- jfd->jf_fd = -1;
-
- return 0;
-}
-
-int jrnl_create(struct jrnl_file_desc *jfd)
-{
- return jrnl_open(jfd, O_RDWR | O_CREAT);
-}
-
-inline uint32_t jrnl_get_type(struct jrnl_descriptor *jd)
-{
- return *((uint32_t *) jd->jd_head);
-}
-
-int jrnl_get_type_from_file(struct jrnl_file_desc *jfd, uint32_t *jrnl_type)
-{
- ssize_t retsize;
-
- retsize = pread64(jfd->jf_fd, jrnl_type, sizeof(*jrnl_type), 0);
-
- if (retsize != sizeof(*jrnl_type))
- return SD_RES_EIO;
- else
- return SD_RES_SUCCESS;
-}
-
-int jrnl_remove(struct jrnl_file_desc *jfd)
-{
- char path[1024];
- int ret;
-
- snprintf(path, sizeof(path), "%s%08u/%016" PRIx64, jrnl_path,
- jfd->jf_epoch, jfd->jf_oid);
- ret = unlink(path);
- if (ret) {
- eprintf("failed to remove %s, %s\n", path, strerror(errno));
- ret = SD_RES_EIO;
- } else
- ret = SD_RES_SUCCESS;
-
- return ret;
-}
-
-inline int jrnl_has_end_mark(struct jrnl_descriptor *jd)
-{
- return jrnl_handlers[jrnl_get_type(jd)].has_end_mark(jd);
-}
-
-inline int jrnl_write_header(struct jrnl_descriptor *jd)
-{
- return jrnl_handlers[jrnl_get_type(jd)].write_header(jd);
-}
-
-inline int jrnl_write_data(struct jrnl_descriptor *jd)
-{
- return jrnl_handlers[jrnl_get_type(jd)].write_data(jd);
-}
-
-inline int jrnl_write_end_mark(struct jrnl_descriptor *jd)
-{
- return jrnl_handlers[jrnl_get_type(jd)].write_end_mark(jd);
-}
-
-inline int jrnl_apply_to_target_object(struct jrnl_file_desc *jfd)
-{
- int ret;
- uint32_t jrnl_type;
-
- ret = jrnl_get_type_from_file(jfd, &jrnl_type);
- if (ret)
- return ret;
-
- return jrnl_handlers[jrnl_type].apply_to_target_object(jfd);
-}
-
-inline int jrnl_commit_data(struct jrnl_descriptor *jd)
-{
- return jrnl_handlers[jrnl_get_type(jd)].commit_data(jd);
-}
-
-int jrnl_perform(struct jrnl_descriptor *jd)
-{
- int ret;
-
- ret = jrnl_create(&jd->jd_jfd);
- if (ret)
- goto out;
-
- ret = jrnl_write_header(jd);
- if (ret)
- goto out;
-
- ret = jrnl_write_data(jd);
- if (ret)
- goto out;
-
- ret = jrnl_write_end_mark(jd);
- if (ret)
- goto out;
-
- ret = jrnl_commit_data(jd);
- if (ret)
- goto out;
-
- ret = jrnl_close(&jd->jd_jfd);
- if (ret)
- goto out;
-
- ret = jrnl_remove(&jd->jd_jfd);
-
-out:
- return ret;
-}
-
-int jrnl_recover(void)
-{
- DIR *dir;
- struct dirent *d;
- char jrnl_dir[PATH_MAX], jrnl_file_path[PATH_MAX], obj_file_path[PATH_MAX];
- int epoch;
-
- epoch = get_latest_epoch();
- if (epoch < 0)
- return 1;
-
- snprintf(jrnl_dir, sizeof(jrnl_dir), "%s%08u/", jrnl_path, epoch);
-
- eprintf("Openning the directory %s.\n", jrnl_dir);
- dir = opendir(jrnl_dir);
- if (!dir)
- return -1;
-
- vprintf(SDOG_NOTICE, "start jrnl_recovery.\n");
- while ((d = readdir(dir))) {
- int ret;
- struct jrnl_file_desc jfd;
-
- if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
- continue;
-
- jfd.jf_epoch = epoch;
- sscanf(d->d_name, "%" PRIx64, &jfd.jf_oid);
- snprintf(jrnl_file_path, sizeof(jrnl_file_path), "%s%016" PRIx64,
- jrnl_dir, jfd.jf_oid);
- snprintf(obj_file_path, sizeof(obj_file_path), "%s%08u/%016" PRIx64,
- obj_path, epoch, jfd.jf_oid);
- ret = jrnl_open(&jfd, O_RDONLY);
- if (ret) {
- eprintf("Unable to open the journal file, %s, for reading.\n",
- jrnl_file_path);
- goto end_while_3;
- }
- jfd.jf_target_fd = ob_open(epoch, jfd.jf_oid, 0, &ret);
- if (ret) {
- eprintf("Unable to open the object file, %s, to recover.\n",
- obj_file_path);
- goto end_while_2;
- }
- ret = jrnl_apply_to_target_object(&jfd);
- if (ret)
- eprintf("Unable to recover the object, %s.\n",
- obj_file_path);
-
- close(jfd.jf_target_fd);
- jfd.jf_target_fd = -1;
-end_while_2:
- jrnl_close(&jfd);
-end_while_3:
- vprintf(SDOG_INFO, "recovered the object in journal, %s\n",
- jrnl_file_path);
- jrnl_remove(&jfd);
- }
- closedir(dir);
- vprintf(SDOG_NOTICE, "end jrnl_recovery.\n");
-
- return 0;
-}
-
-/* VDI data journalling functions */
-static int jrnl_vdi_has_end_mark(struct jrnl_descriptor *jd)
-{
- ssize_t ret;
- uint32_t end_mark = UNSET_END_MARK;
- struct jrnl_vdi_head *head = (struct jrnl_vdi_head *) jd->jd_head;
-
- ret = pread64(jd->jdf_fd, &end_mark, sizeof(end_mark),
- sizeof(*head) + head->jh_size);
-
- return IS_END_MARK_SET(end_mark) ? SET_END_MARK : UNSET_END_MARK;
-}
-
-static int jrnl_vdi_write_header(struct jrnl_descriptor *jd)
-{
- ssize_t ret;
- struct jrnl_vdi_head *head = (struct jrnl_vdi_head *) jd->jd_head;
-
- ret = pwrite64(jd->jdf_fd, head, sizeof(*head), 0);
-
- if (ret != sizeof(*head)) {
- if (errno == ENOSPC)
- ret = SD_RES_NO_SPACE;
- else
- ret = SD_RES_EIO;
- } else
- ret = SD_RES_SUCCESS;
-
- return ret;
-}
-
-static int jrnl_vdi_write_data(struct jrnl_descriptor *jd)
-{
- ssize_t ret;
- struct jrnl_vdi_head *head = (struct jrnl_vdi_head *) jd->jd_head;
-
- ret = pwrite64(jd->jdf_fd, jd->jd_data, head->jh_size, sizeof(*head));
-
- if (ret != head->jh_size) {
- if (errno == ENOSPC)
- ret = SD_RES_NO_SPACE;
- else
- ret = SD_RES_EIO;
- } else
- ret = SD_RES_SUCCESS;
-
- return ret;
-}
-
-static int jrnl_vdi_write_end_mark(struct jrnl_descriptor *jd)
-{
- ssize_t retsize;
- int ret;
- uint32_t end_mark = SET_END_MARK;
- struct jrnl_vdi_head *head = (struct jrnl_vdi_head *) jd->jd_head;
-
- retsize = pwrite64(jd->jdf_fd, &end_mark, sizeof(end_mark),
- sizeof(*head) + head->jh_size);
-
- if (retsize != sizeof(end_mark)) {
- if (errno == ENOSPC)
- ret = SD_RES_NO_SPACE;
- else
- ret = SD_RES_EIO;
- } else
- ret = SD_RES_SUCCESS;
-
- jd->jd_end_mark = end_mark;
-
- return ret;
-}
-
-static int jrnl_vdi_apply_to_target_object(struct jrnl_file_desc *jfd)
-{
- char *buf = NULL;
- int buf_len, res = 0;
- ssize_t retsize;
- struct jrnl_vdi_head jh;
-
- /* FIXME: handle larger size */
- buf_len = (1 << 22);
- buf = zalloc(buf_len);
- if (!buf) {
- eprintf("failed to allocate memory\n");
- return SD_RES_NO_MEM;
- }
-
- /* Flush out journal to disk (vdi object) */
- retsize = pread64(jfd->jf_fd, &jh, sizeof(jh), 0);
- retsize = pread64(jfd->jf_fd, buf, jh.jh_size, sizeof(jh));
- retsize = pwrite64(jfd->jf_target_fd, buf, jh.jh_size, jh.jh_offset);
- if (retsize != jh.jh_size) {
- if (errno == ENOSPC)
- res = SD_RES_NO_SPACE;
- else
- res = SD_RES_EIO;
- }
-
- /* Clean up */
- free(buf);
-
- return res;
-}
-
-static int jrnl_vdi_commit_data(struct jrnl_descriptor *jd)
-{
- int ret = 0;
- ssize_t retsize;
- struct jrnl_vdi_head *head = (struct jrnl_vdi_head *) jd->jd_head;
-
- retsize = pwrite64(jd->jdf_target_fd, jd->jd_data, head->jh_size,
- head->jh_offset);
- if (retsize != head->jh_size) {
- if (errno == ENOSPC)
- ret = SD_RES_NO_SPACE;
- else
- ret = SD_RES_EIO;
- }
-
- return ret;
-}
--
1.7.2.5
More information about the sheepdog
mailing list