[sheepdog] [PATCH 3/5] migrate: add helper to do process for each epoch
MORITA Kazutaka
morita.kazutaka at gmail.com
Fri May 31 19:15:48 CEST 2013
From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
This prepares for the migration from v1 to v2.
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
sheep/migrate.c | 168 ++++++++++++++++++++++++++++++++++---------------------
1 file changed, 103 insertions(+), 65 deletions(-)
diff --git a/sheep/migrate.c b/sheep/migrate.c
index 7e05fbf..24fbfcc 100644
--- a/sheep/migrate.c
+++ b/sheep/migrate.c
@@ -15,6 +15,7 @@
#include <fcntl.h>
#include <errno.h>
#include <time.h>
+#include <dirent.h>
#include "sheep_priv.h"
@@ -73,6 +74,31 @@ static size_t get_file_size(const char *path)
return stbuf.st_size;
}
+static void for_each_epoch(int (*func)(uint32_t epoch))
+{
+ DIR *dir;
+ struct dirent *d;
+
+ dir = opendir(epoch_path);
+ if (!dir)
+ panic("failed to open %s: %m", epoch_path);
+
+ while ((d = readdir(dir))) {
+ uint32_t e;
+ char *p;
+ e = strtol(d->d_name, &p, 10);
+ if (d->d_name == p)
+ continue;
+
+ if (strlen(d->d_name) != 8)
+ continue;
+
+ if (func(e) != 0)
+ return;
+ }
+ closedir(dir);
+}
+
/* copy file from 'fname' to 'fname.suffix' */
static int backup_file(char *fname, char *suffix)
{
@@ -126,13 +152,29 @@ out:
return ret;
}
+static int backup_epoch(uint32_t epoch)
+{
+ char path[PATH_MAX];
+ char suffix[256];
+ struct timeval tv;
+ struct tm tm;
+
+ gettimeofday(&tv, NULL);
+ localtime_r(&tv.tv_sec, &tm);
+ strftime(suffix, sizeof(suffix), "%Y-%m-%d_%H%M%S", &tm);
+
+ snprintf(path, sizeof(path), "%s%08u", epoch_path, epoch);
+
+ return backup_file(path, suffix);
+}
+
/* backup config and epoch info */
static int backup_store(void)
{
char suffix[256];
struct timeval tv;
struct tm tm;
- int ret, epoch, le;
+ int ret;
gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &tm);
@@ -142,23 +184,73 @@ static int backup_store(void)
if (ret < 0)
return ret;
- le = get_latest_epoch();
- for (epoch = 1; epoch <= le; epoch++) {
- char path[PATH_MAX];
- snprintf(path, sizeof(path), "%s%08u", epoch_path, epoch);
+ for_each_epoch(backup_epoch);
- ret = backup_file(path, suffix);
- if (ret < 0)
- return ret;
+ return 0;
+}
+
+static int update_epoch_from_v0_to_v1(uint32_t epoch)
+{
+ char path[PATH_MAX];
+ struct sd_node_v0 nodes_v0[SD_MAX_NODES];
+ struct sd_node_v1 nodes_v1[SD_MAX_NODES];
+ size_t nr_nodes;
+ time_t *t;
+ int len, fd, ret;
+
+ snprintf(path, sizeof(path), "%s%08u", epoch_path, epoch);
+ fd = open(path, O_RDWR | O_DSYNC);
+ if (fd < 0) {
+ if (errno == ENOENT)
+ return 0;
+
+ sd_eprintf("failed to open epoch %"PRIu32" log", epoch);
+ return -1;
+ }
+
+ ret = xread(fd, nodes_v0, sizeof(nodes_v0));
+ if (ret < 0) {
+ sd_eprintf("failed to read epoch %"PRIu32" log", epoch);
+ close(fd);
+ return ret;
+ }
+
+ nr_nodes = ret / sizeof(nodes_v0[0]);
+ for (int i = 0; i < nr_nodes; i++) {
+ memcpy(&nodes_v1[i].nid, &nodes_v0[i].nid,
+ sizeof(struct node_id_v1));
+ nodes_v1[i].nr_vnodes = nodes_v0[i].nr_vnodes;
+ nodes_v1[i].zone = nodes_v0[i].zone;
+ nodes_v1[i].space = 0;
+ }
+
+ len = sizeof(nodes_v1[0]) * nr_nodes;
+ ret = xpwrite(fd, nodes_v1, len, 0);
+ if (ret != len) {
+ sd_eprintf("failed to write epoch %"PRIu32" log",
+ epoch);
+ close(fd);
+ return -1;
+ }
+
+ t = (time_t *)&nodes_v0[nr_nodes];
+
+ ret = xpwrite(fd, t, sizeof(*t), len);
+ if (ret != sizeof(*t)) {
+ sd_eprintf("failed to write time to epoch %"
+ PRIu32" log", epoch);
+ close(fd);
+ return -1;
}
+ close(fd);
+
return 0;
}
static int migrate_from_v0_to_v1(void)
{
- int fd, ret, epoch, le, i;
- char path[PATH_MAX];
+ int ret, fd;
struct sheepdog_config_v1 config;
fd = open(config_path, O_RDWR);
@@ -202,61 +294,7 @@ static int migrate_from_v0_to_v1(void)
return 0;
/* upgrade epoch log */
- le = get_latest_epoch();
- for (epoch = 1; epoch <= le; epoch++) {
- struct sd_node_v0 nodes_v0[SD_MAX_NODES];
- struct sd_node_v1 nodes_v1[SD_MAX_NODES];
- size_t nr_nodes;
- time_t *t;
- int len;
-
- snprintf(path, sizeof(path), "%s%08u", epoch_path, epoch);
- fd = open(path, O_RDWR | O_DSYNC);
- if (fd < 0) {
- if (errno == ENOENT)
- continue;
-
- sd_eprintf("failed to open epoch %"PRIu32" log", epoch);
- return -1;
- }
-
- ret = xread(fd, nodes_v0, sizeof(nodes_v0));
- if (ret < 0) {
- sd_eprintf("failed to read epoch %"PRIu32" log", epoch);
- close(fd);
- return ret;
- }
-
- nr_nodes = ret / sizeof(nodes_v0[0]);
- for (i = 0; i < nr_nodes; i++) {
- memcpy(&nodes_v1[i].nid, &nodes_v0[i].nid,
- sizeof(struct node_id_v1));
- nodes_v1[i].nr_vnodes = nodes_v0[i].nr_vnodes;
- nodes_v1[i].zone = nodes_v0[i].zone;
- nodes_v1[i].space = 0;
- }
-
- len = sizeof(nodes_v1[0]) * nr_nodes;
- ret = xpwrite(fd, nodes_v1, len, 0);
- if (ret != len) {
- sd_eprintf("failed to write epoch %"PRIu32" log",
- epoch);
- close(fd);
- return -1;
- }
-
- t = (time_t *)&nodes_v0[nr_nodes];
-
- ret = xpwrite(fd, t, sizeof(*t), len);
- if (ret != sizeof(*t)) {
- sd_eprintf("failed to write time to epoch %"
- PRIu32" log", epoch);
- close(fd);
- return -1;
- }
-
- close(fd);
- }
+ for_each_epoch(update_epoch_from_v0_to_v1);
return ret;
}
--
1.7.9.5
More information about the sheepdog
mailing list