Changeset: 71ef68f4ae0a for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=71ef68f4ae0a
Modified Files:
tools/merovingian/client/monetdb.c
tools/merovingian/daemon/controlrunner.c
tools/merovingian/utils/database.c
Branch: wlcr
Log Message:
Fork and execute rsync
This is the first step of the protocol (see the comment above the function
db_master)
diffs (137 lines):
diff --git a/tools/merovingian/client/monetdb.c
b/tools/merovingian/client/monetdb.c
--- a/tools/merovingian/client/monetdb.c
+++ b/tools/merovingian/client/monetdb.c
@@ -1635,8 +1635,10 @@ command_master(int argc, char *argv[])
exit(1);
}
- if (argc == 3)
+ if (argc == 3) {
target_path = strdup(argv[2]);
+ argv[2] = NULL;
+ }
if ((e = MEROgetStatus(&orig, NULL)) != NULL) {
fprintf(stderr, "master: %s\n", e);
@@ -1653,6 +1655,8 @@ command_master(int argc, char *argv[])
snprintf(cmd, len, "master path=%s", target_path);
simple_argv_cmd(argv[0], orig, cmd,
"set database as master", NULL);
+ free(target_path);
+ free(cmd);
} else {
simple_argv_cmd(argv[0], orig, "master",
"set database as master", NULL);
diff --git a/tools/merovingian/daemon/controlrunner.c
b/tools/merovingian/daemon/controlrunner.c
--- a/tools/merovingian/daemon/controlrunner.c
+++ b/tools/merovingian/daemon/controlrunner.c
@@ -628,7 +628,10 @@ static void ctl_handle_client(
send_client("!");
free(e);
} else {
-
+ Mfprintf(_mero_ctlout, "%s: set
database '%s' to master mode\n",
+ origin, q);
+ len = snprintf(buf2, sizeof(buf2),
"OK\n");
+ send_client("=");
}
} else if (strncmp(p, "name=", strlen("name=")) == 0) {
char *e;
diff --git a/tools/merovingian/utils/database.c
b/tools/merovingian/utils/database.c
--- a/tools/merovingian/utils/database.c
+++ b/tools/merovingian/utils/database.c
@@ -374,16 +374,83 @@ char *db_release(char *dbname) {
return(NULL);
}
-char *db_master(char *dbname) {
- /* sabdb *stats; */
- /* char *e; */
- /* char buf[8096]; */
+/*
+ * The following functions require rsync to be installed and also the system
+ * calls exec and wait.
+ *
+ * They should be compiled conditionally.
+ */
- /* if ((e = msab_getStatus(&stats, dbname)) != NULL) { */
- /* snprintf(buf, sizeof(buf), "internal error: %s", e); */
- /* free(e); */
- /* return(strdup(buf)); */
- /* } */
- (void)dbname;
- return strdup("executing db_master");
+#include <sys/types.h>
+#include <sys/wait.h>
+
+static char *
+synchronize_files(char *source, char *destination) {
+ int status = 0;
+ pid_t pid = fork();
+ char buf[8096];
+
+ if (pid == -1) {
+ snprintf(buf, sizeof(buf), "fork for rsync failed");
+ return strdup(buf);
+ }
+ if (pid) {
+ wait(&status);
+ }
+ else {
+ /* make sure that the source path ends in '/' */
+ char *src;
+ if (source[strlen(source)] == '/') {
+ src = strdup(source);
+ }
+ else {
+ snprintf(buf, sizeof(buf), "%s/", source);
+ src = strdup(buf);
+ }
+ execlp("rsync", "rsync", "-ar",
+ src, destination, NULL);
+ free(src);
+ }
+
+ return NULL;
}
+/*
+ The master protocol:
+ 1. rsync the files to the remote location
+ 2. lock the db
+ 3. stop the db
+ a. forcibly fail currently running transactions
+ b. flush the dirty bats
+ c. merge deltas?
+ 4. rsync again
+ 5. release the db
+ */
+char *
+db_master(char *dbname) {
+ sabdb *stats;
+ char *e;
+ char *destination;
+ char buf[8096];
+
+ if ((e = msab_getStatus(&stats, dbname)) != NULL) {
+ snprintf(buf, sizeof(buf), "internal error: %s", e);
+ free(e);
+ return(strdup(buf));
+ }
+
+ /* TODO: This should not be hardcoded */
+ snprintf(buf, sizeof(buf), "%s/master", stats->path);
+ destination = strdup(buf);
+
+ /* Step 1 of the protocol */
+ if ((e = synchronize_files(stats->path, destination)) != NULL) {
+ snprintf(buf, sizeof(buf), "internal error: %s", e);
+ free(e);
+ free(destination);
+ return(strdup(buf));
+ }
+
+ free(destination);
+
+ return NULL;
+}
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list