Skip to content

Commit

Permalink
posix: deprecate POSIX_MAX_FDS and add POSIX_DEVICE_IO
Browse files Browse the repository at this point in the history
The POSIX_MAX_FDS option does not correspond to any standard
POSIX option. It was used to define the size of the file
descriptor table, which is by no means exclusively used by
POSIX (also net, fs, ...).

POSIX_MAX_FDS is being deprecated in order to ensure that
Zephyr's POSIX Kconfig variables correspond to those defined in
the specification, as of IEEE 1003.1-2017. Namely,
POSIX_OPEN_MAX. CONFIG_POSIX_MAX_OPEN_FILES is being deprecated
for the same reason.

To mitigate any possible layering violations, that option is
not user selectable. It tracks the newly added
CONFIG_ZVFS_OPEN_MAX option, which is native to Zephyr.

With this deprecation, we introduce the following Kconfig
options that map directly to standard POSIX Option Groups by
simply removing "CONFIG_":

* CONFIG_POSIX_DEVICE_IO

Similarly, with this deprecation, we introduce the following
Kconfig options that map directly to standard POSIX Options by
simply removing "CONFIG":

* CONFIG_POSIX_OPEN_MAX

In order to maintain parity with the current feature set, we
introduce the following Kconfig options.

* CONFIG_POSIX_DEVICE_IO_ALIAS_CLOSE
* CONFIG_POSIX_DEVICE_IO_ALIAS_OPEN
* CONFIG_POSIX_DEVICE_IO_ALIAS_READ
* CONFIG_POSIX_DEVICE_IO_ALIAS_WRITE

Gate open(), close(), read(), and write() via the
CONFIG_POSIX_DEVICE_IO Kconfig option and move
implementations into device_io.c, to be conformant with the
spec.

Lastly, stage function names for upcoming ZVFS work, to be
completed as part of the LTSv3 Roadmap (e.g. zvfs_open(), ..).

Signed-off-by: Chris Friedt <[email protected]>
  • Loading branch information
Chris Friedt committed May 22, 2024
1 parent 51a4ef8 commit c48f5af
Show file tree
Hide file tree
Showing 55 changed files with 221 additions and 116 deletions.
2 changes: 1 addition & 1 deletion doc/connectivity/networking/net_config_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Socket Options
Maximum number of supported poll() entries. One needs to select proper value here depending
on how many BSD sockets are polled in the system.

:kconfig:option:`CONFIG_POSIX_MAX_FDS`
:kconfig:option:`CONFIG_ZVFS_OPEN_MAX`
Maximum number of open file descriptors, this includes files, sockets, special devices, etc.
One needs to select proper value here depending on how many BSD sockets are created in
the system.
Expand Down
4 changes: 2 additions & 2 deletions doc/services/portability/posix/kconfig/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ implementation of the POSIX API.
* :kconfig:option:`CONFIG_NET_SOCKETS_POLL_MAX`
* :kconfig:option:`CONFIG_POSIX_API`
* :kconfig:option:`CONFIG_POSIX_FS`
* :kconfig:option:`CONFIG_POSIX_MAX_FDS`
* :kconfig:option:`CONFIG_POSIX_MAX_OPEN_FILES`
* :kconfig:option:`CONFIG_ZVFS_OPEN_MAX`
* :kconfig:option:`CONFIG_POSIX_OPEN_MAX`
* :kconfig:option:`CONFIG_POSIX_MQUEUE`
* :kconfig:option:`CONFIG_POSIX_RTSIG_MAX`
* :kconfig:option:`CONFIG_POSIX_SIGNAL`
Expand Down
2 changes: 1 addition & 1 deletion drivers/modem/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ config MODEM_SOCKET
modem_socket_init().
Note that the modem socket uses runtime allocated file descriptors
reserved from the fdtable, for which the max count is set using the
Kconfig option POSIX_MAX_FDS. Make sure to update this value as both
Kconfig option ZVFS_OPEN_MAX. Make sure to update this value as both
the modem sockets and the POSIX_API, if used, share them.

