All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Laurent Vivier <laurent@vivier.eu>
Cc: Michael Tokarev <mjt@tls.msk.ru>,
	QEMU Developers <qemu-devel@nongnu.org>
Subject: Re: [PATCH trivial 1/2] close_all_open_fd(): move to oslib-posix.c
Date: Fri, 26 Jan 2024 09:06:22 +0000	[thread overview]
Message-ID: <ZbN2DhQ4GeKc-aaX@redhat.com> (raw)
In-Reply-To: <ffc002d5-f648-43b8-b938-011a4a92cf5e@vivier.eu>

On Fri, Jan 26, 2024 at 08:44:13AM +0100, Laurent Vivier wrote:
> Le 25/01/2024 à 23:29, Michael Tokarev a écrit :
> > Initially in async-teardown.c, but the same construct is used
> > elsewhere too.
> > 
> > Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
> > ---
> >   include/sysemu/os-posix.h |  1 +
> >   system/async-teardown.c   | 37 +------------------------------------
> >   util/oslib-posix.c        | 36 ++++++++++++++++++++++++++++++++++++
> >   3 files changed, 38 insertions(+), 36 deletions(-)
> > 
> > diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
> > index dff32ae185..4c91d03f44 100644
> > --- a/include/sysemu/os-posix.h
> > +++ b/include/sysemu/os-posix.h
> > @@ -53,6 +53,7 @@ bool os_set_runas(const char *user_id);
> >   void os_set_chroot(const char *path);
> >   void os_setup_post(void);
> >   int os_mlock(void);
> > +void os_close_all_open_fd(int minfd);
> >   /**
> >    * qemu_alloc_stack:
> > diff --git a/system/async-teardown.c b/system/async-teardown.c
> > index 396963c091..41d3d94935 100644
> > --- a/system/async-teardown.c
> > +++ b/system/async-teardown.c
> > @@ -26,40 +26,6 @@
> >   static pid_t the_ppid;
> > -/*
> > - * Close all open file descriptors.
> > - */
> > -static void close_all_open_fd(void)
> > -{
> > -    struct dirent *de;
> > -    int fd, dfd;
> > -    DIR *dir;
> > -
> > -#ifdef CONFIG_CLOSE_RANGE
> > -    int r = close_range(0, ~0U, 0);
> > -    if (!r) {
> > -        /* Success, no need to try other ways. */
> > -        return;
> > -    }
> > -#endif
> > -
> > -    dir = opendir("/proc/self/fd");
> > -    if (!dir) {
> > -        /* If /proc is not mounted, there is nothing that can be done. */
> > -        return;
> > -    }
> > -    /* Avoid closing the directory. */
> > -    dfd = dirfd(dir);
> > -
> > -    for (de = readdir(dir); de; de = readdir(dir)) {
> > -        fd = atoi(de->d_name);
> > -        if (fd != dfd) {
> > -            close(fd);
> > -        }
> > -    }
> > -    closedir(dir);
> > -}
> > -
> >   static void hup_handler(int signal)
> >   {
> >       /* Check every second if this process has been reparented. */
> > @@ -85,9 +51,8 @@ static int async_teardown_fn(void *arg)
> >       /*
> >        * Close all file descriptors that might have been inherited from the
> >        * main qemu process when doing clone, needed to make libvirt happy.
> > -     * Not using close_range for increased compatibility with older kernels.
> >        */
> > -    close_all_open_fd();
> > +    os_close_all_open_fd(0);
> >       /* Set up a handler for SIGHUP and unblock SIGHUP. */
> >       sigaction(SIGHUP, &sa, NULL);
> > diff --git a/util/oslib-posix.c b/util/oslib-posix.c
> > index 7c297003b9..09d0ce4da6 100644
> > --- a/util/oslib-posix.c
> > +++ b/util/oslib-posix.c
> > @@ -27,6 +27,7 @@
> >    */
> >   #include "qemu/osdep.h"
> > +#include <dirent.h>
> >   #include <termios.h>
> >   #include <glib/gprintf.h>
> > @@ -106,6 +107,41 @@ int qemu_get_thread_id(void)
> >   #endif
> >   }
> > +/*
> > + * Close all open file descriptors starting with minfd and up.
> > + * Not using close_range for increased compatibility with older kernels.
> > + */
> > +void os_close_all_open_fd(int minfd)
> > +{
> > +    struct dirent *de;
> > +    int fd, dfd;
> > +    DIR *dir;
> > +
> > +#ifdef CONFIG_CLOSE_RANGE
> > +    int r = close_range(minfd, ~0U, 0);
> > +    if (!r) {
> > +        /* Success, no need to try other ways. */
> > +        return;
> > +    }
> > +#endif
> > +
> > +    dir = opendir("/proc/self/fd");
> > +    if (!dir) {
> > +        /* If /proc is not mounted, there is nothing that can be done. */
> > +        return;
> > +    }
> > +    /* Avoid closing the directory. */
> > +    dfd = dirfd(dir);
> > +
> > +    for (de = readdir(dir); de; de = readdir(dir)) {
> > +        fd = atoi(de->d_name);
> > +        if (fd >= minfd && fd != dfd) {
> > +            close(fd);
> > +        }
> > +    }
> > +    closedir(dir);
> > +}
> 
> I think the way using sysconf(_SC_OPEN_MAX) is more portable, simpler and
> cleaner than the one using /proc/self/fd.

A fallback that uses _SC_OPEN_MAX is good for portability, but it is
should not be considered a replacement for iterating over /proc/self/fd,
rather an additional fallback for non-Linux, or when /proc is not mounted.
It is not uncommon for _SC_OPEN_MAX to be *exceedingly* high

  $ podman run -it quay.io/centos/centos:stream9
  [root@4a440d62935c /]# ulimit -n
  524288

Iterating over 1/2 a million FDs is a serious performance penalty that
we don't want to have, so _SC_OPEN_MAX should always be the last resort.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



  reply	other threads:[~2024-01-26  9:06 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-25 22:29 [PATCH trivial 0/2] split out os_close_all_open_fd and use it in net/tap.c too Michael Tokarev
2024-01-25 22:29 ` [PATCH trivial 1/2] close_all_open_fd(): move to oslib-posix.c Michael Tokarev
2024-01-26  7:44   ` Laurent Vivier
2024-01-26  9:06     ` Daniel P. Berrangé [this message]
2024-01-26 10:45       ` Michael Tokarev
2024-01-26 11:01         ` Daniel P. Berrangé
2024-01-26 12:05           ` Michael Tokarev
2024-01-25 22:29 ` [PATCH trivial 2/2] net/tap: use os_close_all_open_fd() instead of open-coding it Michael Tokarev

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=ZbN2DhQ4GeKc-aaX@redhat.com \
    --to=berrange@redhat.com \
    --cc=laurent@vivier.eu \
    --cc=mjt@tls.msk.ru \
    --cc=qemu-devel@nongnu.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 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.