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 checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list