All of lore.kernel.org
 help / color / mirror / Atom feed
From: Avinesh Kumar <akumar@suse.de>
To: Li Wang <liwang@redhat.com>
Cc: ltp@lists.linux.it
Subject: Re: [LTP] [PATCH 1/3] shell/lib: refactor checkpoint with shared path for exec() support
Date: Tue, 17 Jun 2025 14:18:22 +0200	[thread overview]
Message-ID: <6179048.lOV4Wx5bFT@thinkpad> (raw)
In-Reply-To: <20250616102619.54254-2-liwang@redhat.com>

Hi Li,

Thank you for this refactoring and fixing the pec test regression,
I tested this patchset.

Tested-by: Avinesh Kumar <akumar@suse.de>


Regards,
Avinesh

On Monday, June 16, 2025 12:26:17 PM CEST Li Wang via ltp wrote:
> This patch refactors shell checkpoint mechanism to support exec()
> based process synchronization by introducing support for a shared
> futex region via a configurable path.
> 
> Key changes:
> 
>  - Introduce LTP_IPC_PATH environment variable to specify the futex
>    shared memory file used for checkpoint synchronization.
>  - Add magic header "LTPM" to validate the shared memory file content.
>  - Add checkpoint_reinit() to re-attach futex mapping for wait/wake
>    operations in exec()'ed processes.
>  - Update tst_checkpoint CLI tool to support "init", "wait", and "wake"
>    commands with a unified interface.
> 
> Signed-off-by: Li Wang <liwang@redhat.com>
> ---
>  include/tst_checkpoint_fn.h    | 20 +++++++++-
>  lib/tst_checkpoint.c           | 70 +++++++++++++++++++++++-----------
>  testcases/lib/tst_checkpoint.c | 27 +++++++------
>  testcases/lib/tst_test.sh      |  2 +
>  4 files changed, 83 insertions(+), 36 deletions(-)
> 
> diff --git a/include/tst_checkpoint_fn.h b/include/tst_checkpoint_fn.h
> index 3a010d616..209296fe0 100644
> --- a/include/tst_checkpoint_fn.h
> +++ b/include/tst_checkpoint_fn.h
> @@ -6,13 +6,29 @@
>  #define TST_CHECKPOINT_FN__
>  
>  /*
> - * Checkpoint initializaton, must be done first.
> + * Checkpoint initialization.
>   *
> - * NOTE: tst_tmpdir() must be called beforehand.
> + * This function sets up the shared memory region used for process
> + * synchronization via futexes. It must be called before any checkpoint
> + * operations such as tst_checkpoint_wait() or tst_checkpoint_wake().
>   */
>  void tst_checkpoint_init(const char *file, const int lineno,
>  			 void (*cleanup_fn)(void));
>  
> +/*
> + * Checkpoint reinitialization.
> + *
> + * This function re-attaches to an existing shared memory checkpoint region
> + * pointed to by the LTP_IPC_PATH environment variable. It is typically used
> + * in child processes (e.g., shell scripts) to synchronize with the main test.
> + *
> + * The function verifies the magic header in the shared memory file and maps
> + * the futex array into memory. It must be called before using checkpoint
> + * operations in a process that did not perform the original initialization.
> + */
> +void tst_checkpoint_reinit(const char *file, const int lineno,
> +			   void (*cleanup_fn)(void));
> +
>  /*
>   * Waits for wakeup.
>   *
> diff --git a/lib/tst_checkpoint.c b/lib/tst_checkpoint.c
> index 6a294b28b..5efbf98d2 100644
> --- a/lib/tst_checkpoint.c
> +++ b/lib/tst_checkpoint.c
> @@ -38,8 +38,9 @@ unsigned int tst_max_futexes;
>  void tst_checkpoint_init(const char *file, const int lineno,
>                           void (*cleanup_fn)(void))
>  {
> +	char *path = getenv("LTP_IPC_PATH");
> +	size_t page_size = getpagesize();
>  	int fd;
> -	unsigned int page_size;
>  
>  	if (tst_futexes) {
>  		tst_brkm_(file, lineno, TBROK, cleanup_fn,
> @@ -47,35 +48,58 @@ void tst_checkpoint_init(const char *file, const int lineno,
>  		return;
>  	}
>  
> -	/*
> -	 * The parent test process is responsible for creating the temporary
> -	 * directory and therefore must pass non-zero cleanup (to remove the
> -	 * directory if something went wrong).
> -	 *
> -	 * We cannot do this check unconditionally because if we need to init
> -	 * the checkpoint from a binary that was started by exec() the
> -	 * tst_tmpdir_created() will return false because the tmpdir was
> -	 * created by parent. In this case we expect the subprogram can call
> -	 * the init as a first function with NULL as cleanup function.
> -	 */
> -	if (cleanup_fn && !tst_tmpdir_created()) {
> -		tst_brkm_(file, lineno, TBROK, cleanup_fn,
> -			"You have to create test temporary directory "
> -			"first (call tst_tmpdir())");
> -		return;
> +	if (!path) {
> +		char *tmp_path = NULL;
> +
> +		if (!tst_tmpdir_created())
> +			tst_tmpdir();
> +
> +		safe_asprintf(__FILE__, __LINE__, cleanup_fn, &tmp_path,
> +				"%s/ltp_checkpoint", tst_get_tmpdir());
> +		path = tmp_path;
>  	}
>  
> -	page_size = getpagesize();
> +	fd = SAFE_OPEN(cleanup_fn, path, O_RDWR | O_CREAT, 0666);
> +	SAFE_WRITE(cleanup_fn, 1, fd, "LTPM", 4);
> +
> +	tst_futexes = SAFE_MMAP(cleanup_fn, NULL, page_size,
> +				PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
> +
> +	tst_futexes = (futex_t *)((char *)tst_futexes + 4);
> +	tst_max_futexes = (page_size - 4) / sizeof(futex_t);
> +
> +	SAFE_CLOSE(cleanup_fn, fd);
> +}
> +
> +void tst_checkpoint_reinit(const char *file, const int lineno,
> +			   void (*cleanup_fn)(void))
> +{
> +	const char *path = getenv("LTP_IPC_PATH");
> +	size_t page_size = getpagesize();
> +	int fd;
>  
> -	fd = SAFE_OPEN(cleanup_fn, "checkpoint_futex_base_file",
> -	               O_RDWR | O_CREAT, 0666);
> +	if (!path) {
> +		tst_brkm_(file, lineno, TBROK, cleanup_fn,
> +				"LTP_IPC_PATH is not defined");
> +	}
>  
> -	SAFE_FTRUNCATE(cleanup_fn, fd, page_size);
> +	if (access(path, F_OK)) {
> +		tst_brkm_(file, lineno, TBROK, cleanup_fn,
> +				"File %s does not exist!", path);
> +	}
>  
> +	fd = SAFE_OPEN(cleanup_fn, path, O_RDWR);
>  	tst_futexes = SAFE_MMAP(cleanup_fn, NULL, page_size,
> -	                    PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
> +			PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
> +
> +	char *ptr = (char *)tst_futexes;
> +	if (memcmp(ptr, "LTPM", 4) != 0) {
> +		tst_brkm_(file, lineno, TBROK, cleanup_fn,
> +				"Invalid shared memory region (bad magic)");
> +	}
>  
> -	tst_max_futexes = page_size / sizeof(uint32_t);
> +	tst_futexes = (futex_t *)((char *)tst_futexes + 4);
> +	tst_max_futexes = (page_size - 4) / sizeof(futex_t);
>  
>  	SAFE_CLOSE(cleanup_fn, fd);
>  }
> diff --git a/testcases/lib/tst_checkpoint.c b/testcases/lib/tst_checkpoint.c
> index c70c4e8e5..35a0c0dfa 100644
> --- a/testcases/lib/tst_checkpoint.c
> +++ b/testcases/lib/tst_checkpoint.c
> @@ -9,11 +9,14 @@
>  #include <stdlib.h>
>  #define TST_NO_DEFAULT_MAIN
>  #include "tst_test.h"
> +#include "tst_checkpoint.h"
>  
>  static void print_help(void)
>  {
> -	printf("Usage: tst_checkpoint wait TIMEOUT ID\n");
> +	printf("Usage: tst_checkpoint init\n");
> +	printf("   or: tst_checkpoint wait TIMEOUT ID\n");
>  	printf("   or: tst_checkpoint wake TIMEOUT ID NR_WAKE\n");
> +	printf("Arguments:\n");
>  	printf("       TIMEOUT - timeout in ms\n");
>  	printf("       ID - checkpoint id\n");
>  	printf("       NR_WAKE - number of processes to wake up\n");
> @@ -43,8 +46,13 @@ int main(int argc, char *argv[])
>  	int ret;
>  	int type;
>  
> -	if (argc < 3)
> -		goto help;
> +	if (!strcmp(argv[1], "init")) {
> +		if (argc != 2)
> +			goto help;
> +
> +		tst_checkpoint_init(__FILE__, __LINE__, NULL);
> +		return 0;
> +	}
>  
>  	if (!strcmp(argv[1], "wait")) {
>  		type = 0;
> @@ -70,17 +78,14 @@ int main(int argc, char *argv[])
>  		goto help;
>  	}
>  
> -	tst_reinit();
> +	tst_checkpoint_reinit(__FILE__, __LINE__, NULL);
>  
> -	if (type)
> -		ret = tst_checkpoint_wake(id, nr_wake, timeout);
> -	else
> +	if (type == 0)
>  		ret = tst_checkpoint_wait(id, timeout);
> -
> -	if (ret)
> -		return 1;
>  	else
> -		return 0;
> +		ret = tst_checkpoint_wake(id, nr_wake, timeout);
> +
> +	return ret ? 1 : 0;
>  
>  help:
>  	print_help();
> diff --git a/testcases/lib/tst_test.sh b/testcases/lib/tst_test.sh
> index c32bd8b19..e5e76067b 100644
> --- a/testcases/lib/tst_test.sh
> +++ b/testcases/lib/tst_test.sh
> @@ -629,6 +629,8 @@ _tst_init_checkpoints()
>  	ROD_SILENT dd if=/dev/zero of="$LTP_IPC_PATH" bs="$pagesize" count=1
>  	ROD_SILENT chmod 600 "$LTP_IPC_PATH"
>  	export LTP_IPC_PATH
> +
> +	tst_checkpoint init
>  }
>  
>  _prepare_device()
> 





-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

  reply	other threads:[~2025-06-17 12:18 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-16 10:26 [LTP] [PATCH 0/3] checkpoint: Refactor and unify shell/C reinit support Li Wang via ltp
2025-06-16 10:26 ` [LTP] [PATCH 1/3] shell/lib: refactor checkpoint with shared path for exec() support Li Wang via ltp
2025-06-17 12:18   ` Avinesh Kumar [this message]
2025-06-16 10:26 ` [LTP] [PATCH 2/3] kernel/pec: switch to new checkpoint wait/wake interface Li Wang via ltp
2025-06-16 10:26 ` [LTP] [PATCH 3/3] tst_checkpoint: Detect and reinit shell or C style checkpoint file Li Wang via ltp
2025-06-26 13:26 ` [LTP] [PATCH 0/3] checkpoint: Refactor and unify shell/C reinit support Cyril Hrubis
2025-06-26 15:09   ` Li Wang via ltp
2025-06-27  7:49     ` Cyril Hrubis
2025-06-27  9:25       ` Li Wang via ltp
2025-06-27 10:20         ` Cyril Hrubis
2025-06-27 10:28           ` Li Wang via ltp
2025-06-27 10:43             ` Cyril Hrubis
2025-06-27 10:49               ` Li Wang via ltp

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6179048.lOV4Wx5bFT@thinkpad \
    --to=akumar@suse.de \
    --cc=liwang@redhat.com \
    --cc=ltp@lists.linux.it \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.