Sophie

Sophie

distrib > Mageia > 5 > i586 > media > core-updates-src > by-pkgid > c454047046288fa22cc04811dc0287e0 > files > 20

rpm-4.12.0.1-20.3.mga5.src.rpm

From 35bcd948b00a3c904d5278e06987485ee7c2758e Mon Sep 17 00:00:00 2001
From: Colin Guthrie <colin@mageia.org>
Date: Tue, 22 Jul 2014 22:42:07 +0100
Subject: [PATCH] filetriggers: Start filetriggers in priority order.

This ensures that filetriggers are started in a more deterministic way
whereby they are grouped by priority and executed to completion before
moving on to executing the next highest priority.
---
 doc/manual/filetriggers |  8 ++++++-
 lib/filetriggers.c      | 63 ++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/doc/manual/filetriggers b/doc/manual/filetriggers
index 3bde56c..77d5919 100644
--- a/doc/manual/filetriggers
+++ b/doc/manual/filetriggers
@@ -64,7 +64,13 @@ some files match, the corresponding {{prog|%_filetriggersdir/<name>.script}} is
 called, with matching lines passed in stdin.
 
 Note that this is done in parallel, so multiple {{prog|<name>.script}} may be running
-at the same time.
+at the same time. As it may be required to run some filetriggers before others,
+a priority mechanism is supported and only those triggers with the same priority
+are run in parallel before moving on to the next highest priority.
+
+To prioritize triggers, simply prefix them with a two digit number followed by a
+hyphen, e.g. {{file|00-ldconfig.script}}. Only the range 00 to 99 is supported
+and if no numeric prefix is detected then the default priority of 50 is assumed.
 
 When it's done, {{file|/var/lib/rpm/files-awaiting-filetriggers}} is removed.
 
diff --git a/lib/filetriggers.c b/lib/filetriggers.c
index f5817bf..a1172e0 100644
--- a/lib/filetriggers.c
+++ b/lib/filetriggers.c
@@ -67,6 +67,8 @@ struct filetrigger_raw {
 struct filetrigger {
      regex_t regexp;
      char *name;
+     char *matched;
+     int priority;
      int command_pipe;
      int command_pid;
 };
@@ -146,7 +148,18 @@ static void getFiletriggers(const char *rootDir, regex_t *matches_any, int *nb,
      *list = calloc(*nb, sizeof(**list));
      int i;
      for (i = 0; i < *nb; i++) {
-	  (*list)[i].name = list_raw[i].name;
+	  char *n = (*list)[i].name = list_raw[i].name;
+	  (*list)[i].matched = NULL;
+	  (*list)[i].priority = 50;
+	  if (strlen(n) > 3 && '-' == n[2]) {
+	      if ('0' == n[0] && '0' == n[1])
+	          (*list)[i].priority = 0;
+	      else {
+	          int priority = atoi(n);
+	          if (priority > 0 && priority < 100)
+	              (*list)[i].priority = priority;
+	      }
+	  }
 	  compileFiletriggersRegexp(list_raw[i].regexp, &(*list)[i].regexp);
      }
      free(list_raw);
@@ -159,6 +172,8 @@ static void freeFiletriggers(regex_t *matches_any, int nb, struct filetrigger *l
      for (i = 0; i < nb; i++) {
 	  regfree(&list[i].regexp);
 	  free(list[i].name);
+	  if (list[i].matched)
+		  free(list[i].matched);
      }
      free(list);
 }
@@ -236,6 +251,8 @@ void rpmRunFileTriggers(const char *rootDir)
           awaiting = fopen(file, "r");
      if (awaiting) {
 	  char tmp[1024];
+	  int matched_any = 0;
+	  int matched_priorities[100] = { 0 };
 
 	  void *oldhandler = signal(SIGPIPE, SIG_IGN);
 
@@ -245,20 +262,44 @@ void rpmRunFileTriggers(const char *rootDir)
 		    int i;
 		    for (i = 0; i < nb; i++)
 			 if (is_regexp_matching(&list[i].regexp, tmp)) {
-			      mayStartFiletrigger(rootDir, &list[i]);
-			      write(list[i].command_pipe, tmp, strlen(tmp));
+			      int len = strlen(tmp);
+			      matched_any = matched_priorities[list[i].priority] = 1;
+			      if (!list[i].matched) {
+			          list[i].matched = xmalloc(len+1);
+			          strncpy(list[i].matched, tmp, len+1);
+			      } else {
+			          char *oldtmp = list[i].matched;
+			          int oldlen = strlen(oldtmp);
+			          list[i].matched = xmalloc(oldlen+len+1);
+			          strncpy(list[i].matched, oldtmp, oldlen);
+			          strncpy(list[i].matched+oldlen, tmp, len+1);
+			          free(oldtmp);
+			      }
 			 }
 	       }
 	  fclose(awaiting);
 
-	  int i;
-	  for (i = 0; i < nb; i++)
-	       if (list[i].command_pipe) {
-		    close(list[i].command_pipe);
-		    int status;
-		    rpmlog(RPMLOG_DEBUG, "[filetriggers] waiting for %s to end\n", list[i].name);
-		    waitpid(list[i].command_pid, &status, 0);
-	       }
+	  if (matched_any) {
+		  int i;
+		  for (i = 0; i < 100; ++i) {
+			  int j;
+			  if (!matched_priorities[i]) continue;
+
+			  for (j = 0; j < nb; j++)
+			       if (list[j].matched && list[j].priority == i) {
+				    mayStartFiletrigger(rootDir, &list[j]);
+				    write(list[j].command_pipe, list[j].matched, strlen(list[j].matched));
+			       }
+			  for (j = 0; j < nb; j++)
+			       if (list[j].command_pipe) {
+				    int status;
+				    close(list[j].command_pipe);
+				    list[j].command_pipe = 0;
+				    rpmlog(RPMLOG_DEBUG, "[filetriggers] waiting for %s to end\n", list[j].name);
+				    waitpid(list[j].command_pid, &status, 0);
+			       }
+		  }
+	  }
 	  freeFiletriggers(&matches_any, nb, list);
 
 	  signal(SIGPIPE, oldhandler);
-- 
1.9.2