Add version check and soname for libovni
Adds ovni_version_check() to test the version at runtime, set the SONAME to the major version and install a symlinks to the complete version: libovni.so -> libovni.so.1 libovni.so.1 -> libovni.so.1.0.0 libovni.so.1.0.0
This commit is contained in:
		
							parent
							
								
									df169c89c3
								
							
						
					
					
						commit
						b6ce54b7ee
					
				| @ -6,6 +6,8 @@ trace is correct. | ||||
| 
 | ||||
| ## Trace processes and threads | ||||
| 
 | ||||
| - Call `ovni_version_check()` once before calling any ovni function. | ||||
| 
 | ||||
| - Call `ovni_proc_init()` when a new process begins the execution. | ||||
| 
 | ||||
| - Call `ovni_thread_init()` when a new thread begins the execution | ||||
|  | ||||
| @ -6,6 +6,10 @@ add_library(ovni SHARED | ||||
|   parson.c | ||||
| ) | ||||
| 
 | ||||
| set_target_properties(ovni PROPERTIES | ||||
|   VERSION 1.0.0 | ||||
|   SOVERSION 1) | ||||
| 
 | ||||
| target_include_directories(ovni PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) | ||||
| 
 | ||||
| configure_file("config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" ) | ||||
|  | ||||
							
								
								
									
										82
									
								
								src/ovni.c
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								src/ovni.c
									
									
									
									
									
								
							| @ -24,6 +24,88 @@ struct ovni_rproc rproc = {0}; | ||||
| /* Data per thread */ | ||||
| _Thread_local struct ovni_rthread rthread = {0}; | ||||
| 
 | ||||
| static int | ||||
| parse_version(const char *version, int tuple[3]) | ||||
| { | ||||
| 	char buf[64]; | ||||
| 
 | ||||
| 	if (strlen(version) >= 64) { | ||||
| 		err("parse_version: version too long: %s\n", version); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	strcpy(buf, version); | ||||
| 
 | ||||
| 	char *str = buf; | ||||
| 	char *which[] = { "major", "minor", "patch" }; | ||||
| 	char *delim[] = { ".", ".", ".-" }; | ||||
| 	char *save = NULL; | ||||
| 
 | ||||
| 	for (int i = 0; i < 3; i++) { | ||||
| 		char *num = strtok_r(str, delim[i], &save); | ||||
| 
 | ||||
| 		/* Subsequent calls need NULL as string */ | ||||
| 		str = NULL; | ||||
| 
 | ||||
| 		if (num == NULL) { | ||||
| 			err("parse_version: missing %s number: %s\n", | ||||
| 					which[i], version); | ||||
| 			return -1; | ||||
| 		} | ||||
| 
 | ||||
| 		errno = 0; | ||||
| 		char *endptr = NULL; | ||||
| 		int v = (int) strtol(num, &endptr, 10); | ||||
| 
 | ||||
| 		if (errno != 0 || endptr == num || endptr[0] != '\0') { | ||||
| 			err("parse_version: failed to parse %s number: %s\n", | ||||
| 					which[i], version); | ||||
| 			return -1; | ||||
| 		} | ||||
| 
 | ||||
| 		if (v < 0) { | ||||
| 			err("parse_version: invalid negative %s number: %s\n", | ||||
| 					which[i], version); | ||||
| 			return -1; | ||||
| 		} | ||||
| 
 | ||||
| 		tuple[i] = v; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void ovni_version_check_str(const char *version) | ||||
| { | ||||
| 	if (version == NULL) | ||||
| 		die("ovni version string is NULL\n"); | ||||
| 
 | ||||
| 	int provided[3]; | ||||
| 	int expected[3]; | ||||
| 
 | ||||
| 	if (parse_version(version, provided) != 0) | ||||
| 		die("failed to parse provided version \"%s\"\n", version); | ||||
| 
 | ||||
| 	if (parse_version(OVNI_LIB_VERSION, expected) != 0) | ||||
| 		die("failed to parse expected version \"%s\"\n", OVNI_LIB_VERSION); | ||||
| 
 | ||||
| 	/* Match the major */ | ||||
| 	if (provided[0] != expected[0]) { | ||||
| 		die("ovni major version mismatch: found %d (%s), expected %d (%s)\n", | ||||
| 				provided[0], version, | ||||
| 				expected[0], OVNI_LIB_VERSION); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Only fail if the minor is older */ | ||||
| 	if (provided[1] < expected[1]) { | ||||
| 		die("ovni minor version too old: found %d (%s), expected %d (%s)\n", | ||||
| 				provided[1], version, | ||||
| 				expected[1], OVNI_LIB_VERSION); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Ignore the patch number */ | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| create_trace_stream(void) | ||||
| { | ||||
|  | ||||
| @ -31,6 +31,9 @@ typedef struct json_value_t JSON_Value; | ||||
| #define OVNI_STREAM_VERSION 1 | ||||
| #define OVNI_MODEL_VERSION "O1 V1 T1 M1 D1 K1 61" | ||||
| 
 | ||||
| /* Follow https://semver.org rules for versioning */ | ||||
| #define OVNI_LIB_VERSION "1.0.0" | ||||
| 
 | ||||
| /* ----------------------- common ------------------------ */ | ||||
| 
 | ||||
| enum ovni_ev_flags { | ||||
| @ -120,6 +123,9 @@ struct ovni_rproc { | ||||
| 	JSON_Value *meta; | ||||
| }; | ||||
| 
 | ||||
| #define ovni_version_check() ovni_version_check_str(OVNI_LIB_VERSION) | ||||
| void ovni_version_check_str(const char *version); | ||||
| 
 | ||||
| void ovni_proc_init(int app, const char *loom, int pid); | ||||
| 
 | ||||
| /* Sets the MPI rank of the current process and the number of total nranks */ | ||||
|  | ||||
| @ -86,6 +86,7 @@ instr_start(int rank, int nranks) | ||||
| 
 | ||||
| 	sprintf(rankname, "%s.%d", hostname, rank); | ||||
| 
 | ||||
| 	ovni_version_check(); | ||||
| 	ovni_proc_init(1, rankname, getpid()); | ||||
| 	ovni_proc_set_rank(rank, nranks); | ||||
| 	ovni_thread_init(gettid()); | ||||
|  | ||||
| @ -14,3 +14,5 @@ ovni_test(sort-first-and-full-ring.c SORT | ||||
| ovni_test(burst-stats.c REGEX "burst stats: median 33 ns, avg 33\.0 ns, max 33 ns") | ||||
| ovni_test(mp-simple.c MP) | ||||
| ovni_test(mp-rank.c MP) | ||||
| ovni_test(version-good.c) | ||||
| ovni_test(version-bad.c SHOULD_FAIL REGEX "version mismatch") | ||||
|  | ||||
							
								
								
									
										15
									
								
								test/emu/ovni/version-bad.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/emu/ovni/version-bad.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| /* Copyright (c) 2021-2022 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| 
 | ||||
| #undef OVNI_LIB_VERSION | ||||
| #define OVNI_LIB_VERSION "0.0.0" /* Cause the major to fail */ | ||||
| 
 | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	/* Should fail */ | ||||
| 	ovni_version_check(); | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										16
									
								
								test/emu/ovni/version-good.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								test/emu/ovni/version-good.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| /* Copyright (c) 2021-2022 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #include "instr_ovni.h" | ||||
| 
 | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	ovni_version_check(); | ||||
| 
 | ||||
| 	/* Create a dummy trace */ | ||||
| 	instr_start(0, 1); | ||||
| 	instr_end(); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user