* device-mapper ./WHATS_NEW dmeventd/dmeventd.c
@ 2006-12-20 14:35 agk
0 siblings, 0 replies; 3+ messages in thread
From: agk @ 2006-12-20 14:35 UTC (permalink / raw)
To: dm-cvs, dm-devel
CVSROOT: /cvs/dm
Module name: device-mapper
Changes by: agk@sourceware.org 2006-12-20 14:35:02
Modified files:
. : WHATS_NEW
dmeventd : dmeventd.c
Log message:
Fix dmeventd mirror to cope if monitored device disappears.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/device-mapper/WHATS_NEW.diff?cvsroot=dm&r1=1.137&r2=1.138
http://sourceware.org/cgi-bin/cvsweb.cgi/device-mapper/dmeventd/dmeventd.c.diff?cvsroot=dm&r1=1.24&r2=1.25
--- device-mapper/WHATS_NEW 2006/11/28 22:51:01 1.137
+++ device-mapper/WHATS_NEW 2006/12/20 14:35:02 1.138
@@ -1,5 +1,7 @@
Version 1.02.14 -
=============================
+ Some dmevent cleanups.
+ Fix dmeventd to cope if monitored device disappears.
Version 1.02.13 - 28 Nov 2006
=============================
--- device-mapper/dmeventd/dmeventd.c 2006/05/11 19:08:02 1.24
+++ device-mapper/dmeventd/dmeventd.c 2006/12/20 14:35:02 1.25
@@ -129,8 +129,8 @@
struct dso_data *dso_data;/* DSO this thread accesses. */
char *device_path; /* Mapped device path. */
- uint32_t event_nr; /* event number */
- int processing; /* Set when event is being processed */
+ uint32_t event_nr; /* event number */
+ int processing; /* Set when event is being processed */
enum dm_event_type events; /* bitfield for event filter. */
enum dm_event_type current_events;/* bitfield for occured events. */
enum dm_event_type processed_events;/* bitfield for processed events. */
@@ -179,12 +179,13 @@
{
struct dso_data *ret = (typeof(ret)) dm_malloc(sizeof(*ret));
- if (ret) {
- if (!memset(ret, 0, sizeof(*ret)) ||
- !(ret->dso_name = dm_strdup(data->dso_name))) {
- dm_free(ret);
- ret = NULL;
- }
+ if (!ret)
+ return NULL;
+
+ if (!memset(ret, 0, sizeof(*ret)) ||
+ !(ret->dso_name = dm_strdup(data->dso_name))) {
+ dm_free(ret);
+ return NULL;
}
return ret;
@@ -342,10 +343,9 @@
{
struct thread_status *thread;
- list_iterate_items(thread, &thread_registry) {
+ list_iterate_items(thread, &thread_registry)
if (!strcmp(data->device_path, thread->device_path))
return thread;
- }
return NULL;
}
@@ -546,6 +546,15 @@
thread->current_events |= DM_EVENT_TIMEOUT;
ret = 1;
thread->processed_events = 0;
+ } else {
+ /* FIXME replace with log_* macro */
+ syslog(LOG_NOTICE, "dm_task_run failed, errno = %d, %s",
+ errno, strerror(errno));
+ if (errno == ENXIO) {
+ /* FIXME replace with log_* macro */
+ syslog(LOG_ERR, "%s disappeared, detaching", thread->device_path);
+ ret = 2; /* FIXME What does 2 mean? Use macro. */
+ }
}
pthread_sigmask(SIG_SETMASK, &set, NULL);
@@ -592,6 +601,7 @@
static void *monitor_thread(void *arg)
{
struct thread_status *thread = arg;
+ int wait_error = 0;
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
pthread_cleanup_push(monitor_unregister, thread);
@@ -605,13 +615,18 @@
thread->current_events = 0;
/*
- * FIXME: if unrecoverable error (ENODEV) happens,
+ * FIXME If unrecoverable error (ENODEV) happens
* we loop indefinitely. event_wait should return
* more than 0/1.
*/
- if (!event_wait(thread))
+ wait_error = event_wait(thread);
+ if (!wait_error)
continue;
+ /* FIXME Give a DSO a chance to clean up. */
+ if (wait_error == 2)
+ break;
+
/*
* Check against filter.
*
@@ -680,13 +695,12 @@
lock_mutex();
- list_iterate_items(dso_data, &dso_registry) {
+ list_iterate_items(dso_data, &dso_registry)
if (!strcmp(data->dso_name, dso_data->dso_name)) {
lib_get(dso_data);
ret = dso_data;
break;
}
- }
unlock_mutex();
@@ -935,31 +949,29 @@
lock_mutex();
/* Iterate list of threads checking if we want a particular one. */
- list_iterate_items(thread, &thread_registry) {
+ list_iterate_items(thread, &thread_registry)
if ((hit = want_registered_device(message_data->dso_name,
message_data->device_path,
thread)))
break;
- }
/*
* If we got a registered device and want the next one ->
* fetch next conforming element off the list.
*/
- if (hit) {
- if (next) {
- do {
- if (list_end(&thread_registry, &thread->list))
- goto out;
-
- thread = list_item(thread->list.n,
- struct thread_status);
- } while (!want_registered_device(message_data->dso_name,
- NULL, thread));
- }
+ if (!hit || !next)
+ goto out;
- return registered_device(message_data, thread);
- }
+ do {
+ if (list_end(&thread_registry, &thread->list))
+ goto out;
+
+ thread = list_item(thread->list.n,
+ struct thread_status);
+ } while (!want_registered_device(message_data->dso_name,
+ NULL, thread));
+
+ return registered_device(message_data, thread);
out:
unlock_mutex();
@@ -1118,10 +1130,9 @@
{ DM_EVENT_CMD_ACTIVE, active },
}, *req;
- for (req = requests; req < requests + sizeof(requests); req++) {
+ for (req = requests; req < requests + sizeof(requests); req++)
if (req->cmd == msg->opcode.cmd)
return req->f(message_data);
- }
return -EINVAL;
}
@@ -1139,9 +1150,8 @@
!parse_message(&message_data)) {
stack;
ret = -EINVAL;
- } else {
+ } else
ret = handle_request(msg, &message_data);
- }
free_message(&message_data);
@@ -1242,7 +1252,7 @@
static int lock_pidfile(void)
{
int lf;
- char pidfile[] = "/var/run/dmeventd.pid";
+ char pidfile[] = "/var/run/dmeventd.pid"; /* FIXME Must be configurable at compile-time! */
if ((lf = open(pidfile, O_CREAT | O_RDWR, 0644)) < 0)
return -EXIT_OPEN_PID_FAILURE;
@@ -1326,14 +1336,3 @@
exit(EXIT_SUCCESS);
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
^ permalink raw reply [flat|nested] 3+ messages in thread
* device-mapper ./WHATS_NEW dmeventd/dmeventd.c
@ 2007-01-19 17:22 agk
0 siblings, 0 replies; 3+ messages in thread
From: agk @ 2007-01-19 17:22 UTC (permalink / raw)
To: dm-cvs, dm-devel
CVSROOT: /cvs/dm
Module name: device-mapper
Changes by: agk@sourceware.org 2007-01-19 17:22:17
Modified files:
. : WHATS_NEW
dmeventd : dmeventd.c
Log message:
Add cmdline debug & version options to dmeventd.
Fix oom_adj handling.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/device-mapper/WHATS_NEW.diff?cvsroot=dm&r1=1.154&r2=1.155
http://sourceware.org/cgi-bin/cvsweb.cgi/device-mapper/dmeventd/dmeventd.c.diff?cvsroot=dm&r1=1.40&r2=1.41
--- device-mapper/WHATS_NEW 2007/01/19 15:53:00 1.154
+++ device-mapper/WHATS_NEW 2007/01/19 17:22:17 1.155
@@ -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).
--- device-mapper/dmeventd/dmeventd.c 2007/01/17 14:45:10 1.40
+++ device-mapper/dmeventd/dmeventd.c 2007/01/19 17:22:17 1.41
@@ -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 @@
#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 @@
#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 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 @@
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 @@
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 @@
stack;
}
break;
- }
+ }
list_del(l);
syslog(LOG_ERR,
@@ -1465,31 +1492,39 @@
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;
-
- fp = fopen("/proc/self/oom_adj", "w");
+ 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;
+ }
- 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 @@
}
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 @@
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 @@
break;
}
- exit(EXIT_FAILURE); /* Redundant */
+ exit(child_status);
}
- setsid();
if (chdir("/"))
exit(EXIT_CHDIR_FAILURE);
@@ -1555,28 +1592,61 @@
(open("/dev/null", O_WRONLY) < 0))
exit(EXIT_DESC_OPEN_FAILURE);
- openlog("dmeventd", LOG_PID, LOG_DAEMON);
-
- _lock_pidfile(); /* exits if failure */
+ setsid();
+}
- /* Set the rest of the signals to cause '_exit_now' to be set */
- signal(SIGINT, &_exit_handler);
- signal(SIGHUP, &_exit_handler);
- signal(SIGQUIT, &_exit_handler);
+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};
- _daemonize();
+ opterr = 0;
+ optind = 0;
- /*
- * ENOENT means the kernel does not support oom_adj
- */
- if (_set_oom_adj(-16) != -ENOENT)
+ 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 */
+
+ /* Set the rest of the signals to cause '_exit_now' to be set */
+ signal(SIGINT, &_exit_handler);
+ signal(SIGHUP, &_exit_handler);
+ signal(SIGQUIT, &_exit_handler);
+
+ 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 @@
/* 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 @@
#endif
pthread_mutex_destroy(&_global_mutex);
- syslog(LOG_INFO, "dmeventd shutting down.");
+ syslog(LOG_NOTICE, "dmeventd shutting down.");
closelog();
+
exit(EXIT_SUCCESS);
}
^ permalink raw reply [flat|nested] 3+ messages in thread
* device-mapper ./WHATS_NEW dmeventd/dmeventd.c
@ 2007-04-23 15:06 mornfall
0 siblings, 0 replies; 3+ messages in thread
From: mornfall @ 2007-04-23 15:06 UTC (permalink / raw)
To: dm-cvs, dm-devel
CVSROOT: /cvs/dm
Module name: device-mapper
Changes by: mornfall@sourceware.org 2007-04-23 16:06:03
Modified files:
. : WHATS_NEW
dmeventd : dmeventd.c
Log message:
Fix some memory leaks in dmeventd.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/device-mapper/WHATS_NEW.diff?cvsroot=dm&r1=1.175&r2=1.176
http://sourceware.org/cgi-bin/cvsweb.cgi/device-mapper/dmeventd/dmeventd.c.diff?cvsroot=dm&r1=1.47&r2=1.48
--- device-mapper/WHATS_NEW 2007/04/19 20:24:00 1.175
+++ device-mapper/WHATS_NEW 2007/04/23 15:06:03 1.176
@@ -1,7 +1,7 @@
Version 1.02.19 -
====================================
Introduce _add_field() and _is_same_field() to libdm-report.c.
- Fix some libdevmapper-event memory leaks.
+ Fix some libdevmapper-event and dmeventd memory leaks.
Remove unnecessary memset() return value checks.
Fix a few leaks in reporting error paths. [1.02.15+]
--- device-mapper/dmeventd/dmeventd.c 2007/03/16 14:36:14 1.47
+++ device-mapper/dmeventd/dmeventd.c 2007/04/23 15:06:03 1.48
@@ -245,6 +245,8 @@
static void _free_thread_status(struct thread_status *thread)
{
+ if (thread->current_task)
+ dm_task_destroy(thread->current_task);
dm_free(thread->device.uuid);
dm_free(thread->device.name);
dm_free(thread);
@@ -811,11 +813,6 @@
static int _terminate_thread(struct thread_status *thread)
{
- int ret;
-
- if ((ret = pthread_cancel(thread->thread)))
- return ret;
-
return pthread_kill(thread->thread, SIGALRM);
}
@@ -1389,7 +1386,7 @@
message_data.msg = msg;
if (msg->cmd == DM_EVENT_CMD_HELLO) {
ret = 0;
- answer = dm_strdup(msg->data);
+ answer = msg->data;
if (answer) {
msg->size = dm_asprintf(&(msg->data), "%s HELLO", answer);
dm_free(answer);
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-04-23 15:06 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-20 14:35 device-mapper ./WHATS_NEW dmeventd/dmeventd.c agk
-- strict thread matches above, loose matches on Subject: below --
2007-01-19 17:22 agk
2007-04-23 15:06 mornfall
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.