public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Florian Weimer <fweimer@redhat.com>
To: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Cc: Adhemerval Zanella via Libc-alpha <libc-alpha@sourceware.org>
Subject: Re: [PATCH 1/3] Linux: Add close_range
Date: Tue, 22 Dec 2020 12:41:50 +0100	[thread overview]
Message-ID: <87blemukxt.fsf@oldenburg2.str.redhat.com> (raw)
In-Reply-To: <60578ab1-54a7-493a-9f08-d083007dfd95@linaro.org> (Adhemerval Zanella's message of "Tue, 22 Dec 2020 08:35:52 -0300")

* Adhemerval Zanella:

>> I think we generally use int for file descriptors, following POSIX.
>
> The Linux interface uses unsigned integer, meaning that negative values
> won't really trigger an invalid usage (kernel will return EINVAL if 
> second argument is larger than first one though).
>
> I would prefer for syscall wrapper to be close as possible of the kernel
> interface, otherwise it would require to add additional semantic to
> handle potential pitfall cases.
>
> On this case, if we go for 'int' as argument should we return EBADF 
> for invalid handles?

Hmm.  I think unsigned int is needed for ~0U to work, which is what you
used in the tests.  If that's what applications use today when issuing
the syscall directly, I think we need to stick to unsigned int.

>> __THROW is incompatible with close_range as a cancellation point.  I'm
>> not sure if it is useful for this function to be a cancellation point,
>> given that it's mostly used for cleanup.  It's true that close can block
>> for an indefinite time for certain descriptors, but I don't know if
>> close_range inherits that behavior.  It certainly does not apply to
>> CLOSE_RANGE_CLOEXEC.
>
> I wasn't sure about making a cancellation entrypoint, so I followed
> current close semantic.  The cancellation entrypoing would act also
> in an early mode, meaning that asynchronous cancellation is enabled
> and thread signaled the cancellation will act prior the syscall 
> execution. 
>
> In the other hand, reading the close_range code it does seen it 
> returns with side-effects due signal interrupt. So maybe not making
> a cancellation entrypoint is indeed a better option.
>
> The FreeBSD implementation does not seem to make close_range a 
> cancellation entrypoint.

Yes, let's do not act upon cancellation.

>>> diff --git a/sysdeps/unix/sysv/linux/tst-clone.h b/sysdeps/unix/sysv/linux/tst-clone.h
>>> new file mode 100644
>>> index 0000000000..2344ac5101
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/tst-clone.h
>>> @@ -0,0 +1,48 @@
>>> +/* Auxiliary wrapper to issue the clone symbol.
>> 
>> It's not clear to me what this means.
>
> Maybe:
>
>   Auxiliary functions to issue the clone syscall. ?

That's better, thanks.

>>> diff --git a/sysdeps/unix/sysv/linux/tst-close_range.c b/sysdeps/unix/sysv/linux/tst-close_range.c
>>> new file mode 100644
>>> index 0000000000..a685e7d359
>>> --- /dev/null
>>> +++ b/sysdeps/unix/sysv/linux/tst-close_range.c
>> 
>>> +static unsigned int
>>> +first_invalid_flag (void)
>>> +{
>>> +  static const unsigned int flags[] = {
>>> +    CLOSE_RANGE_UNSHARE,
>>> +  };
>>> +
>>> +  unsigned int r = 1;
>>> +  for (int i = 0; i < array_length (flags); i++)
>>> +    if ((1U << r) & flags[i])
>>> +      r++;
>>> +  return 1U << r;
>>> +}
>>> +
>>> +enum
>>> +{
>>> +  maximum_fd = 100,
>>> +  half_fd = maximum_fd / 2,
>>> +  gap_1 = maximum_fd - 8,
>>> +  gap_0 = (maximum_fd * 3) / 4
>>> +};
>>> +
>>> +static void
>>> +close_range_test_common (int *fds, unsigned int flags)
>>> +{
>>> +  /* Basic test for invalid flags, bail out if unsupported.  */
>>> +  TEST_COMPARE (close_range (fds[0], fds[half_fd], first_invalid_flag()), -1);
>> 
>> This test is not future-proof at all.  I don't think it's valuable.
>
> But the idea is exactly to raise a warning if the underlying kernel
> supports more flags than the one support by glibc.