config MODEM_SOCKET_PACKET_COUNT
Expand Down
2 changes: 1 addition & 1 deletion include/zephyr/net/socket_select.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ extern "C" {
/** @cond INTERNAL_HIDDEN */

typedef struct zsock_fd_set {
uint32_t bitset[(CONFIG_POSIX_MAX_FDS + 31) / 32];
uint32_t bitset[(CONFIG_ZVFS_OPEN_MAX + 31) / 32];
} zsock_fd_set;

/** @endcond */
Expand Down
2 changes: 1 addition & 1 deletion include/zephyr/posix/posix_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@
#define _POSIX_MQ_PRIO_MAX (32)
#define _POSIX_NAME_MAX (14)
#define _POSIX_NGROUPS_MAX (8)
#define _POSIX_OPEN_MAX CONFIG_POSIX_MAX_FDS
#define _POSIX_OPEN_MAX CONFIG_POSIX_OPEN_MAX
#define _POSIX_PATH_MAX (256)
#define _POSIX_PIPE_BUF (512)
#define _POSIX_RE_DUP_MAX (255)
Expand Down
2 changes: 1 addition & 1 deletion include/zephyr/posix/sys/sysconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ enum {
#define __z_posix_sysconf_SC_NGROUPS_MAX _POSIX_NGROUPS_MAX
#define __z_posix_sysconf_SC_MQ_OPEN_MAX MQ_OPEN_MAX
#define __z_posix_sysconf_SC_MQ_PRIO_MAX MQ_PRIO_MAX
#define __z_posix_sysconf_SC_OPEN_MAX CONFIG_POSIX_MAX_FDS
#define __z_posix_sysconf_SC_OPEN_MAX CONFIG_ZVFS_OPEN_MAX
#define __z_posix_sysconf_SC_PAGE_SIZE PAGE_SIZE
#define __z_posix_sysconf_SC_PAGESIZE PAGESIZE
#define __z_posix_sysconf_SC_THREAD_DESTRUCTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS
Expand Down
4 changes: 4 additions & 0 deletions lib/libc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ config NEWLIB_LIBC
depends on !NATIVE_APPLICATION
depends on NEWLIB_LIBC_SUPPORTED
select NEED_LIBC_MEM_PARTITION
imply POSIX_DEVICE_IO_ALIAS_CLOSE
imply POSIX_DEVICE_IO_ALIAS_OPEN
imply POSIX_DEVICE_IO_ALIAS_READ
imply POSIX_DEVICE_IO_ALIAS_WRITE
imply POSIX_FD_MGMT_ALIAS_LSEEK
help
Build with newlib library. The newlib library is expected to be
Expand Down
9 changes: 9 additions & 0 deletions lib/os/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ config FDTABLE
for any I/O object implementing POSIX I/O semantics (i.e. read/write +
aux operations).

config ZVFS_OPEN_MAX
int "Maximum number of open file descriptors"
default 16 if WIFI_NM_WPA_SUPPLICANT
default 16 if POSIX_API
default 4
help
Maximum number of open file descriptors, this includes
files, sockets, special devices, etc.

config PRINTK_SYNC
bool "Serialize printk() calls"
default y if SMP && MP_MAX_NUM_CPUS > 1 && !(EFI_CONSOLE && LOG)
Expand Down
34 changes: 15 additions & 19 deletions lib/os/fdtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ struct fd_entry {
struct k_condvar cond;
};

#ifdef CONFIG_POSIX_API
#if defined(CONFIG_POSIX_DEVICE_IO)
static const struct fd_op_vtable stdinout_fd_op_vtable;
#endif

static struct fd_entry fdtable[CONFIG_POSIX_MAX_FDS] = {
#ifdef CONFIG_POSIX_API
BUILD_ASSERT(CONFIG_ZVFS_OPEN_MAX >= 3, "CONFIG_ZVFS_OPEN_MAX >= 3 for CONFIG_POSIX_DEVICE_IO");
#endif /* defined(CONFIG_POSIX_DEVICE_IO) */

static struct fd_entry fdtable[CONFIG_ZVFS_OPEN_MAX] = {
#if defined(CONFIG_POSIX_DEVICE_IO)
/*
* Predefine entries for stdin/stdout/stderr.
*/
Expand All @@ -62,9 +64,7 @@ static struct fd_entry fdtable[CONFIG_POSIX_MAX_FDS] = {
.cond = Z_CONDVAR_INITIALIZER(fdtable[2].cond),
},
#else
{
0
},
{0},
#endif
};

Expand Down Expand Up @@ -296,9 +296,7 @@ int z_alloc_fd(void *obj, const struct fd_op_vtable *vtable)
return fd;
}

#ifdef CONFIG_POSIX_API

ssize_t read(int fd, void *buf, size_t sz)
ssize_t zvfs_read(int fd, void *buf, size_t sz)
{
ssize_t res;

Expand All @@ -314,9 +312,8 @@ ssize_t read(int fd, void *buf, size_t sz)

return res;
}
FUNC_ALIAS(read, _read, ssize_t);

ssize_t write(int fd, const void *buf, size_t sz)
ssize_t zvfs_write(int fd, const void *buf, size_t sz)
{
ssize_t res;

Expand All @@ -332,9 +329,8 @@ ssize_t write(int fd, const void *buf, size_t sz)

return res;
}
FUNC_ALIAS(write, _write, ssize_t);

int close(int fd)
int zvfs_close(int fd)
{
int res;

Expand All @@ -352,7 +348,6 @@ int close(int fd)

return res;
}
FUNC_ALIAS(close, _close, int);

#ifdef CONFIG_POSIX_FSYNC
int fsync(int fd)
Expand All @@ -372,8 +367,8 @@ off_t zvfs_lseek(int fd, off_t offset, int whence)
return -1;
}

return z_fdtable_call_ioctl(fdtable[fd].vtable, fdtable[fd].obj, ZFD_IOCTL_LSEEK,
offset, whence);
return z_fdtable_call_ioctl(fdtable[fd].vtable, fdtable[fd].obj, ZFD_IOCTL_LSEEK, offset,
whence);
}

