51f100
commit 3a6c9a855195e6f6f44ad6dffe2cd4046426ab53
51f100
Author: Masahiko, Yamada <yamada.masahiko@fujitsu.com>
51f100
Date:   Wed Nov 25 21:46:26 2020 +0900
51f100
51f100
    fix for performance improvement of _mx_init_component() function
51f100
51f100
diff --git a/src/components/mx/linux-mx.c b/src/components/mx/linux-mx.c
51f100
index 2da406d14..34e6f02c2 100644
51f100
--- a/src/components/mx/linux-mx.c
51f100
+++ b/src/components/mx/linux-mx.c
51f100
@@ -224,26 +224,35 @@ _mx_init_component( int cidx )
51f100
 {
51f100
 
51f100
 	FILE *fff;
51f100
-	char test_string[BUFSIZ];
51f100
+	char *path;
51f100
+	int len, pathlen;
51f100
 
51f100
 	/* detect if MX available */
51f100
 
51f100
-	strncpy(mx_counters_exe,"mx_counters 2> /dev/null",BUFSIZ);
51f100
-	fff=popen(mx_counters_exe,"r");
51f100
-	/* popen only returns NULL if "sh" fails, not the actual command */
51f100
-	if (fgets(test_string,BUFSIZ,fff)==NULL) {
51f100
-	   pclose(fff);
51f100
-	   strncpy(mx_counters_exe,"./components/mx/utils/fake_mx_counters 2> /dev/null",BUFSIZ);
51f100
-	   fff=popen(mx_counters_exe,"r");
51f100
-	   if (fgets(test_string,BUFSIZ,fff)==NULL) {
51f100
-	      pclose(fff);
51f100
-	      /* neither real nor fake found */
51f100
-	      strncpy(_mx_vector.cmp_info.disabled_reason,
51f100
-		      "No MX utilities found",PAPI_MAX_STR_LEN);
51f100
-	      return PAPI_ECMP;
51f100
+	path = getenv("PATH");
51f100
+	pathlen = strlen(path);
51f100
+	while(pathlen > 0) {
51f100
+	   len = strcspn(path, ":");
51f100
+	   strncpy(mx_counters_exe, path, len);
51f100
+	   mx_counters_exe[len] = '\0';
51f100
+	   strcat(mx_counters_exe, "/mx_counters");
51f100
+	   fff = fopen(mx_counters_exe, "r");
51f100
+	   if (fff != NULL) {
51f100
+	      strcat(mx_counters_exe, " 2> /dev/null");
51f100
+	      break;
51f100
 	   }
51f100
+	   pathlen = pathlen - len - 1;
51f100
+	   if (pathlen > 0) {
51f100
+	      path = path + len + 1;
51f100
+	   }
51f100
+	}
51f100
+	if (fff == NULL) {
51f100
+	   /* neither real nor fake found */
51f100
+	   strncpy(_mx_vector.cmp_info.disabled_reason,
51f100
+		   "No MX utilities found",PAPI_MAX_STR_LEN);
51f100
+	   return PAPI_ECMP;
51f100
 	}
51f100
-	pclose(fff);
51f100
+	fclose(fff);
51f100
 
51f100
 	num_events=MX_MAX_COUNTERS;
51f100
 	_mx_vector.cmp_info.num_native_events=num_events;
51f100
commit 3a2560a86be44f4b15d96a45eda8e7f387b9166c
51f100
Author: Masahiko, Yamada <yamada.masahiko@fujitsu.com>
51f100
Date:   Tue Jan 26 16:30:40 2021 +0900
51f100
51f100
    Add string length check before strncpy() and strcat() calls in _mx_init_component()
51f100
    
51f100
    Myrinet Express-related component MX modules are initialized with the _mx_init_component() function,
51f100
    which is called from the PAPI_library_init() function.
51f100
    The popen(3) call runs a loadable module called "mx_counters",
51f100
    and if the loadable module does not exist,
51f100
    it attempts to run a loadable module called "./components/mx/utils/fake_mx_counters".
51f100
    In an environment where there are no "mx_counters" and "./components/mx/utils/fake_mx_counters" loadable modules,
51f100
    popen(3) will be called twice uselessly.
51f100
    popen(3) internally calls pipe(2) once, fork(2) twice and exec(2) once.
51f100
    
51f100
    The size of the user space of the application calling the PAPI_library_init() function affects the performance of fork(2),
51f100
    which is called as an extension of popen(3).
51f100
    As a result, the performance of the PAPI_library_init() function is affected by the amount of user space in the application
51f100
    that called the PAPI_library_init() function.
51f100
    
51f100
    In the _mx_init_component() function,
51f100
    the MX module only needs to be able to verify that a load module named "mx_counters" exists.
51f100
    We improved the _mx_init_component() function to call fopen(3) instead of popen(3).
51f100
    We add string length check before strncpy() and strcat() calls in _mx_init_component() function.
51f100
51f100
diff --git a/src/components/mx/linux-mx.c b/src/components/mx/linux-mx.c
51f100
index 34e6f02c2..c2920d65b 100644
51f100
--- a/src/components/mx/linux-mx.c
51f100
+++ b/src/components/mx/linux-mx.c
51f100
@@ -225,7 +225,7 @@ _mx_init_component( int cidx )
51f100
 
51f100
 	FILE *fff;
51f100
 	char *path;
51f100
-	int len, pathlen;
51f100
+	int checklen, len, pathlen;
51f100
 
51f100
 	/* detect if MX available */
51f100
 
51f100
@@ -233,13 +233,31 @@ _mx_init_component( int cidx )
51f100
 	pathlen = strlen(path);
51f100
 	while(pathlen > 0) {
51f100
 	   len = strcspn(path, ":");
51f100
-	   strncpy(mx_counters_exe, path, len);
51f100
+	   if (len < BUFSIZ) {
51f100
+	      strncpy(mx_counters_exe, path, len);
51f100
+	   } else {
51f100
+	      fff = NULL;
51f100
+	      break;
51f100
+	   }
51f100
 	   mx_counters_exe[len] = '\0';
51f100
-	   strcat(mx_counters_exe, "/mx_counters");
51f100
+	   checklen = len + strlen("/mx_counters");
51f100
+	   if (checklen < BUFSIZ) {
51f100
+	      strcat(mx_counters_exe, "/mx_counters");
51f100
+	   } else {
51f100
+	      fff = NULL;
51f100
+	      break;
51f100
+	   }
51f100
 	   fff = fopen(mx_counters_exe, "r");
51f100
 	   if (fff != NULL) {
51f100
-	      strcat(mx_counters_exe, " 2> /dev/null");
51f100
-	      break;
51f100
+	      checklen = checklen + strlen(" 2> /dev/null");
51f100
+	      if (checklen < BUFSIZ) {
51f100
+	         strcat(mx_counters_exe, " 2> /dev/null");
51f100
+	         break;
51f100
+	      } else {
51f100
+	         fclose(fff);
51f100
+	         fff = NULL;
51f100
+	         break;
51f100
+	      }
51f100
 	   }
51f100
 	   pathlen = pathlen - len - 1;
51f100
 	   if (pathlen > 0) {
51f100
@@ -247,7 +265,7 @@ _mx_init_component( int cidx )
51f100
 	   }
51f100
 	}
51f100
 	if (fff == NULL) {
51f100
-	   /* neither real nor fake found */
51f100
+	   /* mx_counters not found */
51f100
 	   strncpy(_mx_vector.cmp_info.disabled_reason,
51f100
 		   "No MX utilities found",PAPI_MAX_STR_LEN);
51f100
 	   return PAPI_ECMP;