But it causes a test failure, not a warning.  I don't think it's valid
to poke for unknown system call flags like this, so even a proper
warning would be hard.

>>> +  if (errno == ENOSYS)
>>> +    FAIL_UNSUPPORTED ("close_range not supported");
>>> +  TEST_COMPARE (errno, EINVAL);
>>> +
>>> +  /* Close half of the descriptors and check result.  */
>>> +  TEST_COMPARE (close_range (fds[0], fds[half_fd], flags), 0);
>>> +  for (int i = 0; i <= half_fd; i++)
>>> +    {
>>> +      TEST_COMPARE (fcntl (fds[i], F_GETFL), -1);
>>> +      TEST_COMPARE (errno, EBADF);
>>> +    }
>> 
>> I have some difficulty figuring out whether you expect the descriptors
>> to be in a continuous range or not.
>> 
>> I think it would make sense to create one specific layout of file
>> descriptors and test with that.
>
> I think it is a fair assumption that descriptors are a continuous range.
> I modeled this tests using the kernel one as base, which make the same
> assumptions [1]
>
> [1] tools/testing/selftests/core/close_range_test.c

The you don't need the fds array.  It's what makes this confusing.

>>> +static int
>>> +close_range_unshare_test_fn (void *arg)
>>> +{
>>> +  close_range_test_common (arg, CLOSE_RANGE_UNSHARE);
>>> +  exit (EXIT_SUCCESS);
>>> +}
>>> +
>>> +/* Check if a close_range with CLOSE_RANGE_UNSHARE issued from a subprocess
>>> +   created with CLONE_FILES does not close the parent file descriptor list.  */
>>> +static void
>>> +close_range_unshare_test (void)
>>> +{
>> 
>> I think there could also be a test without CLOSE_RANGE_UNSHARE that
>> verifies that the subprocess operators on the shared file descriptor
>> table.
>
> Do you mean issue a 	? I may add it, although it would tests
> more CLONE_FILES support than close_range.

Sorry?  I meant a test that shows that flags == 0 and flags ==
CLOSE_RANGE_UNSHARE behave differently.

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill


  reply	other threads:[~2020-12-22 11:41 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-21 21:50 Adhemerval Zanella
2020-12-21 21:50 ` [PATCH 2/3] io: Add closefrom [BZ #10353] Adhemerval Zanella
2020-12-22 10:49   ` Florian Weimer
2020-12-22 11:50     ` Adhemerval Zanella
2020-12-22 11:57       ` Florian Weimer
2020-12-22 12:41         ` Adhemerval Zanella
2020-12-22 13:17           ` Florian Weimer
2020-12-22 13:28             ` Adhemerval Zanella
2020-12-22 13:34               ` Florian Weimer
2020-12-21 21:50 ` [PATCH 3/3] posix: Add posix_spawn_file_actions_closefrom Adhemerval Zanella
2020-12-22 11:32   ` Florian Weimer
2020-12-22 11:56     ` Adhemerval Zanella
2020-12-22 12:00       ` Florian Weimer
2020-12-22 12:46         ` Adhemerval Zanella
2020-12-22  9:05 ` [PATCH 1/3] Linux: Add close_range Florian Weimer
2020-12-22 11:35   ` Adhemerval Zanella
2020-12-22 11:41     ` Florian Weimer [this message]
2020-12-22 11:47       ` Adhemerval Zanella
2020-12-23 12:33       ` Christian Brauner

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=87blemukxt.fsf@oldenburg2.str.redhat.com \
    --to=fweimer@redhat.com \
    --cc=adhemerval.zanella@linaro.org \
    --cc=libc-alpha@sourceware.org \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).