Skip to content

Commit

Permalink
Fix "foreach" command with "DE" state to display only expected tasks
Browse files Browse the repository at this point in the history
Currently, the "foreach DE ps -m" command may display "DE" as well as
"ZO" state tasks as below:

  crash> foreach DE ps -m
  ...
  [0 00:00:00.040] [ZO]  PID: 11458    TASK: ffff91c75680d280  CPU: 7    COMMAND: "ora_w01o_p01mci"
  [0 00:00:00.044] [ZO]  PID: 49118    TASK: ffff91c7bf3e8000  CPU: 19   COMMAND: "oracle_49118_p0"
  [0 00:00:00.050] [ZO]  PID: 28748    TASK: ffff91a7cbde3180  CPU: 2    COMMAND: "ora_imr0_p01sci"
  [0 00:00:00.050] [DE]  PID: 28405    TASK: ffff91a7c8eb0000  CPU: 27   COMMAND: "ora_vktm_p01sci"
  [0 00:00:00.051] [ZO]  PID: 31716    TASK: ffff91a7f7192100  CPU: 6    COMMAND: "ora_p001_p01sci"
  ...

That is not expected behavior, the "foreach" command needs to handle
such cases. Let's add a check to determine if the task state identifier
is specified and the specified identifier is equal to the actual task
state identifier, so that it can filter out the unspecified state
tasks.

With the patch:
  crash> foreach DE ps -m
  [0 00:00:00.050] [DE]  PID: 28405    TASK: ffff91a7c8eb0000  CPU: 27   COMMAND: "ora_vktm_p01sci"
  crash>

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
  • Loading branch information
lian-bo authored and k-hagio committed Aug 3, 2023
1 parent c74f375 commit 558aecc
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 34 deletions.
2 changes: 1 addition & 1 deletion defs.h
Expand Up @@ -1203,7 +1203,7 @@ struct foreach_data {
char *pattern;
regex_t regex;
} regex_info[MAX_REGEX_ARGS];
ulong state;
const char *state;
char *reference;
int keys;
int pids;
Expand Down
52 changes: 19 additions & 33 deletions task.c
Expand Up @@ -6636,39 +6636,42 @@ cmd_foreach(void)
STREQ(args[optind], "NE") ||
STREQ(args[optind], "SW")) {

ulong state = TASK_STATE_UNINITIALIZED;

if (fd->flags & FOREACH_STATE)
error(FATAL, "only one task state allowed\n");

if (STREQ(args[optind], "RU"))
fd->state = _RUNNING_;
state = _RUNNING_;
else if (STREQ(args[optind], "IN"))
fd->state = _INTERRUPTIBLE_;
state = _INTERRUPTIBLE_;
else if (STREQ(args[optind], "UN"))
fd->state = _UNINTERRUPTIBLE_;
state = _UNINTERRUPTIBLE_;
else if (STREQ(args[optind], "ST"))
fd->state = _STOPPED_;
state = _STOPPED_;
else if (STREQ(args[optind], "TR"))
fd->state = _TRACING_STOPPED_;
state = _TRACING_STOPPED_;
else if (STREQ(args[optind], "ZO"))
fd->state = _ZOMBIE_;
state = _ZOMBIE_;
else if (STREQ(args[optind], "DE"))
fd->state = _DEAD_;
state = _DEAD_;
else if (STREQ(args[optind], "SW"))
fd->state = _SWAPPING_;
state = _SWAPPING_;
else if (STREQ(args[optind], "PA"))
fd->state = _PARKED_;
state = _PARKED_;
else if (STREQ(args[optind], "WA"))
fd->state = _WAKING_;
state = _WAKING_;
else if (STREQ(args[optind], "ID"))
fd->state = _UNINTERRUPTIBLE_|_NOLOAD_;
state = _UNINTERRUPTIBLE_|_NOLOAD_;
else if (STREQ(args[optind], "NE"))
fd->state = _NEW_;
state = _NEW_;

if (fd->state == TASK_STATE_UNINITIALIZED)
if (state == TASK_STATE_UNINITIALIZED)
error(FATAL,
"invalid task state for this kernel: %s\n",
args[optind]);

fd->state = args[optind];
fd->flags |= FOREACH_STATE;

optind++;
Expand Down Expand Up @@ -7039,26 +7042,9 @@ foreach(struct foreach_data *fd)
if ((fd->flags & FOREACH_KERNEL) && !is_kernel_thread(tc->task))
continue;

if (fd->flags & FOREACH_STATE) {
if (fd->state == _RUNNING_) {
if (task_state(tc->task) != _RUNNING_)
continue;
} else if (fd->state & _UNINTERRUPTIBLE_) {
if (!(task_state(tc->task) & _UNINTERRUPTIBLE_))
continue;

if (valid_task_state(_NOLOAD_)) {
if (fd->state & _NOLOAD_) {
if (!(task_state(tc->task) & _NOLOAD_))
continue;
} else {
if ((task_state(tc->task) & _NOLOAD_))
continue;
}
}
} else if (!(task_state(tc->task) & fd->state))
continue;
}
if ((fd->flags & FOREACH_STATE) &&
(!STRNEQ(task_state_string(tc->task, buf, 0), fd->state)))
continue;

if (specified) {
for (j = 0; j < fd->tasks; j++) {
Expand Down

0 comments on commit 558aecc

Please sign in to comment.