1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-22 17:35:59 +03:00

lvmpolld: reinstate internal progress info tracking

This commit is contained in:
Ondrej Kozina 2016-03-09 18:02:30 +01:00
parent 8f01ee3035
commit 542d0c4bff
3 changed files with 80 additions and 6 deletions

View File

@ -203,6 +203,60 @@ static int read_single_line(struct lvmpolld_thread_data *data, int err)
return (r > 0);
}
static const char *keyword(const enum poll_type type)
{
switch (type) {
case PVMOVE:
return "Moved";
case CONVERT:
return "Converted";
case MERGE: /* fall through */
case MERGE_THIN:
return "Merged";
default:
return NULL;
}
}
static void parse_percents(struct lvmpolld_lv *pdlv, const char *line)
{
char *endptr, *keyw, *nr;
dm_percent_t perc;
double d;
if (!(keyw = strstr(line, keyword(pdlv->type))) || keyw == line
|| !strchr(keyw, DM_PERCENT_CHAR)) {
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX,
"parsing percentage from lvm2 command failed");
return;
}
nr = strpbrk(keyw, "+-0123456789");
if (!nr) {
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX,
"parsing percentage from lvm2 command failed");
return;
}
d = strtod(nr, &endptr);
if (nr == endptr) {
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX,
"parsing percentage from lvm2 command failed");
return;
} else if (d > 100.0) {
WARN(pdlv->ls, "%s: %s", PD_LOG_PREFIX,
"parsing percentage from lvm2 command returned invalid value");
return;
}
perc = dm_make_percent((uint64_t)(d * DM_PERCENT_1), DM_PERCENT_100);
DEBUGLOG(pdlv->ls, "%s: %s %.1f%%", PD_LOG_PREFIX,
"parsed", dm_percent_to_float(perc));
pdlv_set_percents(pdlv, perc);
}
static void update_idle_state(struct lvmpolld_state *ls)
{
if (!ls->idle)
@ -274,6 +328,9 @@ static int poll_for_output(struct lvmpolld_lv *pdlv, struct lvmpolld_thread_data
assert(read_single_line(data, 0)); /* may block indef. anyway */
INFO(pdlv->ls, "%s: PID %d: %s: '%s'", LVM2_LOG_PREFIX,
pdlv->cmd_pid, "STDOUT", data->line);
if (pdlv->parse_output_fn)
pdlv->parse_output_fn(pdlv, data->line);
} else if (fds[0].revents) {
if (fds[0].revents & POLLHUP)
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "caught POLLHUP");
@ -329,6 +386,8 @@ static int poll_for_output(struct lvmpolld_lv *pdlv, struct lvmpolld_thread_data
while (read_single_line(data, 0)) {
assert(r > 0);
INFO(pdlv->ls, "%s: PID %d: %s: %s", LVM2_LOG_PREFIX, pdlv->cmd_pid, "STDOUT", data->line);
if (pdlv->parse_output_fn)
pdlv->parse_output_fn(pdlv, data->line);
}
if (fds[1].fd >= 0)
while (read_single_line(data, 1)) {
@ -562,7 +621,8 @@ static struct lvmpolld_lv *construct_pdlv(request req, struct lvmpolld_state *ls
unsigned handle_missing_pvs = daemon_request_int(req, LVMPD_PARM_HANDLE_MISSING_PVS, 0);
pdlv = pdlv_create(ls, id, vgname, lvname, sysdir, type,
interval, uinterval, pdst);
interval, uinterval, pdst,
abort_polling ? NULL : parse_percents);
if (!pdlv) {
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to create internal LV data structure.");

View File

@ -91,7 +91,8 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
const char *vgname, const char *lvname,
const char *sysdir, enum poll_type type,
const char *sinterval, unsigned pdtimeout,
struct lvmpolld_store *pdst)
struct lvmpolld_store *pdst,
lvmpolld_parse_output_fn_t parse_fn)
{
char *lvmpolld_id = dm_strdup(id), /* copy */
*full_lvname = _construct_full_lvname(vgname, lvname), /* copy */
@ -108,7 +109,8 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
.pdtimeout = pdtimeout < MIN_POLLING_TIMEOUT ? MIN_POLLING_TIMEOUT : pdtimeout,
.cmd_state = { .retcode = -1, .signal = 0 },
.pdst = pdst,
.init_rq_count = 1
.init_rq_count = 1,
.parse_output_fn = parse_fn
}, *pdlv = (struct lvmpolld_lv *) dm_malloc(sizeof(struct lvmpolld_lv));
if (!pdlv || !tmp.lvid || !tmp.lvname || !tmp.lvm_system_dir_env || !tmp.sinterval)
@ -183,6 +185,13 @@ void pdlv_set_error(struct lvmpolld_lv *pdlv, unsigned error)
pdlv_unlock(pdlv);
}
void pdlv_set_percents(struct lvmpolld_lv *pdlv, dm_percent_t percent)
{
pdlv_lock(pdlv);
pdlv->percent = percent;
pdlv_unlock(pdlv);
}
void pdlv_set_polling_finished(struct lvmpolld_lv *pdlv, unsigned finished)
{
pdlv_lock(pdlv);

View File

@ -19,6 +19,9 @@
struct buffer;
struct lvmpolld_state;
struct lvmpolld_lv;
typedef void (*lvmpolld_parse_output_fn_t) (struct lvmpolld_lv *pdlv, const char *line);
enum poll_type {
PVMOVE = 0,
@ -54,6 +57,7 @@ struct lvmpolld_lv {
const char *const sinterval;
const char *const lvm_system_dir_env;
struct lvmpolld_store *const pdst;
lvmpolld_parse_output_fn_t parse_output_fn;
const char *const *cmdargv;
const char *const *cmdenvp;
@ -65,13 +69,12 @@ struct lvmpolld_lv {
/* block of shared variables protected by lock */
struct lvmpolld_cmd_stat cmd_state;
dm_percent_t percent;
unsigned init_rq_count; /* for debuging purposes only */
unsigned polling_finished:1; /* no more updates */
unsigned error:1; /* unrecoverable error occured in lvmpolld */
};
typedef void (*lvmpolld_parse_output_fn_t) (struct lvmpolld_lv *pdlv, const char *line);
/* TODO: replace with configuration option */
#define MIN_POLLING_TIMEOUT 60
@ -101,7 +104,8 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
const char *vgname, const char *lvname,
const char *sysdir, enum poll_type type,
const char *sinterval, unsigned pdtimeout,
struct lvmpolld_store *pdst);
struct lvmpolld_store *pdst,
lvmpolld_parse_output_fn_t parse_fn);
/* only call with appropriate struct lvmpolld_store lock held */
void pdlv_destroy(struct lvmpolld_lv *pdlv);
@ -138,6 +142,7 @@ unsigned pdlv_get_polling_finished(struct lvmpolld_lv *pdlv);
struct lvmpolld_lv_state pdlv_get_status(struct lvmpolld_lv *pdlv);
void pdlv_set_cmd_state(struct lvmpolld_lv *pdlv, const struct lvmpolld_cmd_stat *cmd_state);
void pdlv_set_error(struct lvmpolld_lv *pdlv, unsigned error);
void pdlv_set_percents(struct lvmpolld_lv *pdlv, dm_percent_t percent);
void pdlv_set_polling_finished(struct lvmpolld_lv *pdlv, unsigned finished);
/*