[PATCH rtems-libbsd 1/2] racoon/session: Honor file descriptor maximum

Chris Johns chrisj at rtems.org
Fri Feb 26 18:04:48 UTC 2021


On 26/2/21 2:01 am, Christian Mauderer wrote:
> Dynamically allocate a big enough file descriptor set for select(). A
> better solution would be to use kqueue() instead of select().
> ---
>  .../racoon/rtems-bsd-racoon-session-data.h    |  6 +--
>  ipsec-tools/src/racoon/session.c              | 40 +++++++++++++++++++
>  2 files changed, 43 insertions(+), 3 deletions(-)
> 
> diff --git a/ipsec-tools/src/racoon/rtems-bsd-racoon-session-data.h b/ipsec-tools/src/racoon/rtems-bsd-racoon-session-data.h
> index b869a1518..196107a35 100644
> --- a/ipsec-tools/src/racoon/rtems-bsd-racoon-session-data.h
> +++ b/ipsec-tools/src/racoon/rtems-bsd-racoon-session-data.h
> @@ -2,11 +2,11 @@
>  #include <rtems/linkersets.h>
>  #include "rtems-bsd-racoon-data.h"
>  /* session.c */
> -RTEMS_LINKER_RWSET_CONTENT(bsd_prog_racoon, static fd_set active_mask);
> -RTEMS_LINKER_RWSET_CONTENT(bsd_prog_racoon, static fd_set preset_mask);
> +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_racoon, static _types_fd_set *allocated_active_mask);
> +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_racoon, static _types_fd_set *allocated_preset_mask);
>  RTEMS_LINKER_RWSET_CONTENT(bsd_prog_racoon, static int nfds);
>  RTEMS_LINKER_RWSET_CONTENT(bsd_prog_racoon, static int signals[]);
>  RTEMS_LINKER_RWSET_CONTENT(bsd_prog_racoon, static sig_atomic_t volatile volatile sigreq[]);
> -RTEMS_LINKER_RWSET_CONTENT(bsd_prog_racoon, static struct fd_monitor fd_monitors[]);
> +RTEMS_LINKER_RWSET_CONTENT(bsd_prog_racoon, static struct fd_monitor *allocated_fd_monitors);
>  RTEMS_LINKER_RWSET_CONTENT(bsd_prog_racoon, static struct fd_monitor_list fd_monitor_tree[]);
>  RTEMS_LINKER_RWSET_CONTENT(bsd_prog_racoon, static struct sched scflushsa);
> diff --git a/ipsec-tools/src/racoon/session.c b/ipsec-tools/src/racoon/session.c
> index 65124c15e..90120c761 100644
> --- a/ipsec-tools/src/racoon/session.c
> +++ b/ipsec-tools/src/racoon/session.c
> @@ -65,6 +65,10 @@
>  #include <sys/stat.h>
>  #include <paths.h>
>  #include <err.h>
> +#ifdef __rtems__
> +#include <sys/param.h>
> +#include <rtems/libio_.h>
> +#endif /* __rtems__ */
>  
>  #include <netinet/in.h>
>  #include <resolv.h>
> @@ -123,8 +127,16 @@ static void check_sigreq __P((void));
>  static void check_flushsa __P((void));
>  static int close_sockets __P((void));
>  
> +#ifndef __rtems__
>  static fd_set preset_mask, active_mask;
>  static struct fd_monitor fd_monitors[FD_SETSIZE];
> +#else /* __rtems__ */
> +static fd_set *allocated_preset_mask, *allocated_active_mask;
> +static struct fd_monitor *allocated_fd_monitors;
> +#define preset_mask (*allocated_preset_mask)
> +#define active_mask (*allocated_active_mask)
> +#define fd_monitors (allocated_fd_monitors)
> +#endif /* __rtems__ */
>  static TAILQ_HEAD(fd_monitor_list, fd_monitor) fd_monitor_tree[NUM_PRIORITIES];
>  static int nfds = 0;
>  
> @@ -134,7 +146,11 @@ static struct sched scflushsa = SCHED_INITIALIZER();
>  void
>  monitor_fd(int fd, int (*callback)(void *, int), void *ctx, int priority)
>  {
> +#ifndef __rtems__
>  	if (fd < 0 || fd >= FD_SETSIZE) {
> +#else /* __rtems__ */
> +	if (fd < 0 || fd >= rtems_libio_number_iops) {
> +#endif /* __rtems__ */
>  		plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun");
>  		exit(1);
>  	}
> @@ -158,7 +174,11 @@ monitor_fd(int fd, int (*callback)(void *, int), void *ctx, int priority)
>  void
>  unmonitor_fd(int fd)
>  {
> +#ifndef __rtems__
>  	if (fd < 0 || fd >= FD_SETSIZE) {
> +#else /* __rtems__ */
> +	if (fd < 0 || fd >= rtems_libio_number_iops) {
> +#endif /* __rtems__ */
>  		plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun");
>  		exit(1);
>  	}
> @@ -186,7 +206,22 @@ session(void)
>  	struct fd_monitor *fdm;
>  
>  	nfds = 0;
> +#ifndef __rtems__
>  	FD_ZERO(&preset_mask);
> +#else /* __rtems__ */
> +	allocated_preset_mask = calloc(sizeof(fd_set),
> +	    howmany(rtems_libio_number_iops, sizeof(fd_set) * 8));

Does `maxfiles` work here?

> +	if (allocated_preset_mask == NULL)
> +		errx(1, "failed to allocate preset_mask");
> +	allocated_active_mask = calloc(sizeof(fd_set),
> +	    howmany(rtems_libio_number_iops, sizeof(fd_set) * 8));
> +	if (allocated_active_mask == NULL)
> +		errx(1, "failed to allocate active_mask");
> +	allocated_fd_monitors = calloc(
> +	    rtems_libio_number_iops, sizeof(struct fd_monitor));
> +	if (allocated_fd_monitors == NULL)
> +		errx(1, "failed to allocate fd_monitors");

At the core of this issue is the rotating fd allocation that we have in libio. A
report from a FreeBSD machine I have is:

$ sysctl -a | grep maxfiles
kern.maxfiles: 1037243
kern.maxfilesperproc: 933516

I doubt a select process in FreeBSD needs a select array with that many bits. I
have added similar code else where but I am wondering if this is really what we
want to do. A side effect for us is the stack usage is not bounded and that is a
problem. I think our newlib based max setting is too small.

FYI I have a major set of changes to libbsd that enables FreeBSD descriptor
support and moves the libio support to specific interfaces. The changes I have
made are in tarballs in nfsv4 in my ftp area. The support includes the mapping
of libio descriptors to FB ones. The benefit of these changes is VFS and FreeBSD
file system support.

Chris


More information about the devel mailing list