From 4e6e574a3e8eb2351ba1d850369630bf8879dfaf Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 16 Jun 2008 15:50:07 -0700 Subject: [PATCH] mdmon: add debug print statements for profiling mdmon for development only as console output can block leading to monitor deadlocks in low mem situations Signed-off-by: Dan Williams --- managemon.c | 3 +++ mdmon.h | 7 +++++++ monitor.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- super-intel.c | 8 ++++---- 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/managemon.c b/managemon.c index 43db5669..9f3520e8 100644 --- a/managemon.c +++ b/managemon.c @@ -105,6 +105,7 @@ static void free_aa(struct active_array *aa) /* Note that this doesn't close fds if they are being used * by a clone. ->container will be set for a clone */ + dprintf("%s: devnum: %d\n", __func__, aa->devnum); if (!aa->container) close_aa(aa); while (aa->info.devs) { @@ -380,6 +381,8 @@ static void manage_new(struct mdstat_ent *mdstat, new->info.state_fd = sysfs_open(new->devnum, NULL, "array_state"); new->resync_start_fd = sysfs_open(new->devnum, NULL, "resync_start"); new->resync_start = 0; + dprintf("%s: inst: %d action: %d state: %d\n", __func__, atoi(inst), + new->action_fd, new->info.state_fd); sysfs_free(mdi); // finds and compares. diff --git a/mdmon.h b/mdmon.h index 11320ef6..f1b6d76e 100644 --- a/mdmon.h +++ b/mdmon.h @@ -1,3 +1,10 @@ +#ifdef DEBUG +#define dprintf(fmt, arg...) \ + fprintf(stderr, fmt, ##arg) +#else +#define dprintf(fmt, arg...) \ + ({ if (0) fprintf(stderr, fmt, ##arg); 0; }) +#endif enum array_state { clear, inactive, suspended, readonly, read_auto, clean, active, write_pending, active_idle, bad_word}; diff --git a/monitor.c b/monitor.c index 5a951490..6377cc4a 100644 --- a/monitor.c +++ b/monitor.c @@ -281,12 +281,17 @@ static int read_and_act(struct active_array *a) } a->container->ss->sync_metadata(a->container); + dprintf("%s: update[%d]: (", __func__, a->info.container_member); /* Effect state changes in the array */ - if (a->next_state != bad_word) + if (a->next_state != bad_word) { + dprintf(" state:%s", array_states[a->next_state]); write_attr(array_states[a->next_state], a->info.state_fd); - if (a->next_action != bad_action) + } + if (a->next_action != bad_action) { write_attr(sync_actions[a->next_action], a->action_fd); + dprintf(" action:%s", array_states[a->next_state]); + } for (mdi = a->info.devs; mdi ; mdi = mdi->next) { if (mdi->next_state == DS_REMOVE && mdi->state_fd >= 0) { int remove_result; @@ -296,15 +301,20 @@ static int read_and_act(struct active_array *a) * disk, we can simply wait until the next event to try * again. */ + dprintf(" %d:-blocked", mdi->disk.raid_disk); remove_result = write_attr("remove", mdi->state_fd); if (remove_result > 0) { + dprintf(" %d:removed", mdi->disk.raid_disk); close(mdi->state_fd); mdi->state_fd = -1; } } - if (mdi->next_state & DS_INSYNC) + if (mdi->next_state & DS_INSYNC) { write_attr("+in_sync", mdi->state_fd); + dprintf(" %d:+in_sync", mdi->disk.raid_disk); + } } + dprintf(" )\n"); /* move curr_ to prev_ */ a->prev_state = a->curr_state; @@ -410,6 +420,36 @@ static int handle_pipe(struct md_generic_cmd *cmd, struct active_array *aa) return -1; } +#ifdef DEBUG +static void dprint_wake_reasons(fd_set *fds) +{ + int i; + char proc_path[256]; + char link[256]; + char *basename; + int rv; + + fprintf(stderr, "monitor: wake ( "); + for (i = 0; i < FD_SETSIZE; i++) { + if (FD_ISSET(i, fds)) { + sprintf(proc_path, "/proc/%d/fd/%d", + (int) getpid(), i); + + rv = readlink(proc_path, link, sizeof(link) - 1); + if (rv < 0) { + fprintf(stderr, "%d:unknown ", i); + continue; + } + link[rv] = '\0'; + basename = strrchr(link, '/'); + fprintf(stderr, "%d:%s ", + i, basename ? ++basename : link); + } + } + fprintf(stderr, ")\n"); +} +#endif + static int wait_and_act(struct supertype *container, int pfd, int monfd, int nowait) { @@ -457,6 +497,7 @@ static int wait_and_act(struct supertype *container, int pfd, int fd = open(container->device_name, O_RDONLY|O_EXCL); if (fd >= 0 || errno != EBUSY) { /* OK, we are safe to leave */ + dprintf("no arrays to monitor... exiting\n"); exit_now = 1; signal_manager(); remove_pidfile(container->devname); @@ -467,6 +508,10 @@ static int wait_and_act(struct supertype *container, int pfd, if (!nowait) { rv = select(maxfd+1, &rfds, NULL, NULL, NULL); + #ifdef DEBUG + dprint_wake_reasons(&rfds); + #endif + if (rv <= 0) return rv; diff --git a/super-intel.c b/super-intel.c index 0efc49c2..8ca491bd 100644 --- a/super-intel.c +++ b/super-intel.c @@ -1644,7 +1644,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st) static int imsm_open_new(struct supertype *c, struct active_array *a, char *inst) { - fprintf(stderr, "imsm: open_new %s\n", inst); + dprintf("imsm: open_new %s\n", inst); a->info.container_member = atoi(inst); return 0; } @@ -1742,7 +1742,7 @@ static void imsm_set_array_state(struct active_array *a, int consistent) if (!failed) map_state = IMSM_T_STATE_NORMAL; if (map->map_state != map_state) { - fprintf(stderr, "imsm: map_state %d: %d\n", + dprintf("imsm: map_state %d: %d\n", inst, map_state); map->map_state = map_state; super->updates_pending++; @@ -1750,7 +1750,7 @@ static void imsm_set_array_state(struct active_array *a, int consistent) } if (dev->vol.dirty != dirty) { - fprintf(stderr, "imsm: mark '%s' (%llu)\n", + dprintf("imsm: mark '%s' (%llu)\n", dirty?"dirty":"clean", a->resync_start); dev->vol.dirty = dirty; @@ -1776,7 +1776,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state) if (n < 0) return; - fprintf(stderr, "imsm: set_disk %d:%x\n", n, state); + dprintf("imsm: set_disk %d:%x\n", n, state); disk = get_imsm_disk(super->mpb, get_imsm_disk_idx(map, n)); -- 2.39.2