[PATCH] add option -E for foreach

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Dave,

The patch is used to add a new option, "-E regex", to perform the
command(s) on all commands whose names contains a match to "regex".
"regex" is interpreted as an POSIX extended regular expression.

The new option is helpful when using to search some commands whose names
are similar. And I think it is more reliable than "foreach <name>
<command> | grep xxx", for information comes from command may have a
match to "xxx".

P.S.
The patch uses some function defined in regex.h, which is offered by glibc.

-- 
--
Regards
Qiao Nuohan

diff --git a/defs.h b/defs.h
index a942dbb..deabe91 100755
--- a/defs.h
+++ b/defs.h
@@ -47,6 +47,7 @@
 #include <sys/wait.h>
 #include <sys/time.h>
 #include <execinfo.h> /* backtrace() */
+#include <regex.h>
 
 #ifndef ATTRIBUTE_UNUSED
 #define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
@@ -977,6 +978,7 @@ extern struct machdep_table *machdep;
 #define FOREACH_F_FLAG  (0x400000)
 #define FOREACH_x_FLAG  (0x800000)
 #define FOREACH_d_FLAG (0x1000000)
+#define FOREACH_E_FLAG (0x2000000)
 
 struct foreach_data {
 	ulong flags;
@@ -985,6 +987,7 @@ struct foreach_data {
         char *comm_array[MAX_FOREACH_COMMS];
         ulong pid_array[MAX_FOREACH_PIDS];
 	ulong arg_array[MAX_FOREACH_ARGS];
+	regex_t regex;
 	char *reference;
 	int keys;
 	int pids;
diff --git a/help.c b/help.c
index f752283..03f8b84 100755
--- a/help.c
+++ b/help.c
@@ -725,7 +725,7 @@ NULL,
 char *help_foreach[] = {
 "foreach",
 "display command data for multiple tasks in the system",
-"[[pid | taskp | name | [kernel | user]] ...] command [flag] [argument]",
+"[[pid | taskp | name | [kernel | user]] ... | -E regex] command [flag] [argument]",
 "  This command allows for a an examination of various kernel data associated",
 "  with any, or all, tasks in the system, without having to set the context",
 "  to each targeted task.\n",
@@ -737,7 +737,10 @@ 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.",
+" -E regex  perform the command(s) on all commands whose names contains a match",
+"           to the given regex. regex is interpreted as an POSIX extended regular",
+"           expression.\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",
@@ -794,6 +797,17 @@ char *help_foreach[] = {
 "  Display the open files for all tasks:\n",
 "    %s> foreach files",
 "    ...\n",
+"  Display the state of tasks whose name contains a match to 'event.*':\n",
+"    %s> foreach -E 'event.*' task -R state",
+"    PID: 99     TASK: ffff8804750d5500  CPU: 0   COMMAND: \"events/0\"",
+"      state = 1,",
+"    ",
+"    PID: 100    TASK: ffff8804750d4ac0  CPU: 1   COMMAND: \"events/1\"",
+"      state = 1,"
+"    ",
+"    PID: 101    TASK: ffff8804750d4080  CPU: 2   COMMAND: \"events/2\"",
+"      state = 1,",
+"    ...\n",
 NULL
 };
 
diff --git a/task.c b/task.c
index fde86eb..b8b709d 100755
--- a/task.c
+++ b/task.c
@@ -4896,9 +4896,14 @@ cmd_foreach(void)
 	BZERO(&foreach_data, sizeof(struct foreach_data));
 	fd = &foreach_data;
 
-        while ((c = getopt(argcnt, args, "R:vomlgersStTpukcfFxhd")) != EOF) {
+        while ((c = getopt(argcnt, args, "E:R:vomlgersStTpukcfFxhd")) != EOF) {
                 switch(c)
 		{
+		case 'E':
+			if (regcomp(&fd->regex, optarg, REG_EXTENDED|REG_NOSUB))
+				error(FATAL, "invalid regular expression!\n");
+			fd->flags |= FOREACH_E_FLAG;
+			break;
 		case 'R':
 			fd->reference = optarg;
 			break;
@@ -5021,6 +5026,9 @@ cmd_foreach(void)
 			switch (str_to_context(args[optind], &value, &tc))
 			{
 			case STR_PID:
+                                if (fd->flags & FOREACH_E_FLAG)
+                                        error(FATAL, "'-E regex' and 'pid' "
+                                            "are mutually exclusive!\n");
                                 if (p == MAX_FOREACH_PIDS)
                                         error(INFO,
                                             "too many pids specified!\n");
@@ -5033,6 +5041,9 @@ cmd_foreach(void)
 				break;
 
 			case STR_TASK:
+                                if (fd->flags & FOREACH_E_FLAG)
+                                        error(FATAL, "'-E regex' and 'taskp' "
+                                            "are mutually exclusive!\n");
                                 if (t == MAX_FOREACH_TASKS)
                                         error(INFO,
                                             "too many tasks specified!\n");
@@ -5053,6 +5064,9 @@ cmd_foreach(void)
 		 *  Select all kernel threads.
 		 */
 		if (STREQ(args[optind], "kernel")) {
+                        if (fd->flags & FOREACH_E_FLAG)
+                                error(FATAL, "'-E regex' and 'kernel' "
+                                   "are mutually exclusive!\n");
 			if (fd->flags & FOREACH_USER)
 				error(FATAL, 
 				   "user and kernel are mutually exclusive!\n");
@@ -5065,6 +5079,9 @@ cmd_foreach(void)
 		 *  Select only user threads.
 		 */
                 if (STREQ(args[optind], "user")) {
+                        if (fd->flags & FOREACH_E_FLAG)
+                                error(FATAL, "'-E regex' and 'user' "
+                                   "are mutually exclusive!\n");
                         if (fd->flags & FOREACH_KERNEL)
                                 error(FATAL, 
                                    "user and kernel are mutually exclusive!\n");
@@ -5077,6 +5094,9 @@ cmd_foreach(void)
 		 *  Select only active tasks (dumpfile only)
 	  	 */
                 if (STREQ(args[optind], "active")) {
+                        if (fd->flags & FOREACH_E_FLAG)
+                                error(FATAL, "'-E regex' and 'active' "
+                                   "are mutually exclusive!\n");
 			if (!DUMPFILE())
 				error(FATAL, 
 				 "active option not allowed on live systems\n");
@@ -5092,6 +5112,9 @@ cmd_foreach(void)
 			&args[optind][1] : args[optind];
 
 		if (comm_exists(p1)) {
+                        if (fd->flags & FOREACH_E_FLAG)
+                                error(FATAL, "'-E regex' and 'name' "
+                                   "are mutually exclusive!\n");
 			if (c == MAX_FOREACH_COMMS)
 				error(INFO, "too many commands specified!\n");
 			else {
@@ -5335,6 +5358,10 @@ foreach(struct foreach_data *fd)
 				if (STREQ(fd->comm_array[j], tc->comm))
 					doit = TRUE;
 		}
+		else if (fd->flags & FOREACH_E_FLAG) {
+			if (regexec(&fd->regex, tc->comm, 0, NULL, 0) == 0)
+				doit = TRUE;
+		}
 		else 
 			doit = TRUE;
 
--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux