Loading...
Searching...
No Matches
Osmocom I/O interface

osmo_io is the new (2023) interface for performing asynchronous I/O. More...

## Files

file | osmo_io.h
| io(_uring) abstraction osmo fd compatibility
file | osmo_io.c

## Data Structures

struct | osmo_io_ops
| I/O operations (call-back functions) related to an osmo_io_fd. More...

## Macros

#define | LOGPIO(iofd, level, fmt, args...)
| log macro used for logging information related to the osmo_io_fd.
#define | OSMO_IO_BACKEND_ENV "LIBOSMO_IO_BACKEND"
| This environment variable can be set to manually set the backend used in osmo_io.

## Enumerations

enum | osmo_io_fd_mode { OSMO_IO_FD_MODE_READ_WRITE , OSMO_IO_FD_MODE_RECVFROM_SENDTO , OSMO_IO_FD_MODE_RECVMSG_SENDMSG }
| The mode of an osmo_io_fd determines if read/write, recvfrom/sendmsg or recvmsg/sendmsg semantics are used. More...
enum | osmo_io_backend { OSMO_IO_BACKEND_POLL , OSMO_IO_BACKEND_IO_URING }
| The back-end used by osmo_io. More...

## Functions

static const char * | osmo_io_backend_name (enum osmo_io_backend val)
| return the string name of an osmo_io_backend
static const char * | osmo_iofd_mode_name (enum osmo_io_fd_mode val)
| return the string name of an osmo_io_mode
void | osmo_iofd_init (void)
| initialize osmo_io for the current thread
struct osmo_io_fd * | osmo_iofd_setup (const void *ctx, int fd, const char *name, enum osmo_io_fd_mode mode, const struct osmo_io_ops *ioops, void *data)
| Allocate and setup a new iofd.
int | osmo_iofd_set_cmsg_size (struct osmo_io_fd *iofd, size_t cmsg_size)
| Set the size of the control message buffer allocated when submitting recvmsg.
int | osmo_iofd_register (struct osmo_io_fd *iofd, int fd)
| Register the osmo_io_fd for active I/O.
int | osmo_iofd_unregister (struct osmo_io_fd *iofd)
| Unregister the given osmo_io_fd from osmo_io.
unsigned int | osmo_iofd_txqueue_len (struct osmo_io_fd *iofd)
| Retrieve the number of messages pending in the transmit queue.
void | osmo_iofd_txqueue_clear (struct osmo_io_fd *iofd)
| Clear the transmit queue of the given osmo_io_fd.
int | osmo_iofd_close (struct osmo_io_fd *iofd)
| Close the given osmo_io_fd.
void | osmo_iofd_free (struct osmo_io_fd *iofd)
| Free the given osmo_io_fd.
void | osmo_iofd_notify_connected (struct osmo_io_fd *iofd)
| Request notification of the user if/when a client socket is connected.
int | osmo_iofd_write_msgb (struct osmo_io_fd *iofd, struct msgb *msg)
| Write a message to a file descriptor / connected socket.
int | osmo_iofd_sendto_msgb (struct osmo_io_fd *iofd, struct msgb *msg, int sendto_flags, const struct osmo_sockaddr *dest)
| Send a message through an unconnected socket.
int | osmo_iofd_sendmsg_msgb (struct osmo_io_fd *iofd, struct msgb *msg, int sendmsg_flags, const struct msghdr *msgh)
| osmo_io equivalent of the sendmsg(2) socket API call.
void | osmo_iofd_set_alloc_info (struct osmo_io_fd *iofd, unsigned int size, unsigned int headroom)
| Set the size and headroom of the msgb allocated when receiving messages.
void | osmo_iofd_set_txqueue_max_length (struct osmo_io_fd *iofd, unsigned int max_length)
| Set the maximum number of messages enqueued for sending.
void * | osmo_iofd_get_data (const struct osmo_io_fd *iofd)
| Retrieve the associated user-data from an osmo_io_fd.
void | osmo_iofd_set_data (struct osmo_io_fd *iofd, void *data)
| Set the associated user-data from an osmo_io_fd.
unsigned int | osmo_iofd_get_priv_nr (const struct osmo_io_fd *iofd)
| Retrieve the private number from an osmo_io_fd.
void | osmo_iofd_set_priv_nr (struct osmo_io_fd *iofd, unsigned int priv_nr)
| Set the private number of an osmo_io_fd.
int | osmo_iofd_get_fd (const struct osmo_io_fd *iofd)
| Retrieve the underlying file descriptor from an osmo_io_fd.
const char * | osmo_iofd_get_name (const struct osmo_io_fd *iofd)
| Retrieve the human-readable name of the given osmo_io_fd.
void | osmo_iofd_set_name (struct osmo_io_fd *iofd, const char *name)
| Set the human-readable name of the file descriptor.
int | osmo_iofd_set_ioops (struct osmo_io_fd *iofd, const struct osmo_io_ops *ioops)
| Set the osmo_io_ops calbacks for an osmo_io_fd.
void | osmo_iofd_get_ioops (struct osmo_io_fd *iofd, struct osmo_io_ops *ioops)
| Retrieve the osmo_io_ops for an iofd.
static | __attribute__ ((constructor(103)))
struct iofd_msghdr * | iofd_msghdr_alloc (struct osmo_io_fd *iofd, enum iofd_msg_action action, struct msgb *msg, size_t cmsg_size)
| Allocate the msghdr.
void | iofd_msghdr_free (struct iofd_msghdr *msghdr)
| Free the msghdr.
struct msgb * | iofd_msgb_alloc (struct osmo_io_fd *iofd)
| convenience wrapper to call msgb_alloc with parameters from osmo_io_fd
struct msgb * | iofd_msgb_pending (struct osmo_io_fd *iofd)
| return the pending msgb in iofd or NULL if there is none
struct msgb * | iofd_msgb_pending_or_alloc (struct osmo_io_fd *iofd)
| Return the pending msgb or allocate and return a new one.
int | iofd_txqueue_enqueue (struct osmo_io_fd *iofd, struct iofd_msghdr *msghdr)
| Enqueue a message to be sent.
void | iofd_txqueue_enqueue_front (struct osmo_io_fd *iofd, struct iofd_msghdr *msghdr)
| Enqueue a message at the front.
struct iofd_msghdr * | iofd_txqueue_dequeue (struct osmo_io_fd *iofd)
| Dequeue a message from the front.
static enum iofd_seg_act | iofd_handle_segmentation (struct osmo_io_fd *iofd, struct msgb *msg, struct msgb **pending_out)
| Handle segmentation of the msg.
void | iofd_handle_segmented_read (struct osmo_io_fd *iofd, struct msgb *msg, int rc)
| Restore message boundaries on read() and pass individual messages to the read callback.
void | iofd_handle_recv (struct osmo_io_fd *iofd, struct msgb *msg, int rc, struct iofd_msghdr *hdr)
| completion handler: Internal function called by osmo_io_backend after a given I/O operation has completed
void | iofd_handle_send_completion (struct osmo_io_fd *iofd, int rc, struct iofd_msghdr *msghdr)
| completion handler: Internal function called by osmo_io_backend after a given I/O operation has completed
static int | check_mode_callback_compat (enum osmo_io_fd_mode mode, const struct osmo_io_ops *ops)

## Variables

const struct value_string | osmo_io_backend_names []
const struct value_string | osmo_iofd_mode_names []
const struct value_string | osmo_io_backend_names []
const struct value_string | osmo_iofd_mode_names []
static enum osmo_io_backend | g_io_backend
struct iofd_backend_ops | osmo_iofd_ops

## Detailed Description

osmo_io is the new (2023) interface for performing asynchronous I/O.

osmo_io encapsulates asynchronous, non-blocking I/O to sockets or other file descriptors with a submission/completion model.

For writes, the API user submits write requests, and receives completion call-backs once the write completes.

For reads, the API user specifies the size (and headroom) for message buffers, and osmo_io internally allocates msgb's accordingly. Whenever data arrives at the socket/file descriptor, osmo_io reads the data into such a msgb and hands it to a read-completion call-back provided by the API user.

A given socket/file descriptor is represented by struct osmo_io_fd. osmo_io_fd are named, i.e. the API user can provide a meaningful name describing the purpose (such as protocol/interface or the name of the remote peer). This allows osmo_io to log any related [error] messages using this name as context.

When implementing some SOCK_STREAM / SOCK_SEQPACKET based client/server transports (such as those on top of TCP or SCTP), you are most likely better off using the osmo_stream_cli / osmo_stream_srv abstractions provided by libosmo-netif. They in turn can be used in an osmo_io mode, see the respective documentation.

If you use osmo_io_fd directly, the life-cycle usually will look as follows:

1. open some socket and bind and/or connect it
2. Allocate an osmo_io_fd using osmo_iofd_setup(), configuring the mode and specifying the call-backs
3. Registering it with osmo_iofd_register(), which enables reading
4. Handle inbound data via {read,recvfrom,recvmsg} call-backs; write to it using osmo_iofd_{write,sendto_sendmsg}_msg()
5. Eventually un-register it using osmo_iofd_unregister(). Afterwards, you can re-cycle the iofd by calling osmo_iofd_register() with a new file-descriptor, or free it using osmo_iofd_free().

## Macro Definition Documentation

## LOGPIO

#define LOGPIO | ( |  | iofd,
|  |  | level,
|  |  | fmt,
|  |  | args... )

