[lvm-devel] master - dmeventd_thin: add wait_pid
Zdenek Kabelac
zkabelac at fedoraproject.org
Fri Jan 20 23:04:11 UTC 2017
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=14746a6c0025fad0d918bff7f1ee105e0eee10c3
Commit: 14746a6c0025fad0d918bff7f1ee105e0eee10c3
Parent: 2e935c0967e8bd3f97614c258619ad0c83fe0a48
Author: Zdenek Kabelac <zkabelac at redhat.com>
AuthorDate: Fri Jan 20 21:42:55 2017 +0100
Committer: Zdenek Kabelac <zkabelac at redhat.com>
CommitterDate: Fri Jan 20 23:55:50 2017 +0100
dmeventd_thin: add wait_pid
Add support handling command exit.
---
daemons/dmeventd/plugins/thin/dmeventd_thin.c | 55 +++++++++++++++++++++++++
1 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/daemons/dmeventd/plugins/thin/dmeventd_thin.c b/daemons/dmeventd/plugins/thin/dmeventd_thin.c
index 3e044ff..74b010a 100644
--- a/daemons/dmeventd/plugins/thin/dmeventd_thin.c
+++ b/daemons/dmeventd/plugins/thin/dmeventd_thin.c
@@ -363,6 +363,35 @@ static int _use_policy(struct dm_task *dmt, struct dso_state *state)
return 1;
}
+/* Check if executed command has finished
+ * Only 1 command may run */
+static int _wait_for_pid(struct dso_state *state)
+{
+ int status = 0;
+
+ if (state->pid == -1)
+ return 1;
+
+ if (!waitpid(state->pid, &status, WNOHANG))
+ return 0;
+
+ /* Wait for finish */
+ if (WIFEXITED(status)) {
+ log_verbose("Child %d exited with status %d.",
+ state->pid, WEXITSTATUS(status));
+ state->fails = WEXITSTATUS(status) ? 1 : 0;
+ } else {
+ if (WIFSIGNALED(status))
+ log_verbose("Child %d was terminated with status %d.",
+ state->pid, WTERMSIG(status));
+ state->fails = 1;
+ }
+
+ state->pid = -1;
+
+ return 1;
+}
+
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
void **user)
@@ -383,6 +412,11 @@ void process_event(struct dm_task *dmt,
dm_percent_to_float(state->data_percent_check),
dm_percent_to_float(state->metadata_percent_check));
#endif
+ if (!_wait_for_pid(state)) {
+ log_warn("WARNING: Skipping event, child %d is still running (%s).",
+ state->pid, state->cmd_str);
+ return;
+ }
if (event & DM_EVENT_DEVICE_ERROR) {
/* Error -> no need to check and do instant resize */
@@ -529,6 +563,7 @@ int register_device(const char *device,
state->metadata_percent_check = CHECK_MINIMUM;
state->data_percent_check = CHECK_MINIMUM;
+ state->pid = -1;
*user = state;
log_info("Monitoring thin pool %s.", device);
@@ -547,6 +582,26 @@ int unregister_device(const char *device,
void **user)
{
struct dso_state *state = *user;
+ int i;
+
+ for (i = 0; !_wait_for_pid(state) && (i < 6); ++i) {
+ if (i == 0)
+ /* Give it 2 seconds, then try to terminate & kill it */
+ log_verbose("Child %d still not finished (%s) waiting.",
+ state->pid, state->cmd_str);
+ else if (i == 3) {
+ log_warn("WARNING: Terminating child %d.", state->pid);
+ kill(state->pid, SIGINT);
+ kill(state->pid, SIGTERM);
+ } else if (i == 5) {
+ log_warn("WARNING: Killing child %d.", state->pid);
+ kill(state->pid, SIGKILL);
+ }
+ sleep(1);
+ }
+
+ if (state->pid != -1)
+ log_warn("WARNING: Cannot kill child %d!", state->pid);
dmeventd_lvm2_exit_with_pool(state);
log_info("No longer monitoring thin pool %s.", device);
More information about the lvm-devel
mailing list