[LTP] [PATCH v1] Rewrite process_vm_readv02.c test with new LTP API

Jan Stancek jstancek@redhat.com
Tue Jan 25 13:11:42 CET 2022


On Tue, Jan 25, 2022 at 12:11 PM Andrea Cervesato
<andrea.cervesato@suse.de> wrote:

Hi,

<snip>

> -
> -static void child_alloc(void)
> +static void child_alloc(const char *data, int length)
>  {
>         char *foo;
> -       char buf[BUFSIZ];
>
> -       foo = SAFE_MALLOC(tst_exit, len + 1);
> -       strncpy(foo, tst_string, len);
> -       foo[len] = '\0';
> -       tst_resm(TINFO, "child 0: memory allocated and initialized.");
> +       foo = SAFE_MALLOC(length + 1);
> +       snprintf(foo, length + 1, "%s", data);
> +       foo[length] = '\0';

or you could use strdup/strcpy

>
> -       /* passing addr of string "foo" via pipe */
> -       SAFE_CLOSE(tst_exit, pipe_fd[0]);
> -       snprintf(buf, BUFSIZ, "%p", foo);
> -       SAFE_WRITE(tst_exit, 1, pipe_fd[1], buf, strlen(buf) + 1);
> -       SAFE_CLOSE(tst_exit, pipe_fd[1]);
> +       snprintf(shared_data, BUFSIZ, "%p", foo);

The only purpose appears to be to hold pointer value, so you could
make shared_data
hold uintptr_t and skip to/from string conversion.

> +
> +       tst_res(TINFO, "child 0: memory allocated and initialized");
>
>         /* wait until child_invoke is done reading from our VM */
> -       TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);
> +       TST_CHECKPOINT_WAIT(0);
>  }
>
> -static void child_invoke(void)
> +static void child_invoke(const char *data, int length, pid_t pid_alloc)
>  {
>         char *lp, *rp;
> -       char buf[BUFSIZ];
>         struct iovec local, remote;
>
> -       /* get addr from pipe */
> -       SAFE_CLOSE(tst_exit, pipe_fd[1]);
> -       SAFE_READ(tst_exit, 0, pipe_fd[0], buf, BUFSIZ);
> -       SAFE_CLOSE(tst_exit, pipe_fd[0]);
> -       if (sscanf(buf, "%p", &rp) != 1)
> -               tst_brkm(TBROK | TERRNO, tst_exit, "sscanf");
> +       if (sscanf(shared_data, "%p", &rp) != 1)
> +               tst_brk(TBROK, "sscanf");
>
> -       lp = SAFE_MALLOC(tst_exit, len + 1);
> +       lp = SAFE_MALLOC(length + 1);
>         local.iov_base = lp;
> -       local.iov_len = len;
> +       local.iov_len = length;
>         remote.iov_base = rp;
> -       remote.iov_len = len;
> -
> -       tst_resm(TINFO, "child 1: reading string from same memory location.");
> -       TEST(tst_syscall(__NR_process_vm_readv, pids[0],
> -                        &local, 1UL, &remote, 1UL, 0UL));
> -       if (TEST_RETURN != len)
> -               tst_brkm(TFAIL | TTERRNO, tst_exit, "process_vm_readv");
> -       if (strncmp(lp, tst_string, len) != 0)
> -               tst_brkm(TFAIL, tst_exit, "child 1: expected string: %s, "
> -                        "received string: %256s", tst_string, lp);
> +       remote.iov_len = length;
> +
> +       tst_res(TINFO, "child 1: reading string from same memory location");
> +
> +       TEST(tst_syscall(__NR_process_vm_readv, pid_alloc, &local, 1UL, &remote,
> +                                        1UL, 0UL));
> +
> +       if (TST_RET != length)
> +               tst_brk(TBROK, "process_vm_readv: %s", tst_strerrno(-TST_RET));
> +
> +       if (strncmp(lp, data, length) != 0)
> +               tst_res(TFAIL, "child 1: expected string: %s, received string: %256s",
> +                               data, lp);
>         else
> -               tst_resm(TPASS, "expected string received.");
> +               tst_res(TPASS, "expected string received");
>  }
>
>  static void setup(void)
>  {
> -       tst_require_root();
> -
>         /* Just a sanity check of the existence of syscall */
>         tst_syscall(__NR_process_vm_readv, getpid(), NULL, 0UL, NULL, 0UL, 0UL);
>
> -       tst_tmpdir();
> -       TST_CHECKPOINT_INIT(cleanup);
> -
> -       TEST_PAUSE;
> +       shared_data = SAFE_MMAP(NULL, BUFSIZ, PROT_READ | PROT_WRITE,
> +                                                       MAP_SHARED | MAP_ANONYMOUS, -1, 0);
>  }
>
>  static void cleanup(void)
>  {
> -       tst_rmdir();
> +       if (shared_data)
> +               SAFE_MUNMAP(shared_data, BUFSIZ);
>  }
> +
> +static void run(void)
> +{
> +       const char *data = "test";
> +       pid_t pid_alloc;
> +       pid_t pid_invoke;
> +       int length;
> +       int status;
> +
> +       length = strlen(data);
> +
> +       pid_alloc = SAFE_FORK();
> +       if (!pid_alloc) {
> +               child_alloc(data, length);
> +               return;
> +       }
> +
> +       pid_invoke = SAFE_FORK();
> +       if (!pid_invoke) {
> +               child_invoke(data, length, pid_alloc);

This is a bit racy, child_alloc() might not be ready at this point:

$ ./process_vm_readv02
tst_test.c:1433: TINFO: Timeout per run is 0h 05m 00s
process_vm_readv02.c:47: TBROK: sscanf
process_vm_readv02.c:110: TFAIL: child 1: returns 512
process_vm_readv02.c:35: TINFO: child 0: memory allocated and initialized



More information about the ltp mailing list