public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
From: Cyril Hrubis <chrubis@suse.cz>
To: Andrea Cervesato <andrea.cervesato@suse.de>
Cc: ltp@lists.linux.it
Subject: Re: [LTP] [PATCH v7 3/6] Refactor mqns_03 using new LTP API
Date: Mon, 22 May 2023 16:41:30 +0200	[thread overview]
Message-ID: <ZGt_GrwbwPJChf6P@yuki> (raw)
In-Reply-To: <20230510124206.19627-4-andrea.cervesato@suse.de>

Hi!
> +#include "tst_test.h"
> +#include "lapi/sched.h"
> +#include "tst_safe_posix_ipc.h"
> +#include "tst_safe_stdio.h"
> +
> +#define CHECK_MQ_OPEN_RET(x) ((x) >= 0 || ((x) == -1 && errno != EMFILE))
> +
> +#define MQNAME1 "/MQ1"
> +#define MQNAME2 "/MQ2"
> +
> +static char *str_op;
> +static char *devdir;
> +static char *mqueue1;
> +static char *mqueue2;
> +static int *mq_freed1;
> +static int *mq_freed2;
> +
> +static void check_mqueue(void)
>  {
> -	char buf[30];
> -	mqd_t mqd;
>  	int rc;
> +	mqd_t mqd;
>  	struct stat statbuf;
>  
> -	(void) vtest;
> +	tst_res(TINFO, "Creating %s mqueue from within child process", MQNAME1);
>  
> -	close(p1[1]);
> -	close(p2[0]);
> +	mqd = TST_RETRY_FUNC(
> +		mq_open(MQNAME1, O_RDWR | O_CREAT | O_EXCL, 0777, NULL),
> +		CHECK_MQ_OPEN_RET);
> +	if (mqd == -1)
> +		tst_brk(TBROK | TERRNO, "mq_open failed");
>  
> -	if (read(p1[0], buf, 3) != 3) {	/* go */
> -		perror("read failed");
> -		exit(1);
> -	}
> +	SAFE_MQ_CLOSE(mqd);
> +	tst_atomic_inc(mq_freed1);

I do not think that we need atomicity here, the cleanup code does not
run concurently at all as the cleanup in the parent is triggered after
the child did exit. I suppose that instead we need to set the mq_freed
to be volatile because it's shared memory which may change at any
change, so we need to tell that to the compiler.

> -	mqd = tst_syscall(__NR_mq_open, NOSLASH_MQ1, O_RDWR | O_CREAT | O_EXCL,
> -		0755, NULL);
> -	if (mqd == -1) {
> -		write(p2[1], "mqfail", 7);
> -		exit(1);
> -	}
> +	tst_res(TINFO, "Mount %s from within child process", devdir);
>  
> -	mq_close(mqd);
> +	SAFE_MOUNT("mqueue", devdir, "mqueue", 0, NULL);
>  
> -	rc = mount("mqueue", DEV_MQUEUE2, "mqueue", 0, NULL);
> -	if (rc == -1) {
> -		write(p2[1], "mount1", 7);
> -		exit(1);
> -	}
> +	SAFE_STAT(mqueue1, &statbuf);
> +	tst_res(TPASS, "%s exists at first mount", mqueue1);
>  
> -	rc = stat(FNAM1, &statbuf);
> -	if (rc == -1) {
> -		write(p2[1], "stat1", 6);
> -		exit(1);
> -	}
> +	tst_res(TINFO, "Creating %s from within child process", mqueue2);
>  
> -	rc = creat(FNAM2, 0755);
> -	if (rc == -1) {
> -		write(p2[1], "creat", 6);
> -		exit(1);
> -	}
> +	rc = SAFE_CREAT(mqueue2, 0755);
> +	SAFE_CLOSE(rc);
> +	tst_atomic_inc(mq_freed2);
>  
> -	close(rc);
> +	tst_res(TINFO, "Mount %s from within child process a second time", devdir);
>  
> -	rc = umount(DEV_MQUEUE2);
> -	if (rc == -1) {
> -		write(p2[1], "umount", 7);
> -		exit(1);
> -	}
> +	SAFE_UMOUNT(devdir);
> +	SAFE_MOUNT("mqueue", devdir, "mqueue", 0, NULL);
>  
> -	rc = mount("mqueue", DEV_MQUEUE2, "mqueue", 0, NULL);
> -	if (rc == -1) {
> -		write(p2[1], "mount2", 7);
> -		exit(1);
> -	}
> +	SAFE_STAT(mqueue1, &statbuf);
> +	tst_res(TPASS, "%s exists at second mount", mqueue1);
>  
> -	rc = stat(FNAM1, &statbuf);
> -	if (rc == -1) {
> -		write(p2[1], "stat2", 7);
> -		exit(1);
> -	}
> +	SAFE_STAT(mqueue2, &statbuf);
> +	tst_res(TPASS, "%s exists at second mount", mqueue2);
>  
> -	rc = stat(FNAM2, &statbuf);
> -	if (rc == -1) {
> -		write(p2[1], "stat3", 7);
> -		exit(1);
> -	}
> +	SAFE_UMOUNT(devdir);
> +
> +	SAFE_MQ_UNLINK(MQNAME1);
> +	tst_atomic_store(0, mq_freed1);
>  
> -	write(p2[1], "done", 5);
> +	SAFE_MQ_UNLINK(MQNAME2);
> +	tst_atomic_store(0, mq_freed2);
> +}
>  
> -	exit(0);
> +static void run(void)
> +{
> +	const struct tst_clone_args clone_args = { CLONE_NEWIPC, SIGCHLD };
> +
> +	if (str_op && !strcmp(str_op, "clone")) {
> +		tst_res(TINFO, "Spawning isolated process");
> +
> +		if (!SAFE_CLONE(&clone_args)) {
> +			check_mqueue();
> +			return;
> +		}
> +	} else if (str_op && !strcmp(str_op, "unshare")) {
> +		tst_res(TINFO, "Spawning unshared process");
> +
> +		if (!SAFE_FORK()) {
> +			SAFE_UNSHARE(CLONE_NEWIPC);
> +			check_mqueue();
> +			return;
> +		}
> +	}
>  }
>  
>  static void setup(void)
>  {
> -	tst_require_root();
> -	check_mqns();
> +	char *tmpdir;
> +
> +	if (!str_op)
> +		tst_brk(TCONF, "Please specify clone|unshare child isolation");
> +
> +	tmpdir = tst_get_tmpdir();
> +
> +	SAFE_ASPRINTF(&devdir, "%s/mqueue", tmpdir);
> +	SAFE_MKDIR(devdir, 0755);
> +
> +	SAFE_ASPRINTF(&mqueue1, "%s" MQNAME1, devdir);
> +	SAFE_ASPRINTF(&mqueue2, "%s" MQNAME2, devdir);
> +
> +	mq_freed1 = SAFE_MMAP(NULL,
> +		sizeof(int),
> +		PROT_READ | PROT_WRITE,
> +		MAP_SHARED | MAP_ANONYMOUS,
> +		-1, 0);
> +
> +	mq_freed2 = SAFE_MMAP(NULL,
> +		sizeof(int),
> +		PROT_READ | PROT_WRITE,
> +		MAP_SHARED | MAP_ANONYMOUS,
> +		-1, 0);

So here you are allocating two pages of memory for something that is
basically two bitflags. Can you at least change this to a single mmap()
something as:

static int *mq_freed;

	mq_freed = SAFE_MMAP(NULL, 2 * sizeof(int), ...)


	mq_freed[0] = 1;
	...

Moreover since we can actually stat()/access() the mqueue we can as well
check for the existence of the devdir in the cleanup and only remove it
if it exists in the filesystem.

Also I would be more afraid of the mqueue filesystem being mounted in
the temp directory if we trigger a failure between one of the
mount()/umount() calls, so we should as well check if it's mounted in
the cleanup and attempt to umount it.


-- 
Cyril Hrubis
chrubis@suse.cz

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

  reply	other threads:[~2023-05-22 14:40 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-10 12:42 [LTP] [PATCH v7 0/6] Refactor mqns testing suite Andrea Cervesato
2023-05-10 12:42 ` [LTP] [PATCH v7 1/6] Refactor mqns_01 using new LTP API Andrea Cervesato
2023-05-22 14:42   ` Cyril Hrubis
2023-05-10 12:42 ` [LTP] [PATCH v7 2/6] Refactor mqns_02 " Andrea Cervesato
2023-05-22 14:42   ` Cyril Hrubis
2023-05-10 12:42 ` [LTP] [PATCH v7 3/6] Refactor mqns_03 " Andrea Cervesato
2023-05-22 14:41   ` Cyril Hrubis [this message]
2023-07-05 13:16     ` Andrea Cervesato via ltp
2023-07-10 11:19       ` Cyril Hrubis
2023-07-11 11:09         ` Petr Vorel
2023-05-10 12:42 ` [LTP] [PATCH v7 4/6] Refactor mqns_04 " Andrea Cervesato
2023-05-22 14:54   ` Cyril Hrubis
2023-05-10 12:42 ` [LTP] [PATCH v7 5/6] Remove deprecated header files from mqns suite Andrea Cervesato
2023-05-10 12:42 ` [LTP] [PATCH v7 6/6] Remove libclone dependency " Andrea Cervesato

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=ZGt_GrwbwPJChf6P@yuki \
    --to=chrubis@suse.cz \
    --cc=andrea.cervesato@suse.de \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox