Copy Paraver configs to output directory
This commit is contained in:
		
							parent
							
								
									819f767dbd
								
							
						
					
					
						commit
						f76d160c69
					
				| @ -34,6 +34,7 @@ add_library(emu STATIC | ||||
|   pv/prf.c | ||||
|   pv/prv.c | ||||
|   pv/pvt.c | ||||
|   pv/cfg.c | ||||
|   recorder.c | ||||
|   system.c | ||||
|   task.c | ||||
|  | ||||
							
								
								
									
										165
									
								
								src/emu/pv/cfg.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								src/emu/pv/cfg.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,165 @@ | ||||
| /* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #define _POSIX_C_SOURCE 200112L | ||||
| 
 | ||||
| #include "cfg.h" | ||||
| 
 | ||||
| #include <dirent.h> | ||||
| #include <linux/limits.h> | ||||
| #include <stdio.h> | ||||
| #include <sys/stat.h> | ||||
| #include <unistd.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| #include "common.h" | ||||
| #include "config.h" | ||||
| 
 | ||||
| static int | ||||
| copy_file(const char *src, const char *dst) | ||||
| { | ||||
| 	char buffer[1024]; | ||||
| 
 | ||||
| 	FILE *infile = fopen(src, "r"); | ||||
| 
 | ||||
| 	if (infile == NULL) { | ||||
| 		err("fopen(%s) failed:", src); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	FILE *outfile = fopen(dst, "w"); | ||||
| 
 | ||||
| 	if (outfile == NULL) { | ||||
| 		err("fopen(%s) failed:", src); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	size_t bytes; | ||||
| 	while ((bytes = fread(buffer, 1, sizeof(buffer), infile)) > 0) | ||||
| 		fwrite(buffer, 1, bytes, outfile); | ||||
| 
 | ||||
| 	fclose(outfile); | ||||
| 	fclose(infile); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| copy_recursive(const char *src, const char *dst) | ||||
| { | ||||
| 	DIR *dir; | ||||
| 	int failed = 0; | ||||
| 
 | ||||
| 	if ((dir = opendir(src)) == NULL) { | ||||
| 		err("opendir '%s' failed:", src); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (mkdir(dst, 0755) != 0) { | ||||
| 		err("mkdir '%s' failed:", src); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Use the heap, as the recursion may exhaust the stack */ | ||||
| 	char *newsrc = calloc(1, PATH_MAX); | ||||
| 	if (newsrc == NULL) { | ||||
| 		err("calloc failed:"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	char *newdst = calloc(1, PATH_MAX); | ||||
| 	if (newdst == NULL) { | ||||
| 		die("calloc failed:"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	struct dirent *dirent; | ||||
| 	while ((dirent = readdir(dir)) != NULL) { | ||||
| 		struct stat st; | ||||
| 
 | ||||
| 		if (strcmp(dirent->d_name, ".") == 0) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (strcmp(dirent->d_name, "..") == 0) | ||||
| 			continue; | ||||
| 
 | ||||
| 		int n = snprintf(newsrc, PATH_MAX, "%s/%s", | ||||
| 				src, dirent->d_name); | ||||
| 
 | ||||
| 		if (n >= PATH_MAX) { | ||||
| 			err("src path too long: %s/%s", src, dirent->d_name); | ||||
| 			failed = 1; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		int m = snprintf(newdst, PATH_MAX, "%s/%s", | ||||
| 				dst, dirent->d_name); | ||||
| 
 | ||||
| 		if (m >= PATH_MAX) { | ||||
| 			err("dst path too long: %s/%s", dst, dirent->d_name); | ||||
| 			failed = 1; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if (stat(newsrc, &st) != 0) { | ||||
| 			err("stat '%s' failed:", newsrc); | ||||
| 			failed = 1; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if (S_ISDIR(st.st_mode)) { | ||||
| 			if (copy_recursive(newsrc, newdst) != 0) { | ||||
| 				failed = 1; | ||||
| 			} | ||||
| 		} else { | ||||
| 			if (copy_file(newsrc, newdst) != 0) { | ||||
| 				failed = 1; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	closedir(dir); | ||||
| 
 | ||||
| 	free(newsrc); | ||||
| 	free(newdst); | ||||
| 
 | ||||
| 	if (failed) { | ||||
| 		err("some files couldn't be copied"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| cfg_generate(const char *tracedir) | ||||
| { | ||||
| 	/* TODO: generate the configuration files dynamically instead of
 | ||||
| 	 * copying them from a directory */ | ||||
| 
 | ||||
| 	/* Allow override so we can run the tests without install */ | ||||
| 	char *src = getenv("OVNI_CONFIG_DIR"); | ||||
| 
 | ||||
| 	if (src == NULL) | ||||
| 		src = OVNI_CONFIG_DIR; | ||||
| 
 | ||||
| 	char dst[PATH_MAX]; | ||||
| 	char *cfg = "cfg"; | ||||
| 	if (snprintf(dst, PATH_MAX, "%s/%s", tracedir, cfg) >= PATH_MAX) { | ||||
| 		err("path too long: %s/%s", tracedir, cfg); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	struct stat st; | ||||
| 	if (stat(dst, &st) == 0) { | ||||
| 		err("directory '%s' already exists, skipping config copy", dst); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (copy_recursive(src, dst) != 0) { | ||||
| 		err("cannot copy config files: recursive copy failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										9
									
								
								src/emu/pv/cfg.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/emu/pv/cfg.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| /* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #ifndef CFG_H | ||||
| #define CFG_H | ||||
| 
 | ||||
| int cfg_generate(const char *tracedir); | ||||
| 
 | ||||
| #endif /* CFG_H */ | ||||
| @ -5,6 +5,8 @@ | ||||
| 
 | ||||
| #include "recorder.h" | ||||
| 
 | ||||
| #include "pv/cfg.h" | ||||
| 
 | ||||
| int | ||||
| recorder_init(struct recorder *rec, const char *dir) | ||||
| { | ||||
| @ -75,5 +77,11 @@ recorder_finish(struct recorder *rec) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* TODO: Use configs per pvt */ | ||||
| 	if (cfg_generate(rec->dir) != 0) { | ||||
| 		err("cfg_generate failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -42,9 +42,13 @@ function(unit_test source) | ||||
|     COMMAND "${OVNI_TEST_NAME}" | ||||
|     WORKING_DIRECTORY "${OVNI_TEST_BUILD_DIR}") | ||||
| 
 | ||||
|   list(APPEND OVNI_TEST_ENV | ||||
|     "OVNI_CONFIG_DIR=${CMAKE_SOURCE_DIR}/cfg") | ||||
| 
 | ||||
|   set_tests_properties("${OVNI_TEST_NAME}" | ||||
|     PROPERTIES | ||||
|       RUN_SERIAL TRUE | ||||
|       ENVIRONMENT "${OVNI_TEST_ENV}" | ||||
|       WORKING_DIRECTORY "${OVNI_TEST_BUILD_DIR}") | ||||
| endfunction(unit_test) | ||||
| 
 | ||||
|  | ||||
| @ -14,6 +14,7 @@ unit_test(bay-hash-speed.c) | ||||
| unit_test(mux.c) | ||||
| unit_test(value.c) | ||||
| unit_test(prv.c) | ||||
| unit_test(cfg.c) | ||||
| #unit_test(ovni_model.c) | ||||
| #unit_test(trace.c) | ||||
| #unit_test(emu.c) | ||||
|  | ||||
							
								
								
									
										29
									
								
								test/unit/cfg.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								test/unit/cfg.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| #define _GNU_SOURCE | ||||
| 
 | ||||
| #include "emu/pv/cfg.h" | ||||
| #include "common.h" | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/stat.h> | ||||
| #include <linux/limits.h> | ||||
| 
 | ||||
| int main(void) | ||||
| { | ||||
| 	char dir[] = "/tmp/ovni.trace.XXXXXX"; | ||||
| 	if (mkdtemp(dir) == NULL) | ||||
| 		die("mkdtemp failed:"); | ||||
| 
 | ||||
| 	if (cfg_generate(dir) != 0) | ||||
| 		die("cfg_generate failed"); | ||||
| 
 | ||||
| 	/* Check that one configuration file is present */ | ||||
| 	char cfg[PATH_MAX]; | ||||
| 	sprintf(cfg, "%s/cfg/cpu/ovni/pid.cfg", dir); | ||||
| 
 | ||||
| 	struct stat st; | ||||
| 	if (stat(cfg, &st) != 0) | ||||
| 		die("stat failed"); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user