Example #1
0
static void
locking_slave(int in_fd, int out_fd)
{
    char cmd;
    int rv;
    file_lock *lock = file_lock_new(TEST_FILENAME);
    gboolean locked = 0;

    while (1) {
	if (!pipeget(in_fd, &cmd))
	    cmd = 'q';

	switch (cmd) {
	    case 'q': /* q = quit */
		tu_dbg("slave: quitting\n");
		file_lock_free(lock);
		lock = NULL;
		return;

	    case 'l': /* l = try locking; reply with 'y' or 'n' */
		g_assert(!locked);
		rv = file_lock_lock(lock);
		if (rv == -1) {
		    g_fprintf(stderr, "file_lock_lock: %s\n",
				    strerror(errno));
		    return;
		}
		tu_dbg("slave: lock attempt => %s\n", (rv == 1)? "n" : "y");
		pipeput(out_fd, (rv == 1)? "n" : "y");
		if (rv != 1)
		    locked = 1;
		break;

	    case 'i': /* i = increment counter, reply with new value */
		g_assert(locked);
		if (!inc_counter(lock))
		    return;
		tu_dbg("slave: inc'd to %c\n", lock->data[0]);
		pipeput(out_fd, lock->data);
		break;

	    case 'u': /* u = try unlocking; reply with 'k' */
		g_assert(locked);
		rv = file_lock_unlock(lock);
		if (rv != 0) {
		    g_fprintf(stderr, "file_lock_unlock: %s\n",
			    strerror(errno));
		    return;
		}
		tu_dbg("slave: unlocked\n");
		pipeput(out_fd, "k");
		locked = 0;
		break;

	    default:
		return;
	}
    }
}
Example #2
0
cmddatas_t *
read_cmdfile(
    char *filename)
{
    cmddatas_t *cmddatas = g_new0(cmddatas_t, 1);
    char **xlines;
    int    i;
    pid_t  pids[NB_PIDS];
    pid_t  new_pids[NB_PIDS];
    int    nb_pids = 0;
    int    result;
    gboolean generic_command_restore = FALSE;
    gboolean specific_command_restore = FALSE;

    cmddatas->lock = file_lock_new(filename);
    cmddatas->cmdfile = g_hash_table_new_full(g_direct_hash, g_direct_equal,
					      NULL, &free_cmddata);
    need_rewrite = FALSE;

    // open
    while ((result = file_lock_lock(cmddatas->lock)) == 1) {
        sleep(1);
    }
    if (result != 0) {
        g_debug("read_cmdfile open failed: %s", strerror(errno));
    }

    if (!cmddatas->lock->data) {
	cmddatas->version = 1;
	cmddatas->max_id = 0;
	return cmddatas;
    }
    xlines = g_strsplit(cmddatas->lock->data, "\n", 0);

    // read
    if (sscanf(xlines[0], "VERSION %d", &cmddatas->version) != 1) {};
    if (sscanf(xlines[1], "ID %d", &cmddatas->max_id) != 1) {};

    // read cmd
    for (i=2; xlines[i] != NULL; i++) {
	cmddata_t *cmddata = cmdfile_parse_line(xlines[i],
				&generic_command_restore,
				&specific_command_restore);

	if (!cmddata) continue;
	/* validate working_pid */
	if (!checked_working_pid && cmddata->working_pid != 0) {
	    int   i;

	    for (i = 0; i < nb_pids; i++) {
		if (pids[i] == cmddata->working_pid) {
		    cmddata->working_pid = new_pids[i];
		    i += 100;
		    continue;
		}
	    }
	    if (nb_pids < NB_PIDS) {
		pids[nb_pids] = cmddata->working_pid;
		if (kill(cmddata->working_pid, 0) != 0)
		    cmddata->working_pid =0;
		new_pids[nb_pids] = cmddata->working_pid;
		nb_pids++;
	    }
	}

	g_hash_table_insert(cmddatas->cmdfile, GINT_TO_POINTER(cmddata->id), cmddata);
    }

    if (generic_command_restore) {
	if (specific_command_restore) {
	    /* set expire to NOW+24h of all genric command_restore */
	    g_hash_table_foreach(cmddatas->cmdfile, &cmdfile_set_expire, NULL);
	} else {
	    /* check start_time of all generic command_restore and remove them */
	    g_hash_table_foreach(cmddatas->cmdfile, &cmdfile_set_to_DONE, NULL);
	}
    }
    g_strfreev(xlines);
    checked_working_pid = 1;

    if (need_rewrite) {
	write_cmdfile(cmddatas);
	return read_cmdfile(filename);
    }
    return cmddatas;
}
Example #3
0
static int
locking_master(int in_fd, int out_fd)
{
    file_lock *lock = file_lock_new(TEST_FILENAME);
    int rv;
    char slaveres;

    /* start by locking here and incrementing the value */
    rv = file_lock_lock(lock);
    if (rv == -1) {
	g_fprintf(stderr, "file_lock_lock: %s\n", strerror(errno));
	return 0;
    }
    g_assert(rv != 1); /* not already locked */
    tu_dbg("master: locked\n");

    if (!inc_counter(lock))
	return 0;

    g_assert(lock->data[0] == 'b');
    tu_dbg("master: inc'd to b\n");

    /* unlock and re-lock */
    rv = file_lock_unlock(lock);
    if (rv != 0) {
	g_fprintf(stderr, "file_lock_unlock: %s\n", strerror(errno));
	return 0;
    }
    tu_dbg("master: unlocked\n");

    rv = file_lock_lock(lock);
    if (rv == -1) {
	g_fprintf(stderr, "file_lock_lock: %s\n", strerror(errno));
	return 0;
    }
    g_assert(rv != 1); /* not already locked */
    tu_dbg("master: locked\n");

    /* inc it again */
    g_assert(lock->data[0] == 'b');
    inc_counter(lock);
    g_assert(lock->data[0] == 'c');
    tu_dbg("master: inc'd to c\n");

    /* the slave should fail to get a lock now */
    pipeput(out_fd, "l");
    g_assert(pipeget(in_fd, &slaveres));
    g_assert(slaveres == 'n');

    /* and, finally unlock */
    rv = file_lock_unlock(lock);
    if (rv != 0) {
	g_fprintf(stderr, "file_lock_unlock: %s\n", strerror(errno));
	return 0;
    }
    tu_dbg("master: unlocked\n");

    /* the slave should succeed now */
    pipeput(out_fd, "l");
    g_assert(pipeget(in_fd, &slaveres));
    g_assert(slaveres == 'y');

    pipeput(out_fd, "i");
    g_assert(pipeget(in_fd, &slaveres));
    g_assert(slaveres == 'd');

    /* master shouldn't be able to lock now */
    rv = file_lock_lock(lock);
    if (rv == -1) {
	g_fprintf(stderr, "file_lock_lock: %s\n", strerror(errno));
	return 0;
    }
    g_assert(rv == 1); /* already locked */
    tu_dbg("master: lock attempt failed (as expected)\n");

    pipeput(out_fd, "i");
    g_assert(pipeget(in_fd, &slaveres));
    g_assert(slaveres == 'e');

    /* get the slave to unlock */
    pipeput(out_fd, "u");
    g_assert(pipeget(in_fd, &slaveres));
    g_assert(slaveres == 'k');

    /* we should get a lock now */
    rv = file_lock_lock(lock);
    if (rv == -1) {
	g_fprintf(stderr, "file_lock_lock: %s\n", strerror(errno));
	return 0;
    }
    g_assert(rv != 1); /* not already locked */
    tu_dbg("master: lock attempt succeeded\n");

    g_assert(lock->data[0] == 'e');

    /* leave it unlocked, just to see what happens */

    return 1;
}
Example #4
0
cmddatas_t *
read_cmdfile(
    char *filename)
{
    cmddatas_t *cmddatas = g_new0(cmddatas_t, 1);
    cmddata_t  *cmddata;
    char  *s, *fp, *operation;
    char   ch;
    char **xlines;
    int    i;
    int    pid;
    pid_t  pids[NB_PIDS];
    pid_t  new_pids[NB_PIDS];
    int    nb_pids = 0;
    int    result;
    gboolean generic_command_restore = FALSE;
    gboolean specific_command_restore = FALSE;

    cmddatas->lock = file_lock_new(filename);
    cmddatas->cmdfile = g_hash_table_new_full(g_direct_hash, g_direct_equal,
                        NULL, &free_cmddata);
    need_rewrite = FALSE;

    // open
    while ((result = file_lock_lock(cmddatas->lock)) == 1) {
        sleep(1);
    }
    if (result != 0) {
        g_debug("read_cmdfile open failed: %s", strerror(errno));
    }

    if (!cmddatas->lock->data) {
        cmddatas->version = 1;
        cmddatas->max_id = 0;
        return cmddatas;
    }
    xlines = g_strsplit(cmddatas->lock->data, "\n", 0);

    // read
    if (sscanf(xlines[0], "VERSION %d", &cmddatas->version) != 1) {};
    if (sscanf(xlines[1], "ID %d", &cmddatas->max_id) != 1) {};

    // read cmd
    for (i=2; xlines[i] != NULL; i++) {
        int id;
        s = xlines[i];
        if (*s == '\0') continue;
        ch = *s++;
        skip_whitespace(s, ch);
        if (ch == '\0' || sscanf((s - 1), "%d", &id) != 1) {
            continue;
        }
        skip_integer(s, ch);
        skip_whitespace(s, ch);
        operation = s - 1;
        skip_non_whitespace(s, ch);
        s[-1] = '\0';
        if (!g_str_equal(operation, "FLUSH") &&
                !g_str_equal(operation, "COPY") &&
                !g_str_equal(operation, "RESTORE")) {
            g_debug("BAD operation %s: %s", operation, s);
            continue;
        }
        cmddata = g_new0(cmddata_t, 1);
        cmddata->id = id;
        skip_whitespace(s, ch);
        fp = s - 1;
        skip_non_whitespace(s, ch);
        s[-1] = '\0';
        cmddata->config = unquote_string(fp);
        if (g_str_equal(operation, "FLUSH")) {
            cmddata->operation = CMD_FLUSH;
            skip_whitespace(s,ch);
            fp = s - 1;
            skip_quoted_string(s, ch);
            s[-1] = '\0';
            cmddata->holding_file = unquote_string(fp);
        } else if (g_str_equal(operation, "COPY")) {
            char *src_labels;
            char *slabels;
            char *a;

            cmddata->operation = CMD_COPY;
            skip_whitespace(s,ch);
            fp = s - 1;
            skip_quoted_string(s, ch);
            s[-1] = '\0';
            cmddata->src_storage = unquote_string(fp);
            skip_whitespace(s,ch);
            fp = s - 1;
            skip_quoted_string(s, ch);
            s[-1] = '\0';
            cmddata->src_pool = unquote_string(fp);
            skip_whitespace(s,ch);
            fp = s - 1;
            skip_quoted_string(s, ch);
            s[-1] = '\0';
            cmddata->src_label = unquote_string(fp);
            skip_whitespace(s,ch);
            fp = s - 1;
            skip_integer(s, ch);
            s[-1] = '\0';
            cmddata->src_fileno = atoi(fp);

            skip_whitespace(s,ch);
            fp = s - 1;
            skip_quoted_string(s, ch);
            s[-1] = '\0';
            slabels = src_labels = unquote_string(fp);
            cmddata->src_labels_str = g_strdup(src_labels);
            a = strstr(slabels, " ;");
            if (a) {
                slabels = a+2;
                while ((a = strstr(slabels, " ;"))) {
                    *a = '\0';
                    cmddata->src_labels = g_slist_append(cmddata->src_labels, g_strdup(slabels));
                    slabels = a+2;
                }
            }
            g_free(src_labels);

            skip_whitespace(s,ch);
            fp = s - 1;
            skip_integer(s, ch);
            s[-1] = '\0';
            cmddata->start_time = atoll(fp);
        } else if (g_str_equal(operation, "RESTORE")) {
            cmddata->operation = CMD_RESTORE;
            skip_whitespace(s,ch);
            fp = s - 1;
            skip_quoted_string(s, ch);
            s[-1] = '\0';
            cmddata->src_storage = unquote_string(fp);
            skip_whitespace(s,ch);
            fp = s - 1;
            skip_quoted_string(s, ch);
            s[-1] = '\0';
            cmddata->src_pool = unquote_string(fp);
            skip_whitespace(s,ch);
            fp = s - 1;
            skip_quoted_string(s, ch);
            s[-1] = '\0';
            if (g_str_equal(cmddata->src_pool, "HOLDING")) {
                cmddata->holding_file = unquote_string(fp);
            } else {
                cmddata->src_label = unquote_string(fp);
            }
            skip_whitespace(s,ch);
            fp = s - 1;
            skip_integer(s, ch);
            s[-1] = '\0';
            cmddata->src_fileno = atoi(fp);

            skip_whitespace(s,ch);
            fp = s - 1;
            skip_integer(s, ch);
            s[-1] = '\0';
            cmddata->expire = atoll(fp);
        } else {
        }
        skip_whitespace(s, ch);
        fp = s - 1;
        skip_quoted_string(s, ch);
        s[-1] = '\0';
        cmddata->hostname = unquote_string(fp);
        skip_whitespace(s, ch);
        fp = s - 1;
        skip_quoted_string(s, ch);
        s[-1] = '\0';
        cmddata->diskname = unquote_string(fp);
        skip_whitespace(s, ch);
        fp = s - 1;
        skip_quoted_string(s, ch);
        s[-1] = '\0';
        cmddata->dump_timestamp = unquote_string(fp);
        skip_whitespace(s,ch);
        fp = s - 1;
        skip_quoted_string(s, ch);
        s[-1] = '\0';
        cmddata->level = atoi(fp);
        skip_whitespace(s, ch);
        if (cmddata->operation != CMD_RESTORE) {
            fp = s - 1;
            skip_quoted_string(s, ch);
            s[-1] = '\0';
            cmddata->dst_storage = unquote_string(fp);
            skip_whitespace(s, ch);
        }
        fp = s - 1;
        skip_non_whitespace(s, ch);
        s[-1] = '\0';
        if (sscanf(fp, "WORKING:%d", &pid) != 1) {
        }
        cmddata->working_pid = pid;
        if (cmddata->operation == CMD_RESTORE) {
            if (cmddata->working_pid == 0)
                generic_command_restore = TRUE;
            else
                specific_command_restore = TRUE;
        }
        skip_whitespace(s, ch);
        fp = s - 1;
        skip_non_whitespace(s, ch);
        s[-1] = '\0';
        if (g_str_equal(fp, "DONE")) {
            cmddata->status = CMD_DONE;
        } else if (g_str_equal(fp, "TODO")) {
            cmddata->status = CMD_TODO;
        } else if (strncmp(fp, "PARTIAL", 7) == 0) {
            long long lsize;
            cmddata->status = CMD_PARTIAL;
            if (sscanf(fp, "PARTIAL:%lld", &lsize) != 1) {
            } else {
                cmddata->size = lsize;
            }
        } else {
        }

        /* validate working_pid */
        if (!checked_working_pid && cmddata->working_pid != 0) {
            int   i;

            for (i = 0; i < nb_pids; i++) {
                if (pids[i] == cmddata->working_pid) {
                    cmddata->working_pid = new_pids[i];
                    i += 100;
                    continue;
                }
            }
            if (nb_pids < NB_PIDS) {
                pids[nb_pids] = cmddata->working_pid;
                if (kill(cmddata->working_pid, 0) != 0)
                    cmddata->working_pid =0;
                new_pids[nb_pids] = cmddata->working_pid;
                nb_pids++;
            }
        }

        g_hash_table_insert(cmddatas->cmdfile, GINT_TO_POINTER(cmddata->id), cmddata);
    }

    if (generic_command_restore) {
        if (specific_command_restore) {
            /* set expire to NOW+24h of all genric command_restore */
            g_hash_table_foreach(cmddatas->cmdfile, &cmdfile_set_expire, NULL);
        } else {
            /* check start_time of all generic command_restore and remove them */
            g_hash_table_foreach(cmddatas->cmdfile, &cmdfile_set_to_DONE, NULL);
        }
    }
    g_strfreev(xlines);
    checked_working_pid = 1;

    if (need_rewrite) {
        write_cmdfile(cmddatas);
        return read_cmdfile(filename);
    }
    return cmddatas;
}