int ioctl(int fd, unsigned long request, ...)
Expand Down Expand Up @@ -406,6 +401,7 @@ int zvfs_fcntl(int fd, int cmd, va_list args)
return res;
}

#if defined(CONFIG_POSIX_DEVICE_IO)
/*
* fd operations for stdio/stdout/stderr
*/
Expand All @@ -420,7 +416,7 @@ static ssize_t stdinout_read_vmeth(void *obj, void *buffer, size_t count)
static ssize_t stdinout_write_vmeth(void *obj, const void *buffer, size_t count)
{
#if defined(CONFIG_BOARD_NATIVE_POSIX)
return write(1, buffer, count);
return zvfs_write(1, buffer, count);
#elif defined(CONFIG_NEWLIB_LIBC) || defined(CONFIG_ARCMWDT_LIBC)
return z_impl_zephyr_write_stdout(buffer, count);
#else
Expand All @@ -441,4 +437,4 @@ static const struct fd_op_vtable stdinout_fd_op_vtable = {
.ioctl = stdinout_ioctl_vmeth,
};

#endif /* CONFIG_POSIX_API */
#endif /* defined(CONFIG_POSIX_DEVICE_IO) */
6 changes: 5 additions & 1 deletion lib/posix/options/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ add_subdirectory_ifdef(CONFIG_GETOPT getopt)
zephyr_library_sources_ifdef(CONFIG_EVENTFD eventfd.c)
zephyr_library_sources_ifdef(CONFIG_FNMATCH fnmatch.c)
zephyr_library_sources_ifdef(CONFIG_GETENTROPY getentropy.c)
zephyr_library_sources_ifdef(CONFIG_POSIX_API perror.c)
zephyr_library_sources_ifdef(CONFIG_POSIX_ASYNCHRONOUS_IO aio.c)
zephyr_library_sources_ifdef(CONFIG_POSIX_CONFSTR confstr.c)
zephyr_library_sources_ifdef(CONFIG_POSIX_DEVICE_IO
# perror should be moved to the common libc
perror.c
device_io.c
)
zephyr_library_sources_ifdef(CONFIG_POSIX_ENV env.c)
zephyr_library_sources_ifdef(CONFIG_POSIX_FD_MGMT
fd_mgmt.c
Expand Down
12 changes: 11 additions & 1 deletion lib/posix/options/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ config POSIX_API
Enable mostly-standards-compliant implementations of
various POSIX (IEEE 1003.1) APIs.

config POSIX_OPEN_MAX
int
default ZVFS_OPEN_MAX
help
The maximum number of files that a process can have open at one time. This option is not
directly user-configurable but can be adjusted via CONFIG_ZVFS_OPEN_MAX.

For more information, please see
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html

config PTHREAD_IPC
bool "POSIX pthread IPC API"
default y if POSIX_API
Expand All @@ -26,9 +36,9 @@ rsource "Kconfig.aio"
rsource "Kconfig.barrier"
rsource "Kconfig.cond"
rsource "Kconfig.confstr"
rsource "Kconfig.device_io"
rsource "Kconfig.env"
rsource "Kconfig.eventfd"
rsource "Kconfig.fdtable"
rsource "Kconfig.fd_mgmt"
rsource "Kconfig.fnmatch"
rsource "Kconfig.fs"
Expand Down
20 changes: 20 additions & 0 deletions lib/posix/options/Kconfig.deprecated
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,26 @@ config POSIX_LIMITS_RTSIG_MAX

Please use CONFIG_POSIX_RTSIG_MAX instead.

config POSIX_MAX_FDS
int "Maximum number of open file descriptors [DEPRECATED]"
default 0
help
This option is deprecated.

Please use CONFIG_POSIX_OPEN_MAX instead.

See also CONFIG_ZVFS_OPEN_MAX.

config POSIX_MAX_OPEN_FILES
int "Maximum number of open file descriptors [DEPRECATED]"
default 0
help
This option is deprecated.

Please use CONFIG_POSIX_OPEN_MAX instead.

See also CONFIG_ZVFS_OPEN_MAX.

config TIMER
bool "Timer support [DEPRECATED]"
select DEPRECATED
Expand Down
42 changes: 42 additions & 0 deletions lib/posix/options/Kconfig.device_io
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright (c) 2024 Tenstorrent AI ULC
#
# SPDX-License-Identifier: Apache-2.0

menuconfig POSIX_DEVICE_IO
bool "POSIX Device IO"
default y if POSIX_API
select FDTABLE
help
Select 'y' here and Zephyr will provide an implementation of the POSIX_DEVICE_IO Option
Group such as FD_CLR(), FD_ISSET(), FD_SET(), FD_ZERO(), close(), fdopen(), fileno(), open(),
poll(), pread(), pselect(), pwrite(), read(), select(), and write().

For more informnation, please see
https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html

if POSIX_DEVICE_IO

# These options are intended to be used for compatibility with external POSIX
# implementations such as those in Newlib or Picolibc.

config POSIX_DEVICE_IO_ALIAS_CLOSE
bool
help
Select 'y' here and Zephyr will provide an alias for close() as _close().

config POSIX_DEVICE_IO_ALIAS_OPEN
bool
help
Select 'y' here and Zephyr will provide an alias for open() as _open().

config POSIX_DEVICE_IO_ALIAS_READ
bool
help
Select 'y' here and Zephyr will provide an alias for read() as _read().

config POSIX_DEVICE_IO_ALIAS_WRITE
bool
help
Select 'y' here and Zephyr will provide an alias for write() as _write().

endif # POSIX_DEVICE_IO
16 changes: 0 additions & 16 deletions lib/posix/options/Kconfig.fdtable

This file was deleted.

7 changes: 0 additions & 7 deletions lib/posix/options/Kconfig.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,6 @@ menuconfig POSIX_FS

if POSIX_FS

config POSIX_MAX_OPEN_FILES
int "Maximum number of open file descriptors"
default 16
help
Maximum number of open files. Note that this setting
is additionally bounded by CONFIG_POSIX_MAX_FDS.

config POSIX_FSYNC
bool "Support for fsync()"
default y
Expand Down
64 changes: 64 additions & 0 deletions lib/posix/options/device_io.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2024, Tenstorrent AI ULC
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stddef.h>
#include <stdint.h>

#include <zephyr/posix/poll.h>
#include <zephyr/posix/unistd.h>
#include <zephyr/posix/sys/select.h>
#include <zephyr/posix/sys/socket.h>

/* prototypes for external, not-yet-public, functions in fdtable.c or fs.c */
int zvfs_close(int fd);
int zvfs_open(const char *name, int flags);
ssize_t zvfs_read(int fd, void *buf, size_t sz);
ssize_t zvfs_write(int fd, const void *buf, size_t sz);

int close(int fd)
{
return zvfs_close(fd);
}
#ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_CLOSE
FUNC_ALIAS(close, _close, int);
#endif /* CONFIG_POSIX_DEVICEIO_ALIAS_CLOSE */

int open(const char *name, int flags, ...)
{
/* FIXME: necessarily need to check for O_CREAT and unpack ... if set */
return zvfs_open(name, flags);
}
#ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_OPEN
FUNC_ALIAS(open, _open, int);
#endif /* CONFIG_POSIX_DEVICEIO_ALIAS_OPEN */

int poll(struct pollfd *fds, int nfds, int timeout)
{
/* TODO: create zvfs_poll() and dispatch to subsystems based on file type */
return zsock_poll(fds, nfds, timeout);
}

ssize_t read(int fd, void *buf, size_t sz)
{
return zvfs_read(fd, buf, sz);
}
#ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_READ
FUNC_ALIAS(read, _read, ssize_t);
#endif /* CONFIG_POSIX_DEVICEIO_ALIAS_READ */

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
{
/* TODO: create zvfs_select() and dispatch to subsystems based on file type */
return zsock_select(nfds, readfds, writefds, exceptfds, (struct zsock_timeval *)timeout);
}

ssize_t write(int fd, const void *buf, size_t sz)
{
return zvfs_write(fd, buf, sz);
}
#ifdef CONFIG_POSIX_DEVICE_IO_ALIAS_WRITE
FUNC_ALIAS(write, _write, ssize_t);
#endif /* CONFIG_POSIX_DEVICEIO_ALIAS_WRITE */
Loading

0 comments on commit c48f5af

Please sign in to comment.