summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Kozina <okozina@redhat.com>2016-03-09 18:02:30 +0100
committerOndrej Kozina <okozina@redhat.com>2016-03-10 12:20:59 +0100
commit542d0c4bff23cb46eb156e25f995c563334e8ba2 (patch)
tree0728b41d92e5f586c5f3111df729d4d467623858
parent8f01ee3035cf5ede72a8653fd1dca2987db29475 (diff)
downloadlvm2-542d0c4bff23cb46eb156e25f995c563334e8ba2.tar.gz
lvmpolld: reinstate internal progress info tracking
-rw-r--r--daemons/lvmpolld/lvmpolld-core.c62
-rw-r--r--daemons/lvmpolld/lvmpolld-data-utils.c13
-rw-r--r--daemons/lvmpolld/lvmpolld-data-utils.h11
3 files changed, 80 insertions, 6 deletions
diff --git a/daemons/lvmpolld/lvmpolld-core.c b/daemons/lvmpolld/lvmpolld-core.c
index fd7327241..c6f02a4de 100644
--- a/daemons/lvmpolld/lvmpolld-core.c
+++ b/daemons/lvmpolld/lvmpolld-core.c
@@ -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.");
diff --git a/daemons/lvmpolld/lvmpolld-data-utils.c b/daemons/lvmpolld/lvmpolld-data-utils.c
index 99883f816..b141f0ace 100644
--- a/daemons/lvmpolld/lvmpolld-data-utils.c
+++ b/daemons/lvmpolld/lvmpolld-data-utils.c
@@ -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);
diff --git a/daemons/lvmpolld/lvmpolld-data-utils.h b/daemons/lvmpolld/lvmpolld-data-utils.h
index 5bb5c863d..215886516 100644
--- a/daemons/lvmpolld/lvmpolld-data-utils.h
+++ b/daemons/lvmpolld/lvmpolld-data-utils.h
@@ -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);
/*