Value:
LOGP(DLIO, level, "iofd(%s) " fmt, iofd->name, ## args)
LOGP
#define LOGP(ss, level, fmt, args...)
Log a new message through the Osmocom logging framework.
Definition logging.h:49
DLIO
#define DLIO
Osmocom IO sub-system.
Definition logging.h:157
level
uint8_t level
logging level
Definition gsmtap.h:6

log macro used for logging information related to the osmo_io_fd.

Parameters

  [in] | iofd | osmo_io_fd about which we're logging
  [in] | level | log-level (LOGL_DEBUG, LOGL_INFO, LOGL_NOTICE, LOGL_ERROR, LOGL_FATAL)
  [in] | fmt | printf-style format string
  [in] | args | arguments to the format string

Referenced by iofd_handle_segmentation(), iofd_poll_ofd_cb_recvmsg_sendmsg(), iofd_txqueue_enqueue(), osmo_iofd_register(), osmo_iofd_sendmsg_msgb(), osmo_iofd_sendto_msgb(), osmo_iofd_set_ioops(), and osmo_iofd_write_msgb().

## OSMO_IO_BACKEND_ENV

#define OSMO_IO_BACKEND_ENV "LIBOSMO_IO_BACKEND"

This environment variable can be set to manually set the backend used in osmo_io.

Referenced by __attribute__().

## Enumeration Type Documentation

## osmo_io_backend

enum osmo_io_backend

The back-end used by osmo_io.

There can be multiple different back-ends available on a given system; only one of it is used for all I/O performed via osmo_io in one given process.

Enumerator
OSMO_IO_BACKEND_POLL | classic back-end using poll(2) and direct read/write/recvfrom/sendto/recvmsg/sendmsg syscalls
OSMO_IO_BACKEND_IO_URING | back-end using io_uring to perform efficient I/O and reduce syscall overhead

## osmo_io_fd_mode

enum osmo_io_fd_mode

The mode of an osmo_io_fd determines if read/write, recvfrom/sendmsg or recvmsg/sendmsg semantics are used.

Enumerator
OSMO_IO_FD_MODE_READ_WRITE | use read() / write() semantics with read_cb/write_cb in osmo_io_ops
OSMO_IO_FD_MODE_RECVFROM_SENDTO | use recvfrom() / sendto() semantics with recvfrom_cb/sendto_cb in osmo_io_ops
OSMO_IO_FD_MODE_RECVMSG_SENDMSG | emulate recvmsg() / sendmsg() semantics with recvmsg_cb/sendto_cb in osmo_io_ops

## Function Documentation

## __attribute__()

__attribute__ | ( | (constructor(103)) |  | ) |

static

References g_io_backend, iofd_poll_ops, OSMO_ASSERT, OSMO_IO_BACKEND_DEFAULT, OSMO_IO_BACKEND_ENV, OSMO_IO_BACKEND_IO_URING, OSMO_IO_BACKEND_POLL, osmo_iofd_init(), and osmo_iofd_ops.

## check_mode_callback_compat()

int check_mode_callback_compat | ( | enum osmo_io_fd_mode | mode,
|  | const struct osmo_io_ops * | ops )

static

References OSMO_IO_FD_MODE_READ_WRITE, OSMO_IO_FD_MODE_RECVFROM_SENDTO, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, osmo_io_ops::read_cb, osmo_io_ops::recvfrom_cb, osmo_io_ops::recvmsg_cb, osmo_io_ops::segmentation_cb, osmo_io_ops::segmentation_cb2, osmo_io_ops::sendmsg_cb, osmo_io_ops::sendto_cb, and osmo_io_ops::write_cb.

Referenced by osmo_iofd_set_ioops(), and osmo_iofd_setup().

## iofd_handle_recv()

void iofd_handle_recv | ( | struct osmo_io_fd * | iofd,
|  | struct msgb * | msg,
|  | int | rc,
|  | struct iofd_msghdr * | hdr )

completion handler: Internal function called by osmo_io_backend after a given I/O operation has completed

Parameters

  [in] | iofd | I/O file-descriptor on which I/O has completed
  [in] | msg | message buffer containing data related to completed I/O
  [in] | rc | result code with read size or error (-errno)
  [in] | hdr | serialized msghdr containing state of completed I/O

References osmo_io_fd::ctx, osmo_io_fd::io_ops, iofd_handle_segmented_read(), osmo_io_fd::mode, osmo_io_fd::msgb_alloc, OSMO_ASSERT, OSMO_IO_FD_MODE_READ_WRITE, OSMO_IO_FD_MODE_RECVFROM_SENDTO, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, osmo_io_ops::recvfrom_cb, and osmo_io_ops::recvmsg_cb.

Referenced by iofd_poll_ofd_cb_recvmsg_sendmsg().

## iofd_handle_segmentation()

enum iofd_seg_act iofd_handle_segmentation | ( | struct osmo_io_fd * | iofd,
|  | struct msgb * | msg,
|  | struct msgb ** | pending_out )

static

Handle segmentation of the msg.

If this function returns *_HANDLE_ONE or MORE then the data in msg will contain one complete message. If there are bytes left over, *pending_out will point to a msgb with the remaining data.

References osmo_io_fd::io_ops, iofd_msgb_alloc(), IOFD_SEG_ACT_DEFER, IOFD_SEG_ACT_HANDLE_MORE, IOFD_SEG_ACT_HANDLE_ONE, LOGL_ERROR, LOGPIO, msgb_data(), msgb_free(), msgb_length(), msgb_put(), osmo_io_ops::segmentation_cb, and osmo_io_ops::segmentation_cb2.

Referenced by iofd_handle_segmented_read().

## iofd_handle_segmented_read()

void iofd_handle_segmented_read | ( | struct osmo_io_fd * | iofd,
|  | struct msgb * | msg,
|  | int | rc )

Restore message boundaries on read() and pass individual messages to the read callback.

References osmo_io_fd::io_ops, IOFD_FLAG_FD_REGISTERED, IOFD_FLAG_ISSET, iofd_handle_segmentation(), IOFD_SEG_ACT_DEFER, IOFD_SEG_ACT_HANDLE_MORE, osmo_io_fd::mode, msgb_free(), OSMO_ASSERT, OSMO_IO_FD_MODE_READ_WRITE, osmo_io_fd::pending, osmo_io_ops::read_cb, and res.

Referenced by iofd_handle_recv().

## iofd_handle_send_completion()

void iofd_handle_send_completion | ( | struct osmo_io_fd * | iofd,
|  | int | rc,
|  | struct iofd_msghdr * | msghdr )

completion handler: Internal function called by osmo_io_backend after a given I/O operation has completed

Parameters

  [in] | iofd | I/O file-descriptor on which I/O has completed
  [in] | rc | return value of the I/O operation
  [in] | msghdr | serialized msghdr containing state of completed I/O

References iofd_msghdr::action, osmo_io_fd::io_ops, IOFD_ACT_SENDMSG, IOFD_ACT_SENDTO, IOFD_ACT_WRITE, iofd_msghdr_free(), iofd_txqueue_enqueue_front(), iofd_msghdr::iov, iofd_msghdr::msg, msgb_free(), msgb_length(), msgb_pull(), iofd_msghdr::osa, OSMO_ASSERT, osmo_io_ops::sendmsg_cb, osmo_io_ops::sendto_cb, and osmo_io_ops::write_cb.

Referenced by iofd_poll_ofd_cb_recvmsg_sendmsg().

## iofd_msgb_alloc()

struct msgb * iofd_msgb_alloc | ( | struct osmo_io_fd * | iofd | ) |

convenience wrapper to call msgb_alloc with parameters from osmo_io_fd

References osmo_io_fd::headroom, osmo_io_fd::msgb_alloc, msgb_alloc_headroom_c(), OSMO_ASSERT, and osmo_io_fd::size.

Referenced by iofd_handle_segmentation(), iofd_msgb_pending_or_alloc(), and iofd_msghdr_alloc().

## iofd_msgb_pending()

struct msgb * iofd_msgb_pending | ( | struct osmo_io_fd * | iofd | ) |

return the pending msgb in iofd or NULL if there is none

References osmo_io_fd::pending.

Referenced by iofd_msgb_pending_or_alloc().

## iofd_msgb_pending_or_alloc()

struct msgb * iofd_msgb_pending_or_alloc | ( | struct osmo_io_fd * | iofd | ) |

Return the pending msgb or allocate and return a new one.

References iofd_msgb_alloc(), and iofd_msgb_pending().

Referenced by iofd_poll_ofd_cb_recvmsg_sendmsg().

## iofd_msghdr_alloc()

struct iofd_msghdr * iofd_msghdr_alloc | ( | struct osmo_io_fd * | iofd,
|  | enum iofd_msg_action | action,
|  | struct msgb * | msg,
|  | size_t | cmsg_size )

Allocate the msghdr.

Parameters

  [in] | iofd | the osmo_io file structure
  [in] | action | the action this msg(hdr) is for (read, write, ..)
  [in] | msg | the msg buffer to use. Will allocate a new one if NULL
  [in] | cmsg_size | size (in bytes) of iofd_msghdr.cmsg buffer. Can be 0 if cmsg is not used.

Returns
  the newly allocated msghdr or NULL in case of error

References iofd_msghdr::action, iofd_msghdr::iofd, and iofd_msgb_alloc().

Referenced by osmo_iofd_sendmsg_msgb(), osmo_iofd_sendto_msgb(), and osmo_iofd_write_msgb().

## iofd_msghdr_free()

void iofd_msghdr_free | ( | struct iofd_msghdr * | msghdr | ) |

Free the msghdr.

Parameters

  [in] | msghdr | the msghdr to free

Referenced by iofd_handle_send_completion(), osmo_iofd_sendmsg_msgb(), osmo_iofd_sendto_msgb(), osmo_iofd_txqueue_clear(), and osmo_iofd_write_msgb().

## iofd_txqueue_dequeue()

struct iofd_msghdr * iofd_txqueue_dequeue | ( | struct osmo_io_fd * | iofd | ) |

Dequeue a message from the front.

Parameters

  [in] | iofd | the file descriptor

Returns
  the msghdr from the front of the queue or NULL if the queue is empty

References osmo_io_fd::current_length, llist_del(), llist_entry, osmo_io_fd::msg_queue, llist_head::next, OSMO_ASSERT, osmo_iofd_ops, and osmo_io_fd::tx_queue.

Referenced by iofd_poll_ofd_cb_recvmsg_sendmsg(), and osmo_iofd_txqueue_clear().

## iofd_txqueue_enqueue()

int iofd_txqueue_enqueue | ( | struct osmo_io_fd * | iofd,
|  | struct iofd_msghdr * | msghdr )

Enqueue a message to be sent.

Enqueues the message at the back of the queue provided there is enough space.

Parameters

  [in] | iofd | the file descriptor
  [in] | msghdr | the message to enqueue

Returns
  0 if the message was enqueued succcessfully, -ENOSPC if the queue already contains the maximum number of messages

References osmo_io_fd::current_length, IOFD_FLAG_CLOSED, IOFD_FLAG_ISSET, iofd_msghdr::list, llist_add_tail(), LOGL_ERROR, LOGPIO, osmo_io_fd::max_length, osmo_io_fd::msg_queue, osmo_iofd_ops, and osmo_io_fd::tx_queue.

Referenced by osmo_iofd_sendmsg_msgb(), osmo_iofd_sendto_msgb(), and osmo_iofd_write_msgb().

## iofd_txqueue_enqueue_front()

void iofd_txqueue_enqueue_front | ( | struct osmo_io_fd * | iofd,
|  | struct iofd_msghdr * | msghdr )

Enqueue a message at the front.

Used to enqueue a msgb from a partial send again. This function will always enqueue the message, even if the maximum number of messages is reached.

Parameters

  [in] | iofd | the file descriptor
  [in] | msghdr | the message to enqueue

References osmo_io_fd::current_length, IOFD_FLAG_CLOSED, IOFD_FLAG_ISSET, iofd_msghdr::list, llist_add(), osmo_io_fd::msg_queue, osmo_iofd_ops, and osmo_io_fd::tx_queue.

Referenced by iofd_handle_send_completion().

## osmo_io_backend_name()

const char * osmo_io_backend_name | ( | enum osmo_io_backend | val | ) |

inline static

return the string name of an osmo_io_backend

References get_value_string(), and osmo_io_backend_names.

## osmo_iofd_close()

int osmo_iofd_close | ( | struct osmo_io_fd * | iofd | ) |

Close the given osmo_io_fd.

This function closes the underlying fd, unregisters it from osmo_io and clears any messages in the tx queue. The iofd itself is not freed and can be assigned a new file descriptor with osmo_iofd_register()

Parameters

  [in] | iofd | the file descriptor

Returns
  0 on success, a negative value otherwise

References osmo_io_fd::fd, iofd_msghdr::iofd, IOFD_FLAG_CLOSED, IOFD_FLAG_ISSET, IOFD_FLAG_SET, msgb_free(), osmo_iofd_ops, osmo_iofd_txqueue_clear(), osmo_iofd_unregister(), and osmo_io_fd::pending.

Referenced by osmo_iofd_free().

## osmo_iofd_free()

void osmo_iofd_free | ( | struct osmo_io_fd * | iofd | ) |

Free the given osmo_io_fd.

The iofd will be automatically closed before via osmo_iofd_close() [which in turn will unregister it and clear any pending transmit queue items]. You must not reference the iofd after calling this function. However, it is safe to call this function from any of osmo_io call-backs; in this case, actual free will be internally delayed until that call-back completes.

Parameters

  [in] | iofd | the file descriptor

References iofd_msghdr::iofd, IOFD_FLAG_IN_CALLBACK, IOFD_FLAG_ISSET, IOFD_FLAG_SET, IOFD_FLAG_TO_FREE, and osmo_iofd_close().

## osmo_iofd_get_data()

void * osmo_iofd_get_data | ( | const struct osmo_io_fd * | iofd | ) |

Retrieve the associated user-data from an osmo_io_fd.

A call to this function will return the opaque user data pointer which was specified previously via osmo_iofd_setup() or via osmo_iofd_set_data().

Parameters

  [in] | iofd | the file descriptor

Returns
  the data that was previously set with osmo_iofd_setup()

References osmo_io_fd::data, and iofd_msghdr::iofd.

## osmo_iofd_get_fd()

int osmo_iofd_get_fd | ( | const struct osmo_io_fd * | iofd | ) |

Retrieve the underlying file descriptor from an osmo_io_fd.

Parameters

  [in] | iofd | the file descriptor

Returns
  the underlying file descriptor number

References osmo_io_fd::fd, and iofd_msghdr::iofd.

## osmo_iofd_get_ioops()

void osmo_iofd_get_ioops | ( | struct osmo_io_fd * | iofd,
|  | struct osmo_io_ops * | ioops )

Retrieve the osmo_io_ops for an iofd.

Parameters

  [in] | iofd | Target iofd file descriptor
  [in] | ioops | caller-allocated osmo_io_ops structure to be filled

References osmo_io_fd::io_ops, and iofd_msghdr::iofd.

## osmo_iofd_get_name()

const char * osmo_iofd_get_name | ( | const struct osmo_io_fd * | iofd | ) |

Retrieve the human-readable name of the given osmo_io_fd.

Parameters

  [in] | iofd | the file descriptor

Returns
  the name of the iofd as given in osmo_iofd_setup()

References iofd_msghdr::iofd, and osmo_io_fd::name.

## osmo_iofd_get_priv_nr()

unsigned int osmo_iofd_get_priv_nr | ( | const struct osmo_io_fd * | iofd | ) |

Retrieve the private number from an osmo_io_fd.

Calling this function will retrieve the private user number previously set via osmo_iofd_set_priv_nr().

Parameters

  [in] | iofd | the file descriptor

Returns
  the private number that was previously set with osmo_iofd_set_priv_nr()

References iofd_msghdr::iofd, and osmo_io_fd::priv_nr.

## osmo_iofd_init()

void osmo_iofd_init | ( | void |  | ) |

initialize osmo_io for the current thread

References g_io_backend, OSMO_ASSERT, OSMO_IO_BACKEND_IO_URING, and OSMO_IO_BACKEND_POLL.

Referenced by __attribute__().

## osmo_iofd_mode_name()

const char * osmo_iofd_mode_name | ( | enum osmo_io_fd_mode | val | ) |

inline static

return the string name of an osmo_io_mode

References get_value_string(), and osmo_iofd_mode_names.

Referenced by osmo_iofd_set_ioops(), and osmo_iofd_setup().

## osmo_iofd_notify_connected()

void osmo_iofd_notify_connected | ( | struct osmo_io_fd * | iofd | ) |

Request notification of the user if/when a client socket is connected.

Calling this function will request osmo_io to notify the user (via write call-back with res=0 and msgb=NULL) once a non-blocking outbound connect() of the socket completes.

This only works for connection oriented sockets in either OSMO_IO_FD_MODE_READ_WRITE or OSMO_IO_FD_MODE_RECVMSG_SENDMSG mode.

The fact that the write call-back is called with msgb=NULL can be used to distinguish before this "connected" notification and a socket write failure.

If the server transmits data quick enough after accepting the connection, it may happen that a read call-back is triggered towards the user before this special write-callback, since both events may come together from the kernel. Hence under those scenarios where server starts the communication, it is important not to assume or require that the write-callback(res=0, msgb=NULL) will be the first one triggered.

Parameters

  [in] | iofd | the file descriptor

References iofd_msghdr::iofd, osmo_io_fd::mode, OSMO_ASSERT, OSMO_IO_FD_MODE_READ_WRITE, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, and osmo_iofd_ops.

## osmo_iofd_register()

int osmo_iofd_register | ( | struct osmo_io_fd * | iofd,
|  | int | fd )

Register the osmo_io_fd for active I/O.

Calling this function will register a previously initialized osmo_io_fd for performing I/O.

If the osmo_iofd has a read_cb/recvfrom_cb_recvmsg_cb set in its osmo_io_ops, read/receive will be automatically enabled and the respective call-back is called at any time data becomes available.

If there is to-be-transmitted data in the transmit queue, write will be automatically enabled, allowing the transmit queue to be drained as soon as the fd/socket becomes writable.

Parameters

  [in] | iofd | the iofd file descriptor
  [in] | fd | the system fd number that will be registered. If you did not yet specify the file descriptor number during osmo_fd_setup(), or if it has changed since then, you can state the [new] file descriptor number as argument. If you wish to proceed with the previously specified file descriptor number, pass -1.

Returns
  zero on success, a negative value on error

References osmo_io_fd::current_length, osmo_io_fd::fd, osmo_io_fd::io_ops, IOFD_FLAG_CLOSED, IOFD_FLAG_FD_REGISTERED, IOFD_FLAG_ISSET, IOFD_FLAG_SET, IOFD_FLAG_UNSET, LOGL_ERROR, LOGPIO, osmo_io_fd::mode, OSMO_IO_FD_MODE_READ_WRITE, OSMO_IO_FD_MODE_RECVFROM_SENDTO, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, osmo_iofd_ops, osmo_io_ops::read_cb, osmo_io_ops::recvfrom_cb, osmo_io_ops::recvmsg_cb, and osmo_io_fd::tx_queue.

## osmo_iofd_sendmsg_msgb()

int osmo_iofd_sendmsg_msgb | ( | struct osmo_io_fd * | iofd,
|  | struct msgb * | msg,
|  | int | sendmsg_flags,
|  | const struct msghdr * | msgh )

osmo_io equivalent of the sendmsg(2) socket API call.

The osmo_io_fd must be using OSMO_IO_FD_MODE_RECVMSG_SENDMSG.

Appends the message to the internal transmit queue for eventual non-blocking sendmsg on the underlying socket/file descriptor.

If the function returns success (0), it will take ownership of the msgb and internally call msgb_free() after the sendmsg request completes. In case of an error the msgb needs to be freed by the caller.

Parameters

  [in] | iofd | file descriptor to write to
  [in] | msg | message buffer to send; is used to fill msgh->iov[]
  [in] | sendmsg_flags | Flags to pass to the send call
  [in] | msgh | 'struct msghdr' for name/control/flags. iov must be empty!

Returns
  0 in case of success; a negative value in case of error

References iofd_msghdr::cmsg, iofd_msghdr::hdr, iofd_msghdr::iofd, IOFD_ACT_SENDMSG, iofd_msghdr_alloc(), iofd_msghdr_free(), iofd_txqueue_enqueue(), iofd_msghdr::iov, LOGL_ERROR, LOGPIO, osmo_io_fd::mode, iofd_msghdr::msg, msgb_data(), msgb_length(), iofd_msghdr::osa, OSMO_ASSERT, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, OSMO_UNLIKELY, osmo_sockaddr::sa, and osmo_sockaddr::u.

## osmo_iofd_sendto_msgb()

int osmo_iofd_sendto_msgb | ( | struct osmo_io_fd * | iofd,
|  | struct msgb * | msg,
|  | int | sendto_flags,
|  | const struct osmo_sockaddr * | dest )

Send a message through an unconnected socket.

The osmo_io_fd must be using OSMO_IO_FD_MODE_RECVFROM_SENDTO.

Appends the message to the internal transmit queue for eventual non-blocking sendto on the underlying socket/file descriptor.

If the function returns success (0), it will take ownership of the msgb and internally call msgb_free() after the sendto request completes. In case of an error the msgb needs to be freed by the caller.

Parameters

  [in] | iofd | file descriptor to write to
  [in] | msg | message buffer to send
  [in] | sendto_flags | Flags to pass to the send call
  [in] | dest | destination address to send the message to

Returns
  0 in case of success; a negative value in case of error

References iofd_msghdr::flags, iofd_msghdr::hdr, iofd_msghdr::iofd, IOFD_ACT_SENDTO, iofd_msghdr_alloc(), iofd_msghdr_free(), iofd_txqueue_enqueue(), iofd_msghdr::iov, LOGL_ERROR, LOGPIO, osmo_io_fd::mode, iofd_msghdr::msg, msgb_data(), msgb_length(), iofd_msghdr::osa, OSMO_ASSERT, OSMO_IO_FD_MODE_RECVFROM_SENDTO, osmo_sockaddr_size(), OSMO_UNLIKELY, osmo_sockaddr::sa, and osmo_sockaddr::u.

## osmo_iofd_set_alloc_info()

void osmo_iofd_set_alloc_info | ( | struct osmo_io_fd * | iofd,
|  | unsigned int | size,
|  | unsigned int | headroom )

Set the size and headroom of the msgb allocated when receiving messages.

Parameters

  [in] | iofd | the file descriptor
  [in] | size | the size of the msgb when receiving data
  [in] | headroom | the headroom of the msgb when receiving data

References osmo_io_fd::headroom, iofd_msghdr::iofd, osmo_io_fd::msgb_alloc, and osmo_io_fd::size.

## osmo_iofd_set_cmsg_size()

int osmo_iofd_set_cmsg_size | ( | struct osmo_io_fd * | iofd,
|  | size_t | cmsg_size )

Set the size of the control message buffer allocated when submitting recvmsg.

If your osmo_io_fd is in OSMO_IO_FD_MODE_RECVMSG_SENDMSG mode, this API function can be used to tell the osmo_io code how much memory should be allocated for the cmsg (control message) buffer when performing recvmsg().

References osmo_io_fd::cmsg_size, osmo_io_fd::mode, and OSMO_IO_FD_MODE_RECVMSG_SENDMSG.

## osmo_iofd_set_data()

void osmo_iofd_set_data | ( | struct osmo_io_fd * | iofd,
|  | void * | data )

Set the associated user-data from an osmo_io_fd.

Calling this function will set/overwrite the opaque user data pointer, which can later be retrieved using osmo_iofd_get_data().

Parameters

  [in] | iofd | the file descriptor
  [in] | data | the data to set

References osmo_io_fd::data, and iofd_msghdr::iofd.

## osmo_iofd_set_ioops()

int osmo_iofd_set_ioops | ( | struct osmo_io_fd * | iofd,
|  | const struct osmo_io_ops * | ioops )

Set the osmo_io_ops calbacks for an osmo_io_fd.

This function can be used to update/overwrite the call-back functions for the given osmo_io_fd; it replaces the currently-set call-back function pointers from a previous call to osmo_iofd_set_ioops() or the original osmo_iofd_setup().

Parameters

  [in] | iofd | Target iofd file descriptor
  [in] | ioops | osmo_io_ops structure to be copied to the osmo_io_fd.

Returns
  0 on success, negative on error

References check_mode_callback_compat(), osmo_io_fd::io_ops, iofd_msghdr::iofd, LOGL_ERROR, LOGPIO, osmo_io_fd::mode, OSMO_ASSERT, OSMO_IO_FD_MODE_READ_WRITE, OSMO_IO_FD_MODE_RECVFROM_SENDTO, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, osmo_iofd_mode_name(), osmo_iofd_ops, osmo_io_ops::read_cb, osmo_io_ops::recvfrom_cb, and osmo_io_ops::recvmsg_cb.

## osmo_iofd_set_name()

void osmo_iofd_set_name | ( | struct osmo_io_fd * | iofd,
|  | const char * | name )

Set the human-readable name of the file descriptor.

The given name will be used as context by all related logging and future calls to osmo_iofd_get_name().

Parameters

  [in] | iofd | the file descriptor
  [in] | name | the name to set on the file descriptor

References iofd_msghdr::iofd, name, osmo_io_fd::name, and osmo_talloc_replace_string().

## osmo_iofd_set_priv_nr()

void osmo_iofd_set_priv_nr | ( | struct osmo_io_fd * | iofd,
|  | unsigned int | priv_nr )

Set the private number of an osmo_io_fd.

The priv_nr passed in via this call can later be retrieved via osmo_iofd_get_priv_nr(). It provides a way how additional context can be stored in the osmo_io_fd beyond the opaque 'data' pointer.

Parameters

  [in] | iofd | the file descriptor
  [in] | priv_nr | the private number to set

References iofd_msghdr::iofd, and osmo_io_fd::priv_nr.

## osmo_iofd_set_txqueue_max_length()

void osmo_iofd_set_txqueue_max_length | ( | struct osmo_io_fd * | iofd,
|  | unsigned int | max_length )

Set the maximum number of messages enqueued for sending.

Parameters

  [in] | iofd | the file descriptor
  [in] | size | the maximum size of the transmit queue

References iofd_msghdr::iofd, osmo_io_fd::max_length, and osmo_io_fd::tx_queue.

## osmo_iofd_setup()

struct osmo_io_fd * osmo_iofd_setup | ( | const void * | ctx,
|  | int | fd,
|  | const char * | name,
|  | enum osmo_io_fd_mode | mode,
|  | const struct osmo_io_ops * | ioops,
|  | void * | data )

Allocate and setup a new iofd.

Use this to create a new osmo_io_fd, specifying the osmo_io_fd_mode and osmo_io_ops, as well as optionally the file-descriptor number and a human-readable name. This is the first function you call for any osmo_io_fd.

The created osmo_io_fd is not yet registered, and hence can not be used for any I/O until a subsequent call to osmo_iofd_register().

The created osmo_io_fd is initialized with some default settings:

- msgb allocations size: OSMO_IO_DEFAULT_MSGB_SIZE (1024)
- msgb headroom: OSMO_IO_DEFAULT_MSGB_HEADROOM (128)
- tx_queue depth: 1024

Those values may be adjusted from their defaults by using osmo_iofd_set_alloc_info() and osmo_iofd_set_txqueue_max_length() on the osmo_io_fd.

Parameters

  [in] | ctx | the parent context from which to allocate
  [in] | fd | the underlying system file descriptor. May be -1 if not known yet; must then be specified at subsequent osmo_iofd_register() time.
  [in] | name | the optional human-readable name of the iofd; may be NULL
  [in] | mode | the osmo_io_fd_mode of the iofd, whether it should use read()/write(), sendto()/recvfrom() semantics.
  [in] | ioops | structure specifying the read/write/send/recv callbacks. Will be copied to the iofd, so the caller does not have to keep it around after issuing the osmo_iofd_setup call.
  [in] | data | opaque user data pointer accessible by the ioops callbacks

Returns
  The newly allocated osmo_io_fd struct or NULL on failure

References check_mode_callback_compat(), osmo_io_fd::ctx, osmo_io_fd::data, DLIO, osmo_io_fd::fd, osmo_io_fd::headroom, INIT_LLIST_HEAD, osmo_io_fd::io_ops, IOFD_FLAG_CLOSED, IOFD_FLAG_SET, LOGL_ERROR, LOGP, osmo_io_fd::max_length, osmo_io_fd::mode, osmo_io_fd::msg_queue, osmo_io_fd::msgb_alloc, name, osmo_io_fd::name, OSMO_IO_DEFAULT_MSGB_HEADROOM, OSMO_IO_DEFAULT_MSGB_SIZE, OSMO_IO_FD_MODE_READ_WRITE, OSMO_IO_FD_MODE_RECVFROM_SENDTO, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, osmo_iofd_mode_name(), osmo_io_fd::pending, osmo_io_fd::size, and osmo_io_fd::tx_queue.

## osmo_iofd_txqueue_clear()

void osmo_iofd_txqueue_clear | ( | struct osmo_io_fd * | iofd | ) |

Clear the transmit queue of the given osmo_io_fd.

This function frees all messages currently pending in the transmit queue

Parameters

  [in] | iofd | the file descriptor

References iofd_msghdr::iofd, iofd_msghdr_free(), iofd_txqueue_dequeue(), and msgb_free().

Referenced by osmo_iofd_close().

## osmo_iofd_txqueue_len()

unsigned int osmo_iofd_txqueue_len | ( | struct osmo_io_fd * | iofd | ) |

Retrieve the number of messages pending in the transmit queue.

Parameters

  [in] | iofd | the file descriptor

References osmo_io_fd::current_length, and osmo_io_fd::tx_queue.

Referenced by iofd_poll_ofd_cb_recvmsg_sendmsg().

## osmo_iofd_unregister()

int osmo_iofd_unregister | ( | struct osmo_io_fd * | iofd | ) |

Unregister the given osmo_io_fd from osmo_io.

After an osmo_io_fd has been successfully unregistered, it can no longer perform any I/O via osmo_io. However, it can be subsequently re-registered using osmo_iofd_register().

Parameters

  [in] | iofd | the file descriptor

Returns
  zero on success, a negative value on error

References IOFD_FLAG_FD_REGISTERED, IOFD_FLAG_ISSET, IOFD_FLAG_UNSET, and osmo_iofd_ops.

Referenced by osmo_iofd_close().

## osmo_iofd_write_msgb()

int osmo_iofd_write_msgb | ( | struct osmo_io_fd * | iofd,
|  | struct msgb * | msg )

Write a message to a file descriptor / connected socket.

The osmo_io_fd must be using OSMO_IO_FD_MODE_READ_WRITE.

Appends the message to the internal transmit queue for eventual non-blocking write to the underlying socket/file descriptor.

If the function returns success (0) it will take ownership of the msgb and internally call msgb_free() after the write request completes. In case of an error, the msgb needs to be freed by the caller.

Parameters

  [in] | iofd | osmo_io_fd file descriptor to write data to
  [in] | msg | message buffer containing the data to write

Returns
  0 in case of success; a negative value in case of error

References iofd_msghdr::flags, iofd_msghdr::hdr, iofd_msghdr::iofd, IOFD_ACT_WRITE, iofd_msghdr_alloc(), iofd_msghdr_free(), iofd_txqueue_enqueue(), iofd_msghdr::iov, LOGL_ERROR, LOGPIO, osmo_io_fd::mode, iofd_msghdr::msg, msgb_data(), msgb_length(), OSMO_ASSERT, OSMO_IO_FD_MODE_READ_WRITE, and OSMO_UNLIKELY.

## Variable Documentation

## g_io_backend

enum osmo_io_backend g_io_backend

static

Referenced by __attribute__(), and osmo_iofd_init().

## osmo_io_backend_names [1/2]

const struct value_string osmo_io_backend_names[]

extern

Referenced by osmo_io_backend_name().

## osmo_io_backend_names [2/2]

const struct value_string osmo_io_backend_names[]

Initial value:
= {
{ OSMO_IO_BACKEND_POLL, "poll" },
{ OSMO_IO_BACKEND_IO_URING, "io_uring" },
{ 0, NULL }
}
OSMO_IO_BACKEND_POLL
@ OSMO_IO_BACKEND_POLL
classic back-end using poll(2) and direct read/write/recvfrom/sendto/recvmsg/sendmsg syscalls
Definition osmo_io.h:77
OSMO_IO_BACKEND_IO_URING
@ OSMO_IO_BACKEND_IO_URING
back-end using io_uring to perform efficient I/O and reduce syscall overhead
Definition osmo_io.h:79

Referenced by osmo_io_backend_name().

## osmo_iofd_mode_names [1/2]

const struct value_string osmo_iofd_mode_names[]

extern

Referenced by osmo_iofd_mode_name().

## osmo_iofd_mode_names [2/2]

const struct value_string osmo_iofd_mode_names[]

Initial value:
= {
{ OSMO_IO_FD_MODE_READ_WRITE, "read/write" },
{ OSMO_IO_FD_MODE_RECVFROM_SENDTO, "recvfrom/sendto" },
{ OSMO_IO_FD_MODE_RECVMSG_SENDMSG, "recvmsg/sendmsg" },
{ 0, NULL }
}
OSMO_IO_FD_MODE_RECVFROM_SENDTO
@ OSMO_IO_FD_MODE_RECVFROM_SENDTO
use recvfrom() / sendto() semantics with recvfrom_cb/sendto_cb in osmo_io_ops
Definition osmo_io.h:68
OSMO_IO_FD_MODE_RECVMSG_SENDMSG
@ OSMO_IO_FD_MODE_RECVMSG_SENDMSG
emulate recvmsg() / sendmsg() semantics with recvmsg_cb/sendto_cb in osmo_io_ops
Definition osmo_io.h:70
OSMO_IO_FD_MODE_READ_WRITE
@ OSMO_IO_FD_MODE_READ_WRITE
use read() / write() semantics with read_cb/write_cb in osmo_io_ops
Definition osmo_io.h:66

Referenced by osmo_iofd_mode_name().

## osmo_iofd_ops

struct iofd_backend_ops osmo_iofd_ops

Referenced by __attribute__(), iofd_txqueue_dequeue(), iofd_txqueue_enqueue(), iofd_txqueue_enqueue_front(), osmo_iofd_close(), osmo_iofd_notify_connected(), osmo_iofd_register(), osmo_iofd_set_ioops(), and osmo_iofd_unregister().