From 558aecc98987e54b122a09ce0d3c3484b034277f Mon Sep 17 00:00:00 2001 From: Lianbo Jiang Date: Wed, 2 Aug 2023 16:18:41 +0800 Subject: [PATCH] Fix "foreach" command with "DE" state to display only expected tasks 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 --- defs.h | 2 +- task.c | 52 +++++++++++++++++++--------------------------------- 2 files changed, 20 insertions(+), 34 deletions(-) diff --git a/defs.h b/defs.h index 358f3655..5ee60f1e 100644 --- a/defs.h +++ b/defs.h @@ -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; diff --git a/task.c b/task.c index b9076da3..c9206f50 100644 --- a/task.c +++ b/task.c @@ -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++; @@ -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++) {