예제 #1
0
파일: cmdfile.c 프로젝트: zmanda/amanda
cmddatas_t *
remove_cmd_in_cmdfile(
    cmddatas_t *cmddatas,
    int         id)
{
    cmddatas_t *new_cmddatas;

    // take the lock and read
    new_cmddatas = read_cmdfile(cmddatas->lock->filename);

    // remove the cmd id
    g_hash_table_remove(new_cmddatas->cmdfile, GINT_TO_POINTER(id));

    // write
    write_cmdfile(new_cmddatas);
    close_cmdfile(cmddatas);
    return new_cmddatas;
}
예제 #2
0
파일: cmdfile.c 프로젝트: zmanda/amanda
cmddatas_t *
remove_working_in_cmdfile(
    cmddatas_t *cmddatas,
    pid_t       pid)
{
    cmddatas_t *new_cmddatas;

    // take the lock and read
    new_cmddatas = read_cmdfile(cmddatas->lock->filename);

    // remove if same pid
    g_hash_table_foreach(new_cmddatas->cmdfile, &cmdfile_remove_working, &pid);

    // write
    write_cmdfile(new_cmddatas);
    close_cmdfile(cmddatas);
    return new_cmddatas;
}
예제 #3
0
파일: cmdfile.c 프로젝트: neepher/amanda
cmddatas_t *
add_cmd_in_cmdfile(
    cmddatas_t *cmddatas,
    cmddata_t  *cmddata)
{
    cmddatas_t *new_cmddatas;

    // take the lock and read
    new_cmddatas = read_cmdfile(cmddatas->lock->filename);

    // add the cmd
    new_cmddatas->max_id++;
    cmddata->id = new_cmddatas->max_id;
    g_hash_table_insert(new_cmddatas->cmdfile,
		        GINT_TO_POINTER(new_cmddatas->max_id), cmddata);

    // write
    write_cmdfile(new_cmddatas);
    close_cmdfile(cmddatas);
    return new_cmddatas;
}
예제 #4
0
파일: cmdfile.c 프로젝트: zmanda/amanda
cmddatas_t *
change_cmd_in_cmdfile(
    cmddatas_t  *cmddatas,
    int          id,
    cmdstatus_t  status,
    off_t        size)
{
    cmddatas_t *new_cmddatas;
    cmddata_t  *cmddata;

    // take the lock and read
    new_cmddatas = read_cmdfile(cmddatas->lock->filename);

    // update status for cmd id in cmddatas and new_cmddatas
    cmddata = g_hash_table_lookup(new_cmddatas->cmdfile, GINT_TO_POINTER(id));
    cmddata->status = status;
    cmddata->size   = size;

    // write
    write_cmdfile(new_cmddatas);
    close_cmdfile(cmddatas);
    return new_cmddatas;
}
예제 #5
0
파일: cmdfile.c 프로젝트: zmanda/amanda
cmddatas_t *
add_cmd_in_cmdfile(
    cmddatas_t *cmddatas,
    cmddata_t  *cmddata)
{
    cmddatas_t *new_cmddatas;

    // take the lock and read
    new_cmddatas = read_cmdfile(cmddatas->lock->filename);

    // add the cmd
    new_cmddatas->max_id++;
    cmddata->id = new_cmddatas->max_id;
    if (cmddata->operation == CMD_RESTORE && cmddata->working_pid == 0)
	cmddata->expire = time(NULL) + EXPIRE_DELAY;
    g_hash_table_insert(new_cmddatas->cmdfile,
		        GINT_TO_POINTER(new_cmddatas->max_id), cmddata);

    // write
    write_cmdfile(new_cmddatas);
    close_cmdfile(cmddatas);
    return new_cmddatas;
}
예제 #6
0
파일: cmdfile.c 프로젝트: zmanda/amanda
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;
}
예제 #7
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;
}