mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-31 21:18:26 +03:00
Add cmdline debug & version options to dmeventd.
Fix oom_adj handling.
This commit is contained in:
parent
19d102082d
commit
2d74110feb
@ -1,5 +1,6 @@
|
||||
Version 1.02.16 -
|
||||
===================================
|
||||
Add cmdline debug & version options to dmeventd.
|
||||
Add DM_LIB_VERSION definition to configure.h.
|
||||
Suppress 'Unrecognised field' error if report field is 'help'.
|
||||
Add --separator and --sort to dmsetup (unused).
|
||||
|
@ -39,7 +39,12 @@
|
||||
#include <arpa/inet.h> /* for htonl, ntohl */
|
||||
|
||||
#ifdef linux
|
||||
#include <malloc.h>
|
||||
# include <malloc.h>
|
||||
|
||||
/* From linux/oom.h */
|
||||
# define OOM_DISABLE (-17)
|
||||
# define OOM_ADJUST_MIN (-16)
|
||||
|
||||
#endif
|
||||
|
||||
/* FIXME We use syslog for now, because multilog is not yet implemented */
|
||||
@ -47,6 +52,7 @@
|
||||
|
||||
static volatile sig_atomic_t _exit_now = 0; /* set to '1' when signal is given to exit */
|
||||
static volatile sig_atomic_t _thread_registries_empty = 1; /* registries are empty initially */
|
||||
static int _debug = 0;
|
||||
|
||||
/* List (un)link macros. */
|
||||
#define LINK(x, head) list_add(head, &(x)->list)
|
||||
@ -58,9 +64,10 @@ static volatile sig_atomic_t _thread_registries_empty = 1; /* registries are emp
|
||||
#define UNLINK_THREAD(x) UNLINK(x)
|
||||
|
||||
#define DAEMON_NAME "dmeventd"
|
||||
#define OOM_ADJ_FILE "/proc/self/oom_adj"
|
||||
|
||||
/*
|
||||
Global mutex for thread list access. Has to be held when:
|
||||
Global mutex for thread list access. Has to be held when:
|
||||
- iterating thread list
|
||||
- adding or removing elements from thread list
|
||||
- changing or reading thread_status's fields:
|
||||
@ -75,6 +82,8 @@ static pthread_mutex_t _global_mutex;
|
||||
|
||||
#define THREAD_STACK_SIZE (300*1024)
|
||||
|
||||
#define DEBUGLOG(fmt, args...) _debuglog(fmt, ## args)
|
||||
|
||||
/* Data kept about a DSO. */
|
||||
struct dso_data {
|
||||
struct list list;
|
||||
@ -172,6 +181,24 @@ static LIST_INIT(_timeout_registry);
|
||||
static pthread_mutex_t _timeout_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t _timeout_cond = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
static void _debuglog(const char *fmt, ...)
|
||||
{
|
||||
time_t P;
|
||||
va_list ap;
|
||||
|
||||
if (!_debug)
|
||||
return;
|
||||
|
||||
va_start(ap,fmt);
|
||||
|
||||
time(&P);
|
||||
fprintf(stderr, "dmeventd[%x]: %.15s ", (int)pthread_self(), ctime(&P)+4 );
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* Allocate/free the status structure for a monitoring thread. */
|
||||
static struct thread_status *_alloc_thread_status(struct message_data *data,
|
||||
struct dso_data *dso_data)
|
||||
@ -883,11 +910,11 @@ static int _register_for_event(struct message_data *message_data)
|
||||
almost as good as dead already... */
|
||||
if (thread_new->events & DM_EVENT_TIMEOUT) {
|
||||
ret = -_register_for_timeout(thread);
|
||||
if (ret) {
|
||||
_unlock_mutex();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (ret) {
|
||||
_unlock_mutex();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(thread = _lookup_thread_status(message_data))) {
|
||||
_unlock_mutex();
|
||||
@ -1361,7 +1388,7 @@ static void _cleanup_unused_threads(void)
|
||||
if (thread->status == DM_THREAD_RUNNING) {
|
||||
thread->status = DM_THREAD_SHUTDOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (thread->status == DM_THREAD_SHUTDOWN) {
|
||||
if (!thread->events) {
|
||||
@ -1377,7 +1404,7 @@ static void _cleanup_unused_threads(void)
|
||||
stack;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_del(l);
|
||||
syslog(LOG_ERR,
|
||||
@ -1465,31 +1492,39 @@ static int _lock_pidfile(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Protection against OOM killer if kernel supports it
|
||||
*/
|
||||
static int _set_oom_adj(int val)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
struct stat st;
|
||||
|
||||
if (stat("/proc/self/oom_adj", &st) == -1)
|
||||
return -errno;
|
||||
if (stat(OOM_ADJ_FILE, &st) == -1) {
|
||||
if (errno == ENOENT)
|
||||
DEBUGLOG(OOM_ADJ_FILE " not found");
|
||||
else
|
||||
perror(OOM_ADJ_FILE ": stat failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fp = fopen("/proc/self/oom_adj", "w");
|
||||
|
||||
if (!fp)
|
||||
return -1;
|
||||
if (!(fp = fopen(OOM_ADJ_FILE, "w"))) {
|
||||
perror(OOM_ADJ_FILE ": fopen failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(fp, "%i", val);
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _daemonize(void)
|
||||
{
|
||||
int status;
|
||||
int pid;
|
||||
int child_status;
|
||||
int fd;
|
||||
pid_t pid;
|
||||
struct rlimit rlim;
|
||||
struct timeval tval;
|
||||
sigset_t my_sigset;
|
||||
@ -1501,14 +1536,17 @@ static void _daemonize(void)
|
||||
}
|
||||
signal(SIGTERM, &_exit_handler);
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid < 0)
|
||||
switch (pid = fork()) {
|
||||
case -1:
|
||||
perror("fork failed:");
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
if (pid) {
|
||||
case 0: /* Child */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Wait for response from child */
|
||||
while (!waitpid(pid, &status, WNOHANG) && !_exit_now) {
|
||||
while (!waitpid(pid, &child_status, WNOHANG) && !_exit_now) {
|
||||
tval.tv_sec = 0;
|
||||
tval.tv_usec = 250000; /* .25 sec */
|
||||
select(0, NULL, NULL, NULL, &tval);
|
||||
@ -1518,7 +1556,7 @@ static void _daemonize(void)
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
/* Problem with child. Determine what it is by exit code */
|
||||
switch (WEXITSTATUS(status)) {
|
||||
switch (WEXITSTATUS(child_status)) {
|
||||
case EXIT_LOCKFILE_INUSE:
|
||||
break;
|
||||
case EXIT_DESC_CLOSE_FAILURE:
|
||||
@ -1535,10 +1573,9 @@ static void _daemonize(void)
|
||||
break;
|
||||
}
|
||||
|
||||
exit(EXIT_FAILURE); /* Redundant */
|
||||
exit(child_status);
|
||||
}
|
||||
|
||||
setsid();
|
||||
if (chdir("/"))
|
||||
exit(EXIT_CHDIR_FAILURE);
|
||||
|
||||
@ -1555,6 +1592,51 @@ static void _daemonize(void)
|
||||
(open("/dev/null", O_WRONLY) < 0))
|
||||
exit(EXIT_DESC_OPEN_FAILURE);
|
||||
|
||||
setsid();
|
||||
}
|
||||
|
||||
static void usage(char *prog, FILE *file)
|
||||
{
|
||||
fprintf(file, "Usage:\n");
|
||||
fprintf(file, "%s [Vhd]\n", prog);
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, " -V Show version of dmeventd\n");
|
||||
fprintf(file, " -h Show this help information\n");
|
||||
fprintf(file, " -d Don't fork, run in the foreground\n");
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
signed char opt;
|
||||
struct dm_event_fifos fifos;
|
||||
//struct sys_log logdata = {DAEMON_NAME, LOG_DAEMON};
|
||||
|
||||
opterr = 0;
|
||||
optind = 0;
|
||||
|
||||
while ((opt = getopt(argc, argv, "?hVd")) != EOF) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
usage(argv[0], stdout);
|
||||
exit(0);
|
||||
case '?':
|
||||
usage(argv[0], stderr);
|
||||
exit(0);
|
||||
case 'd':
|
||||
_debug++;
|
||||
break;
|
||||
case 'V':
|
||||
printf("dmeventd version: %s\n", DM_LIB_VERSION);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_debug)
|
||||
_daemonize();
|
||||
|
||||
openlog("dmeventd", LOG_PID, LOG_DAEMON);
|
||||
|
||||
_lock_pidfile(); /* exits if failure */
|
||||
@ -1563,20 +1645,8 @@ static void _daemonize(void)
|
||||
signal(SIGINT, &_exit_handler);
|
||||
signal(SIGHUP, &_exit_handler);
|
||||
signal(SIGQUIT, &_exit_handler);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
struct dm_event_fifos fifos;
|
||||
//struct sys_log logdata = {DAEMON_NAME, LOG_DAEMON};
|
||||
|
||||
_daemonize();
|
||||
|
||||
/*
|
||||
* ENOENT means the kernel does not support oom_adj
|
||||
*/
|
||||
if (_set_oom_adj(-16) != -ENOENT)
|
||||
if (!_set_oom_adj(OOM_DISABLE) && !_set_oom_adj(OOM_ADJUST_MIN))
|
||||
syslog(LOG_ERR, "Failed to set oom_adj to protect against OOM killer");
|
||||
|
||||
_init_thread_signals();
|
||||
@ -1600,7 +1670,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* Signal parent, letting them know we are ready to go. */
|
||||
kill(getppid(), SIGTERM);
|
||||
syslog(LOG_INFO, "dmeventd ready for processing.");
|
||||
syslog(LOG_NOTICE, "dmeventd ready for processing.");
|
||||
|
||||
while (!_exit_now) {
|
||||
_process_request(&fifos);
|
||||
@ -1619,7 +1689,8 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
pthread_mutex_destroy(&_global_mutex);
|
||||
|
||||
syslog(LOG_INFO, "dmeventd shutting down.");
|
||||
syslog(LOG_NOTICE, "dmeventd shutting down.");
|
||||
closelog();
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user