----- Original Message ----- > The patch below adds support to filter foreach on task states. I've > found [foreach state=D bt] and [foreach state=R bt] useful; the former > allows to emulate the show-blocked-tasks Magic SysRq. > > Rabin I like this idea. But for the sake of conformity, I will change the state identifiers to be the same two-letter strings that the "ps" command uses. Queued for crash-6.0.5. Thanks, Dave > > diff --git a/defs.h b/defs.h > index 2e7f6bd..dc12844 100755 > --- a/defs.h > +++ b/defs.h > @@ -974,6 +974,7 @@ extern struct machdep_table *machdep; > #define FOREACH_F_FLAG (0x400000) > #define FOREACH_x_FLAG (0x800000) > #define FOREACH_d_FLAG (0x1000000) > +#define FOREACH_STATE (0x2000000) > > struct foreach_data { > ulong flags; > @@ -982,6 +983,7 @@ struct foreach_data { > char *comm_array[MAX_FOREACH_COMMS]; > ulong pid_array[MAX_FOREACH_PIDS]; > ulong arg_array[MAX_FOREACH_ARGS]; > + ulong state; > char *reference; > int keys; > int pids; > diff --git a/help.c b/help.c > index adaaea7..dedf479 100755 > --- a/help.c > +++ b/help.c > @@ -736,7 +736,9 @@ char *help_foreach[] = { > " precede the name string with a \"\\\".", > " user perform the command(s) on all user (non-kernel) threads.", > " kernel perform the command(s) on all kernel threads.", > -" active perform the command(s) on the active thread on each CPU.\n", > +" active perform the command(s) on the active thread on each CPU.", > +" state=? perform the command(s) on all tasks in the specified state.", > +" (? is one of R, S, D, T, Z, X, W)\n", > " If none of the task-identifying arguments above are entered, the command", > " will be performed on all tasks.\n", > " command select one or more of the following commands to be run > on the tasks", > @@ -793,6 +795,9 @@ char *help_foreach[] = { > " Display the open files for all tasks:\n", > " %s> foreach files", > " ...\n", > +" Display the stack traces for all blocked (TASK_UNINTERRUPTIBLE) tasks:\n", > +" %s> foreach state=D bt", > +" ...\n", > NULL > }; > > diff --git a/task.c b/task.c > index 433a043..de033c3 100755 > --- a/task.c > +++ b/task.c > @@ -5061,6 +5061,35 @@ cmd_foreach(void) > continue; > } > > + if (STRNEQ(args[optind], "state=")) { > + const char *p = args[optind] + strlen("state="); > + ulong state = 0; > + > + if (STREQ(p, "R")) > + state = _RUNNING_; > + else if (STREQ(p, "S")) > + state = _INTERRUPTIBLE_; > + else if (STREQ(p, "D")) > + state = _UNINTERRUPTIBLE_; > + else if (STREQ(p, "T")) > + state = _STOPPED_; > + else if (STREQ(p, "Z")) > + state = _ZOMBIE_; > + else if (STREQ(p, "X")) > + state = _DEAD_; > + else if (STREQ(p, "W")) > + state = _SWAPPING_; > + else if (*p) > + error(FATAL, "invalid state: %s\n", p); > + else > + error(FATAL, "no state specified\n"); > + > + fd->flags |= FOREACH_STATE; > + fd->state = state; > + optind++; > + continue; > + } > + > /* > * Select only user threads. > */ > @@ -5322,6 +5351,9 @@ foreach(struct foreach_data *fd) > if ((fd->flags & FOREACH_KERNEL) && !is_kernel_thread(tc->task)) > continue; > > + if ((fd->flags & FOREACH_STATE) && task_state(tc->task) != fd->state) > + continue; > + > if (specified) { > for (j = 0; j < fd->tasks; j++) > if (fd->task_array[j] == tc->task) > -- -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility