mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
dmeventd: implement exit_on file check
When exit on file is present in a system and term/break signal is catched, them dmeventd is no longger refusing to exit. For the correct shutdown, there should be ideally unmonitoring call, however in some case it's very hard to implement this correct procedure. With this 'exit on' file dmeventd at least avoid 'blocking' shutdown, before systemd kills use with -9 anyway possibly even in some unwanted stated of internal dmeventd processing (i.e. in the middle of some lvm command processing).
This commit is contained in:
parent
3da18a06d8
commit
a9d7a9d128
@ -98,6 +98,7 @@ static int _systemd_activation = 0;
|
||||
static int _foreground = 0;
|
||||
static int _restart = 0;
|
||||
static time_t _idle_since = 0;
|
||||
static const char *_exit_on = DEFAULT_DMEVENTD_EXIT_ON_PATH;
|
||||
static char **_initial_registrations = 0;
|
||||
|
||||
/* FIXME Make configurable at runtime */
|
||||
@ -723,12 +724,18 @@ static int _get_status(struct message_data *message_data)
|
||||
static int _get_parameters(struct message_data *message_data) {
|
||||
struct dm_event_daemon_message *msg = message_data->msg;
|
||||
int size;
|
||||
char idle_buf[32] = "";
|
||||
|
||||
if (_idle_since)
|
||||
(void)dm_snprintf(idle_buf, sizeof(idle_buf), " idle=%lu", (long unsigned) (time(NULL) - _idle_since));
|
||||
|
||||
free(msg->data);
|
||||
if ((size = dm_asprintf(&msg->data, "%s pid=%d daemon=%s exec_method=%s",
|
||||
if ((size = dm_asprintf(&msg->data, "%s pid=%d daemon=%s exec_method=%s exit_on=\"%s\"%s",
|
||||
message_data->id, getpid(),
|
||||
_foreground ? "no" : "yes",
|
||||
_systemd_activation ? "systemd" : "direct")) < 0) {
|
||||
_systemd_activation ? "systemd" : "direct",
|
||||
_exit_on,
|
||||
idle_buf)) < 0) {
|
||||
stack;
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -2242,8 +2249,9 @@ bad:
|
||||
static void _usage(char *prog, FILE *file)
|
||||
{
|
||||
fprintf(file, "Usage:\n"
|
||||
"%s [-d [-d [-d]]] [-f] [-h] [i] [-l] [-R] [-V] [-?]\n\n"
|
||||
"%s [-d [-d [-d]]] [-e path] [-f] [-h] [i] [-l] [-R] [-V] [-?]\n\n"
|
||||
" -d Log debug messages to syslog (-d, -dd, -ddd)\n"
|
||||
" -e Select a file path checked on exit\n"
|
||||
" -f Don't fork, run in the foreground\n"
|
||||
" -h Show this help information\n"
|
||||
" -i Query running instance of dmeventd for info\n"
|
||||
@ -2266,7 +2274,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
optopt = optind = opterr = 0;
|
||||
optarg = (char*) "";
|
||||
while ((opt = getopt(argc, argv, "?fhiVdlR")) != EOF) {
|
||||
while ((opt = getopt(argc, argv, ":?e:fhiVdlR")) != EOF) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
_usage(argv[0], stdout);
|
||||
@ -2279,6 +2287,13 @@ int main(int argc, char *argv[])
|
||||
case 'R':
|
||||
_restart++;
|
||||
break;
|
||||
case 'e':
|
||||
if (strchr(optarg, '"')) {
|
||||
fprintf(stderr, "dmeventd: option -e does not accept path \"%s\" with '\"' character.\n", optarg);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
_exit_on=optarg;
|
||||
break;
|
||||
case 'f':
|
||||
_foreground++;
|
||||
break;
|
||||
@ -2291,6 +2306,9 @@ int main(int argc, char *argv[])
|
||||
case 'V':
|
||||
printf("dmeventd version: %s\n", DM_LIB_VERSION);
|
||||
return EXIT_SUCCESS;
|
||||
case ':':
|
||||
fprintf(stderr, "dmeventd: option -%c requires an argument.\n", optopt);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2381,15 +2399,28 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (_exit_now == DM_SIGNALED_EXIT) {
|
||||
_exit_now = DM_SCHEDULED_EXIT;
|
||||
/*
|
||||
* When '_exit_now' is set, signal has been received,
|
||||
* but can not simply exit unless all
|
||||
* threads are done processing.
|
||||
*/
|
||||
log_info("dmeventd received break, scheduling exit.");
|
||||
}
|
||||
} else
|
||||
switch (_exit_now) {
|
||||
case DM_SIGNALED_EXIT:
|
||||
_exit_now = DM_SCHEDULED_EXIT;
|
||||
/*
|
||||
* When '_exit_now' is set, signal has been received,
|
||||
* but can not simply exit unless all
|
||||
* threads are done processing.
|
||||
*/
|
||||
log_info("dmeventd received break, scheduling exit.");
|
||||
/* fall through */
|
||||
case DM_SCHEDULED_EXIT:
|
||||
/* While exit is scheduled, check for exit_on file */
|
||||
DEBUGLOG("Checking exit on file \"%s\".", _exit_on);
|
||||
if (_exit_on[0] && (access(_exit_on, F_OK) == 0)) {
|
||||
log_info("dmeventd detected exit on file %s, unregistering all monitored devices.",
|
||||
_exit_on);
|
||||
_unregister_all_threads();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
_process_request(&fifos);
|
||||
_cleanup_unused_threads();
|
||||
}
|
||||
|
@ -167,6 +167,7 @@ DEFAULT_LOCK_DIR = @DEFAULT_LOCK_DIR@
|
||||
DEFAULT_RUN_DIR = @DEFAULT_RUN_DIR@
|
||||
DEFAULT_PID_DIR = @DEFAULT_PID_DIR@
|
||||
DEFAULT_MANGLING = @MANGLING@
|
||||
DEFAULT_DMEVENTD_EXIT_ON_PATH = @DEFAULT_DMEVENTD_EXIT_ON_PATH@
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# From http://blog.melski.net/tag/debugging-makefiles/
|
||||
|
@ -180,6 +180,7 @@ $(SED) -e "s+#VERSION#+$(LVM_VERSION)+" \
|
||||
-e "s+#DEFAULT_PID_DIR#+$(DEFAULT_PID_DIR)+" \
|
||||
-e "s+#SYSTEMD_GENERATOR_DIR#+$(SYSTEMD_GENERATOR_DIR)+" \
|
||||
-e "s+#DEFAULT_LIBLINE#+$(DEFAULT_LIBLINE)+" \
|
||||
-e "s+#DEFAULT_DMEVENTD_EXIT_ON_PATH#+$(DEFAULT_DMEVENTD_EXIT_ON_PATH)+" \
|
||||
-e "s+#DEFAULT_MANGLING#+$(DEFAULT_MANGLING)+" $< > $@
|
||||
endef
|
||||
|
||||
|
@ -10,6 +10,8 @@ dmeventd \(em Device-mapper event daemon
|
||||
.RB [ -d
|
||||
.RB [ -d
|
||||
.RB [ -d ]]]
|
||||
.RB [ -e
|
||||
.BR exit_on_path ]
|
||||
.RB [ -f ]
|
||||
.RB [ -h ]
|
||||
.RB [ -i ]
|
||||
@ -37,6 +39,16 @@ debug messages sent to syslog.
|
||||
Each extra d adds more debugging information.
|
||||
.
|
||||
.TP
|
||||
.B -e exit_on_path
|
||||
Specifies the file path whose presence is checked by the daemon when it
|
||||
receives a signal (SIGINT, SIGTERM) and allows to exit even if there are still
|
||||
monitored devices.
|
||||
This can help with system shutdown where devices
|
||||
have not been unmonitored properly.
|
||||
To disable this behavior set this to the empty string "".
|
||||
Default value is "\fI#DEFAULT_DMEVENTD_EXIT_ON_PATH#\fP".
|
||||
.
|
||||
.TP
|
||||
.B -f
|
||||
Don't fork, run in the foreground.
|
||||
.
|
||||
|
Loading…
Reference in New Issue
Block a user