summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Kozina <okozina@redhat.com>2015-03-03 17:30:25 +0100
committerOndrej Kozina <okozina@redhat.com>2015-04-01 11:01:22 +0200
commit4a4513dbcb74c657025effe89a15458d197c6eeb (patch)
tree64ad43a906d635350f4424313f2b0d97cf88a5dd
parent83def84504a545a32da1c6ebd71bd2c9d99f3c71 (diff)
downloadlvm2-4a4513dbcb74c657025effe89a15458d197c6eeb.tar.gz
lvmpolld: implement dump request
-rw-r--r--daemons/lvmpolld/lvmpolld-cmd-utils.c7
-rw-r--r--daemons/lvmpolld/lvmpolld-cmd-utils.h2
-rw-r--r--daemons/lvmpolld/lvmpolld-core.c61
-rw-r--r--daemons/lvmpolld/lvmpolld-data-utils.c76
-rw-r--r--daemons/lvmpolld/lvmpolld-data-utils.h6
-rw-r--r--daemons/lvmpolld/lvmpolld-protocol.h1
6 files changed, 147 insertions, 6 deletions
diff --git a/daemons/lvmpolld/lvmpolld-cmd-utils.c b/daemons/lvmpolld/lvmpolld-cmd-utils.c
index e33d147de..3563b7246 100644
--- a/daemons/lvmpolld/lvmpolld-cmd-utils.c
+++ b/daemons/lvmpolld/lvmpolld-cmd-utils.c
@@ -28,6 +28,11 @@ static const char *const const polling_ops[] = { [PVMOVE] = LVMPD_REQ_PVMOVE,
[MERGE] = LVMPD_REQ_MERGE,
[MERGE_THIN] = LVMPD_REQ_MERGE_THIN };
+const char *polling_op(enum poll_type type)
+{
+ return type < POLL_TYPE_MAX ? polling_ops[type] : "<undefined>";
+}
+
static int add_to_cmd_arr(const char ***cmdargv, const char *str, unsigned *index, unsigned renameme)
{
const char **newargv = *cmdargv;
@@ -98,7 +103,7 @@ err:
/* FIXME: in fact exclude should be va list */
static int copy_env(const char ***cmd_envp, unsigned *i, unsigned renameme, const char *exclude)
{
- const char * const* tmp = environ;
+ const char * const* tmp = (const char * const*) environ;
if (!tmp)
return 0;
diff --git a/daemons/lvmpolld/lvmpolld-cmd-utils.h b/daemons/lvmpolld/lvmpolld-cmd-utils.h
index ada794db9..f5b42d453 100644
--- a/daemons/lvmpolld/lvmpolld-cmd-utils.h
+++ b/daemons/lvmpolld/lvmpolld-cmd-utils.h
@@ -22,4 +22,6 @@
const char **cmdargv_ctr(const lvmpolld_lv_t *pdlv, const char *lvm_binary, unsigned abort, unsigned handle_missing_pvs);
const char **cmdenvp_ctr(const lvmpolld_lv_t *pdlv);
+const char *polling_op(enum poll_type);
+
#endif /* _LVM_LVMPOLLD_CMD_UTILS_H */
diff --git a/daemons/lvmpolld/lvmpolld-core.c b/daemons/lvmpolld/lvmpolld-core.c
index e6cee2469..ac42bdccb 100644
--- a/daemons/lvmpolld/lvmpolld-core.c
+++ b/daemons/lvmpolld/lvmpolld-core.c
@@ -129,19 +129,29 @@ static int read_single_line(char **line, size_t *lsize, FILE *file)
return (r > 0);
}
+static void lvmpolld_stores_lock(lvmpolld_state_t *ls)
+{
+ pdst_lock(&ls->id_to_pdlv_poll);
+ pdst_lock(&ls->id_to_pdlv_abort);
+}
+
+static void lvmpolld_stores_unlock(lvmpolld_state_t *ls)
+{
+ pdst_unlock(&ls->id_to_pdlv_abort);
+ pdst_unlock(&ls->id_to_pdlv_poll);
+}
+
static void update_active_state(lvmpolld_state_t *ls)
{
if (!ls->idle)
return;
- pdst_lock(&ls->id_to_pdlv_poll);
- pdst_lock(&ls->id_to_pdlv_abort);
+ lvmpolld_stores_lock(ls);
ls->idle->is_idle = !ls->id_to_pdlv_poll.active_polling_count &&
!ls->id_to_pdlv_abort.active_polling_count;
- pdst_unlock(&ls->id_to_pdlv_abort);
- pdst_unlock(&ls->id_to_pdlv_poll);
+ lvmpolld_stores_unlock(ls);
}
/* make this configurable */
@@ -641,6 +651,47 @@ static response poll_init(client_handle h, lvmpolld_state_t *ls, request req, en
return daemon_reply_simple(LVMPD_RESP_OK, NULL);
}
+
+static void lvmpolld_global_lock(lvmpolld_state_t *ls)
+{
+ lvmpolld_stores_lock(ls);
+
+ pdst_locked_lock_all_pdlvs(&ls->id_to_pdlv_poll);
+ pdst_locked_lock_all_pdlvs(&ls->id_to_pdlv_abort);
+}
+
+static void lvmpolld_global_unlock(lvmpolld_state_t *ls)
+{
+ pdst_locked_unlock_all_pdlvs(&ls->id_to_pdlv_abort);
+ pdst_locked_unlock_all_pdlvs(&ls->id_to_pdlv_poll);
+
+ lvmpolld_stores_unlock(ls);
+}
+
+static response dump_state(client_handle h, lvmpolld_state_t *ls, request r)
+{
+ response res = { 0 };
+ struct buffer *b = &res.buffer;
+
+ buffer_init(b);
+
+ lvmpolld_global_lock(ls);
+
+ buffer_append(b, "# Registered polling operations\n\n");
+ buffer_append(b, "poll {\n");
+ pdst_locked_dump(&ls->id_to_pdlv_poll, b);
+ buffer_append(b, "}\n\n");
+
+ buffer_append(b, "# Registered abort operations\n\n");
+ buffer_append(b, "abort {\n");
+ pdst_locked_dump(&ls->id_to_pdlv_abort, b);
+ buffer_append(b, "}\n\n");
+
+ lvmpolld_global_unlock(ls);
+
+ return res;
+}
+
static response handler(struct daemon_state s, client_handle h, request r)
{
lvmpolld_state_t *ls = s.private;
@@ -656,6 +707,8 @@ static response handler(struct daemon_state s, client_handle h, request r)
return poll_init(h, ls, r, MERGE_THIN);
else if (!strcmp(rq, LVMPD_REQ_PROGRESS))
return progress_info(h, ls, r);
+ else if (!strcmp(rq, LVMPD_REQ_DUMP))
+ return dump_state(h, ls, r);
else
return reply_fail(REASON_REQ_NOT_IMPLEMENTED);
}
diff --git a/daemons/lvmpolld/lvmpolld-data-utils.c b/daemons/lvmpolld/lvmpolld-data-utils.c
index 80c0ef4d3..1edcc8229 100644
--- a/daemons/lvmpolld/lvmpolld-data-utils.c
+++ b/daemons/lvmpolld/lvmpolld-data-utils.c
@@ -12,8 +12,11 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "config-util.h"
#include "libdevmapper.h"
#include "lvmpolld-data-utils.h"
+#include "lvmpolld-cmd-utils.h"
+#include "lvmpolld-protocol.h"
static char *_construct_full_lvname(const char *vgname, const char *lvname)
{
@@ -117,8 +120,8 @@ lvmpolld_lv_t *pdlv_create(lvmpolld_state_t *ls, const char *id,
return pdlv;
err:
- dm_free((void *)lvmpolld_id);
dm_free((void *)full_lvname);
+ dm_free((void *)lvmpolld_id);
dm_free((void *)lvm_system_dir_env);
dm_free((void *)tmp.sinterval);
dm_free((void *)pdlv);
@@ -198,3 +201,74 @@ void pdst_destroy(lvmpolld_store_t *pdst)
dm_hash_destroy(pdst->store);
pthread_mutex_destroy(&pdst->lock);
}
+
+void pdst_locked_lock_all_pdlvs(const lvmpolld_store_t *pdst)
+{
+ struct dm_hash_node *n;
+
+ dm_hash_iterate(n, pdst->store)
+ pdlv_lock(dm_hash_get_data(pdst->store, n));
+}
+
+void pdst_locked_unlock_all_pdlvs(const lvmpolld_store_t *pdst)
+{
+ struct dm_hash_node *n;
+
+ dm_hash_iterate(n, pdst->store)
+ pdlv_unlock(dm_hash_get_data(pdst->store, n));
+}
+
+static void _pdlv_locked_dump(struct buffer *buff, const lvmpolld_lv_t *pdlv)
+{
+ char tmp[1024];
+ const lvmpolld_cmd_stat_t *cmd_state = &pdlv->cmd_state;
+
+ /* pdlv-section { */
+ if (dm_snprintf(tmp, sizeof(tmp), "\t%s {\n", pdlv->lvmpolld_id) > 0)
+ buffer_append(buff, tmp);
+
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvid=\"%s\"\n", pdlv->lvid) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\ttype=\"%s\"\n", polling_op(pdlv->type)) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvname=\"%s\"\n", pdlv->lvname) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvmpolld_internal_timeout=%d\n", pdlv->pdtimeout) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvm_command_interval=\"%s\"\n", pdlv->sinterval ?: "<undefined>") > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tLVM_SYSTEM_DIR=%s\n",
+ (*pdlv->lvm_system_dir_env ? (pdlv->lvm_system_dir_env + strlen("LVM_SYSTEM_DIR=")) : "<undefined>")) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvm_command_pid=%d\n", pdlv->cmd_pid) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tpolling_finished=%d\n", pdlv->polling_finished) > 0)
+ buffer_append(buff, tmp);
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\tinternal_error_occured=%d\n", pdlv->internal_error) > 0)
+ buffer_append(buff, tmp);
+
+ /* lvm_commmand-section { */
+ buffer_append(buff, "\t\tlvm_command {\n");
+ if (cmd_state->retcode == -1 && !cmd_state->signal)
+ buffer_append(buff, "\t\t\tstate=\"" LVMPD_RESP_IN_PROGRESS "\"\n");
+ else {
+ buffer_append(buff, "\t\t\tstate=\"" LVMPD_RESP_FINISHED "\"\n");
+ if (dm_snprintf(tmp, sizeof(tmp), "\t\t\treason=\"%s\"\n\t\t\tvalue=%d\n",
+ (cmd_state->signal ? LVMPD_REAS_SIGNAL : LVMPD_REAS_RETCODE),
+ (cmd_state->signal ?: cmd_state->retcode)) > 0)
+ buffer_append(buff, tmp);
+ }
+ buffer_append(buff, "\t\t}\n");
+ /* } lvm_commmand-section */
+
+ buffer_append(buff, "\t}\n");
+ /* } pdlv-section */
+}
+
+void pdst_locked_dump(const lvmpolld_store_t *pdst, struct buffer *buff)
+{
+ struct dm_hash_node *n;
+
+ dm_hash_iterate(n, pdst->store)
+ _pdlv_locked_dump(buff, dm_hash_get_data(pdst->store, n));
+}
diff --git a/daemons/lvmpolld/lvmpolld-data-utils.h b/daemons/lvmpolld/lvmpolld-data-utils.h
index 67a0aa798..9cdb27ae8 100644
--- a/daemons/lvmpolld/lvmpolld-data-utils.h
+++ b/daemons/lvmpolld/lvmpolld-data-utils.h
@@ -17,6 +17,8 @@
#include <pthread.h>
+struct buffer;
+
typedef struct lvmpolld_lv lvmpolld_lv_t;
typedef struct lvmpolld_state lvmpolld_state_t;
@@ -146,6 +148,10 @@ static inline unsigned pdlv_locked_internal_error(const lvmpolld_lv_t *pdlv)
void pdst_init(lvmpolld_store_t *pdst, const char *name);
void pdst_destroy(lvmpolld_store_t *pdst);
+void pdst_locked_dump(const lvmpolld_store_t *pdst, struct buffer *buff);
+void pdst_locked_lock_all_pdlvs(const lvmpolld_store_t *pdst);
+void pdst_locked_unlock_all_pdlvs(const lvmpolld_store_t *pdst);
+
static inline void pdst_lock(lvmpolld_store_t *pdst)
{
pthread_mutex_lock(&pdst->lock);
diff --git a/daemons/lvmpolld/lvmpolld-protocol.h b/daemons/lvmpolld/lvmpolld-protocol.h
index e1e7080a7..ce65524b3 100644
--- a/daemons/lvmpolld/lvmpolld-protocol.h
+++ b/daemons/lvmpolld/lvmpolld-protocol.h
@@ -21,6 +21,7 @@
#define LVMPOLLD_PROTOCOL_VERSION 1
#define LVMPD_REQ_CONVERT CONVERT_POLL
+#define LVMPD_REQ_DUMP "dump"
#define LVMPD_REQ_MERGE MERGE_POLL
#define LVMPD_REQ_MERGE_THIN MERGE_THIN_POLL
#define LVMPD_REQ_PROGRESS "progress_info"