Copy Paraver configs to output directory

This commit is contained in:
Rodrigo Arias 2023-02-16 11:04:50 +01:00 committed by Rodrigo Arias Mallo
parent 819f767dbd
commit f76d160c69
7 changed files with 217 additions and 0 deletions

View File

@ -34,6 +34,7 @@ add_library(emu STATIC
pv/prf.c pv/prf.c
pv/prv.c pv/prv.c
pv/pvt.c pv/pvt.c
pv/cfg.c
recorder.c recorder.c
system.c system.c
task.c task.c

165
src/emu/pv/cfg.c Normal file
View 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
View 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 */

View File

@ -5,6 +5,8 @@
#include "recorder.h" #include "recorder.h"
#include "pv/cfg.h"
int int
recorder_init(struct recorder *rec, const char *dir) 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; return 0;
} }

View File

@ -42,9 +42,13 @@ function(unit_test source)
COMMAND "${OVNI_TEST_NAME}" COMMAND "${OVNI_TEST_NAME}"
WORKING_DIRECTORY "${OVNI_TEST_BUILD_DIR}") WORKING_DIRECTORY "${OVNI_TEST_BUILD_DIR}")
list(APPEND OVNI_TEST_ENV
"OVNI_CONFIG_DIR=${CMAKE_SOURCE_DIR}/cfg")
set_tests_properties("${OVNI_TEST_NAME}" set_tests_properties("${OVNI_TEST_NAME}"
PROPERTIES PROPERTIES
RUN_SERIAL TRUE RUN_SERIAL TRUE
ENVIRONMENT "${OVNI_TEST_ENV}"
WORKING_DIRECTORY "${OVNI_TEST_BUILD_DIR}") WORKING_DIRECTORY "${OVNI_TEST_BUILD_DIR}")
endfunction(unit_test) endfunction(unit_test)

View File

@ -14,6 +14,7 @@ unit_test(bay-hash-speed.c)
unit_test(mux.c) unit_test(mux.c)
unit_test(value.c) unit_test(value.c)
unit_test(prv.c) unit_test(prv.c)
unit_test(cfg.c)
#unit_test(ovni_model.c) #unit_test(ovni_model.c)
#unit_test(trace.c) #unit_test(trace.c)
#unit_test(emu.c) #unit_test(emu.c)

29
test/unit/cfg.c Normal file
View 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;
}