1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-05-28 17:41:28 +03:00

tests/pkd: support -L, --temp-dir=<mkdtemp-template>

Teach `pkd` a new flag `-L, --temp-dir=<mkdtemp-template>` to enable
behavior whereby `pkd` creates a new temporary directory and uses it
for a workspace while running.

The original design of `pkd` assumed that it could freely use the
current working directory from wherever it happened to be invoked.
But, this could pose a problem when multiple `pkd` instances are run
in parallel from the same working directory, due to the usage of
various temporary files within that directory.

To avoid the problem of multiple `pkd` instances interfering with
each other, expose a `-L` flag for optionally specifying a `mkdtemp`
template string such that a temporary scratch space is used instead.

Testing notes:
 - I ran handfuls of iterations locally using the new flag
   and observed `pkd` is indeed using scratch space as desired.

Resolves https://gitlab.com/libssh/libssh-mirror/-/issues/143.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit b610757e6366c3093879f1ac5ddb7520169b0869)
This commit is contained in:
Jon Simons 2022-11-12 17:06:31 -05:00 committed by Jakub Jelen
parent ed8b7ea7a7
commit cd2bf21f9a
2 changed files with 101 additions and 4 deletions

View File

@ -30,6 +30,8 @@ struct pkd_daemon_args {
uint64_t rekey_data_limit;
int original_dir_fd;
struct {
int list;
@ -44,6 +46,10 @@ struct pkd_daemon_args {
struct {
char *mkdtemp_str;
} socket_wrapper;
struct {
char *mkdtemp_str;
} temp_dir;
} opts;
};

View File

@ -1,15 +1,16 @@
/*
* pkd_hello.c --
*
* (c) 2014, 2017-2018 Jon Simons <jon@jonsimons.org>
* (c) 2014, 2017-2018, 2022 Jon Simons <jon@jonsimons.org>
*/
#include "config.h"
#include <fcntl.h>
#include <setjmp.h> // for cmocka
#include <stdarg.h> // for cmocka
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // for cmocka
#include <unistd.h>
#include <cmocka.h>
#include "libssh/priv.h"
@ -33,7 +34,7 @@ static size_t default_payload_len = sizeof(default_payload_buf);
#include <argp.h>
#define PROGNAME "pkd_hello"
#define ARGP_PROGNAME "libssh " PROGNAME
const char *argp_program_version = ARGP_PROGNAME " 2017-07-12";
const char *argp_program_version = ARGP_PROGNAME " 2022-11-12";
const char *argp_program_bug_address = "Jon Simons <jon@jonsimons.org>";
static char doc[] = \
@ -61,6 +62,8 @@ static struct argp_option options[] = {
"Run each test for the given number of iterations (default is 10)", 0 },
{ "match", 'm', "testmatch", 0,
"Run all tests with the given string", 0 },
{ "temp-dir", 'L', "<mkdtemp-template>", 0,
"Run in a temporary directory using the given mkdtemp template", 0 },
{ "socket-wrapper-dir", 'w', "<mkdtemp-template>", 0,
"Run in socket-wrapper mode using the given mkdtemp directory template", 0 },
{ "stdout", 'o', NULL, 0,
@ -90,6 +93,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
case 'l':
pkd_dargs.opts.list = 1;
break;
case 'L':
pkd_dargs.opts.temp_dir.mkdtemp_str = arg;
break;
case 'i':
pkd_dargs.opts.iterations = atoi(arg);
break;
@ -950,6 +956,52 @@ static int pkd_run_tests(void) {
return rc;
}
static int pkd_init_temp_dir(void) {
int rc = 0;
char *mkdtemp_str = NULL;
pkd_dargs.original_dir_fd = -1;
if (pkd_dargs.opts.temp_dir.mkdtemp_str == NULL) {
return 0;
}
pkd_dargs.original_dir_fd = open(".", O_RDONLY);
if (pkd_dargs.original_dir_fd < 0) {
fprintf(stderr, "pkd_init_temp_dir open failed\n");
return -1;
}
mkdtemp_str = strdup(pkd_dargs.opts.temp_dir.mkdtemp_str);
if (mkdtemp_str == NULL) {
fprintf(stderr, "pkd_init_temp_dir strdup failed\n");
goto errstrdup;
}
pkd_dargs.opts.temp_dir.mkdtemp_str = mkdtemp_str;
if (mkdtemp(mkdtemp_str) == NULL) {
fprintf(stderr, "pkd_init_temp_dir mkdtemp '%s' failed\n", mkdtemp_str);
goto errmkdtemp;
}
rc = chdir(mkdtemp_str);
if (rc != 0) {
fprintf(stderr, "pkd_init_temp_dir chdir '%s' failed\n", mkdtemp_str);
goto errchdir;
}
return 0;
errchdir:
rmdir(mkdtemp_str);
errmkdtemp:
free(mkdtemp_str);
errstrdup:
close(pkd_dargs.original_dir_fd);
pkd_dargs.original_dir_fd = -1;
rc = -1;
return rc;
}
static int pkd_init_socket_wrapper(void) {
int rc = 0;
char *mkdtemp_str = NULL;
@ -991,6 +1043,33 @@ static int pkd_rmfiles(const char *path) {
return system_checked(bin);
}
static int pkd_cleanup_temp_dir(void) {
int rc = 0;
if (pkd_dargs.opts.temp_dir.mkdtemp_str == NULL) {
return 0;
}
if (fchdir(pkd_dargs.original_dir_fd) != 0) {
fprintf(stderr, "pkd_cleanup_temp_dir failed fchdir\n");
rc = -1;
goto out;
}
if (rmdir(pkd_dargs.opts.temp_dir.mkdtemp_str) != 0) {
fprintf(stderr, "pkd_cleanup_temp_dir rmdir '%s' failed\n",
pkd_dargs.opts.temp_dir.mkdtemp_str);
rc = -1;
goto out;
}
out:
close(pkd_dargs.original_dir_fd);
pkd_dargs.original_dir_fd = -1;
free(pkd_dargs.opts.temp_dir.mkdtemp_str);
return rc;
}
static int pkd_cleanup_socket_wrapper(void) {
int rc = 0;
@ -1042,10 +1121,16 @@ int main(int argc, char **argv) {
(void) argc; (void) argv;
#endif /* HAVE_ARGP_H */
rc = pkd_init_temp_dir();
if (rc != 0) {
fprintf(stderr, "pkd_init_temp_dir failed: %d\n", rc);
goto out_finalize;
}
rc = pkd_init_socket_wrapper();
if (rc != 0) {
fprintf(stderr, "pkd_init_socket_wrapper failed: %d\n", rc);
goto out_finalize;
goto out_tempdir;
}
if (pkd_dargs.opts.list != 0) {
@ -1064,6 +1149,12 @@ int main(int argc, char **argv) {
fprintf(stderr, "pkd_cleanup_socket_wrapper failed: %d\n", rc);
}
out_tempdir:
rc = pkd_cleanup_temp_dir();
if (rc != 0) {
fprintf(stderr, "pkd_cleanup_temp_dir failed: %d\n", rc);
}
out_finalize:
rc = ssh_finalize();
if (rc != 0) {