[lvm-devel] master - dmeventd_thin: SIGCHLD handler
Zdenek Kabelac
zkabelac at fedoraproject.org
Fri Jan 20 23:04:16 UTC 2017
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=46c23dfb874ab8cebf1b335ef517095ff7bfdd81
Commit: 46c23dfb874ab8cebf1b335ef517095ff7bfdd81
Parent: bc7a1d70d4936fd892223686388fd6fe5c8c3934
Author: Zdenek Kabelac <zkabelac at redhat.com>
AuthorDate: Wed Jan 18 09:55:46 2017 +0100
Committer: Zdenek Kabelac <zkabelac at redhat.com>
CommitterDate: Fri Jan 20 23:55:51 2017 +0100
dmeventd_thin: SIGCHLD handler
To improve reaction time on when child is finished,
lets handle SIGCHLD in particular thread.
Let's hope kernel will route SIGCHLD to matching thread.
---
daemons/dmeventd/plugins/thin/dmeventd_thin.c | 40 +++++++++++++++++++++++++
1 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/daemons/dmeventd/plugins/thin/dmeventd_thin.c b/daemons/dmeventd/plugins/thin/dmeventd_thin.c
index 86a2115..bdccac6 100644
--- a/daemons/dmeventd/plugins/thin/dmeventd_thin.c
+++ b/daemons/dmeventd/plugins/thin/dmeventd_thin.c
@@ -55,6 +55,8 @@ struct dso_state {
uint64_t known_metadata_size;
uint64_t known_data_size;
unsigned fails;
+ int restore_sigset;
+ sigset_t old_sigset;
pid_t pid;
char **argv;
char cmd_str[1024];
@@ -542,6 +544,41 @@ out:
dm_task_destroy(new_dmt);
}
+/* Handle SIGCHLD for a thread */
+static void _sig_child(int signum __attribute__((unused)))
+{
+ /* empty SIG_IGN */;
+}
+
+/* Setup handler for SIGCHLD when executing external command
+ * to get quick 'waitpid()' reaction
+ * It will interrupt syscall just like SIGALRM and
+ * invoke process_event().
+ */
+static void _init_thread_signals(struct dso_state *state)
+{
+ struct sigaction act = { .sa_handler = _sig_child };
+ sigset_t my_sigset;
+
+ sigemptyset(&my_sigset);
+
+ if (sigaction(SIGCHLD, &act, NULL))
+ log_warn("WARNING: Failed to set SIGCHLD action.");
+ else if (sigaddset(&my_sigset, SIGCHLD))
+ log_warn("WARNING: Failed to add SIGCHLD to set.");
+ else if (pthread_sigmask(SIG_UNBLOCK, &my_sigset, &state->old_sigset))
+ log_warn("WARNING: Failed to unblock SIGCHLD.");
+ else
+ state->restore_sigset = 1;
+}
+
+static void _restore_thread_signals(struct dso_state *state)
+{
+ if (state->restore_sigset &&
+ pthread_sigmask(SIG_SETMASK, &state->old_sigset, NULL))
+ log_warn("WARNING: Failed to block SIGCHLD.");
+}
+
int register_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
@@ -575,6 +612,7 @@ int register_device(const char *device,
}
dm_split_words(str, maxcmd - 1, 0, state->argv);
+ _init_thread_signals(state);
}
state->metadata_percent_check = CHECK_MINIMUM;
@@ -619,6 +657,8 @@ int unregister_device(const char *device,
if (state->pid != -1)
log_warn("WARNING: Cannot kill child %d!", state->pid);
+ _restore_thread_signals(state);
+
dmeventd_lvm2_exit_with_pool(state);
log_info("No longer monitoring thin pool %s.", device);
More information about the lvm-devel
mailing list