Projects
osmocom:latest
libosmocore
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 18
View file
libosmocore.spec
Changed
@@ -14,13 +14,13 @@ Name: libosmocore Requires: osmocom-latest -Version: 1.12.1 +Version: 1.13.0 Release: 0 Summary: The Open Source Mobile Communications Core Library License: GPL-2.0-only AND GPL-2.0-or-later AND LGPL-2.1-or-later AND AGPL-3.0-or-later Group: Productivity/Telephony/Utilities Url: https://osmocom.org/projects/libosmocore/wiki/Libosmocore -Source: libosmocore_1.12.1.tar.xz +Source: libosmocore_1.13.0.tar.xz Source1: rpmlintrc BuildRequires: automake >= 1.6 BuildRequires: libtool >= 2
View file
libosmocore_1.12.1.dsc -> libosmocore_1.13.0.dsc
Changed
@@ -2,7 +2,7 @@ Source: libosmocore Binary: libosmocore, libosmocodec4, libosmocodec-doc, libosmocoding0, libosmocoding-doc, libosmocore22, libosmocore-doc, libosmogb14, libosmogb-doc, libosmogsm20, libosmogsm-doc, libosmoisdn0, libosmoisdn-doc, libosmovty13, libosmovty-doc, libosmoctrl0, libosmoctrl-doc, libosmosim2, libosmosim-doc, libosmousb0, libosmousb-doc, libosmocore-dev, libosmocore-utils, libosmocore-dbg Architecture: any all -Version: 1.12.1 +Version: 1.13.0 Maintainer: Osmocom team <openbsc@lists.osmocom.org> Homepage: https://projects.osmocom.org/projects/libosmocore Standards-Version: 3.9.8 @@ -35,8 +35,8 @@ libosmovty-doc deb doc optional arch=all libosmovty13 deb libs optional arch=any Checksums-Sha1: - e4772708e274565f122ec46f94992f0859b47fea 1135416 libosmocore_1.12.1.tar.xz + 9cf278f39ab3d4dddaa6722cc00e3a8ff9a0b5e8 1142416 libosmocore_1.13.0.tar.xz Checksums-Sha256: - de04fe3ab411a20a421ff9e90cab6aecff968ff0af4446bca282f48c932eb9df 1135416 libosmocore_1.12.1.tar.xz + 011feed23ff520b4c0535e8d27286e16654686cff0a68ea652c7361f850f49eb 1142416 libosmocore_1.13.0.tar.xz Files: - 9b274591986ca5feb7bcbc1c0116575e 1135416 libosmocore_1.12.1.tar.xz + 85f5886289510538ab17cd8b5ca596c0 1142416 libosmocore_1.13.0.tar.xz
View file
libosmocore_1.12.1.tar.xz/.tarball-version -> libosmocore_1.13.0.tar.xz/.tarball-version
Changed
@@ -1 +1 @@ -1.12.1 +1.13.0
View file
libosmocore_1.12.1.tar.xz/configure.ac -> libosmocore_1.13.0.tar.xz/configure.ac
Changed
@@ -25,6 +25,18 @@ AC_PROG_INSTALL LT_INIT(pic-only disable-static) +dnl Detect emscripten compiler +case "$CC" in +*emcc*) + emscripten=yes + ;; +*) + emscripten=no + ;; +esac +AM_CONDITIONAL(HAVE_EMSCRIPTEN, test "x$emscripten" = "xyes") +AC_SUBST(HAVE_EMSCRIPTEN, $emscripten) + AC_CONFIG_MACRO_DIR(m4) dnl patching ${archive_cmds} to affect generation of file "libtool" to fix linking with clang @@ -74,7 +86,8 @@ dnl checks for header files AC_HEADER_STDC -AC_CHECK_HEADERS(execinfo.h poll.h sys/select.h sys/socket.h sys/signalfd.h sys/eventfd.h sys/timerfd.h syslog.h ctype.h netinet/tcp.h netinet/in.h) +AC_CHECK_HEADERS(arpa/inet.h execinfo.h poll.h sys/select.h sys/socket.h sys/signalfd.h sys/eventfd.h sys/timerfd.h ctype.h netinet/tcp.h netinet/in.h) +AC_CHECK_DECL(HAVE_NETINET_IN_H, AC_SUBST(HAVE_NETINET_IN_H, 1), AC_SUBST(HAVE_NETINET_IN_H, 0)) AC_CHECK_DECL(HAVE_SYS_SOCKET_H, AC_SUBST(HAVE_SYS_SOCKET_H, 1), AC_SUBST(HAVE_SYS_SOCKET_H, 0)) # for src/conv.c AC_FUNC_ALLOCA @@ -86,6 +99,13 @@ AC_CHECK_LIB(execinfo, backtrace, BACKTRACE_LIB=-lexecinfo, BACKTRACE_LIB=) AC_SUBST(BACKTRACE_LIB) +# check for struct in6_addr has s6_addr32 field +AC_CHECK_MEMBER(struct in6_addr.s6_addr32, + AC_DEFINE(HAVE_IN6_ADDR_S6_ADDR32, 1, + Define if struct in6_addr has s6_addr32 field), + , + #include <netinet/in.h>) + # check for pthread (PTHREAD_CFLAGS, PTHREAD_LIBS) AX_PTHREAD @@ -138,6 +158,18 @@ AC_CHECK_FUNCS(localtime_r) +# Check for network namespace related functions and macros +AC_CHECK_HEADERS(sched.h sys/mount.h sys/param.h) +AC_CHECK_FUNCS(setns unshare mount) + +dnl Check whether CLONE_NEWNET is available +AC_CHECK_DECL(CLONE_NEWNET, + AC_DEFINE(HAVE_CLONE_NEWNET, 1, + Define if CLONE_NEWNET is available), + , + #define _GNU_SOURCE + #include <sched.h>) + AC_DEFUN(CHECK_TM_INCLUDES_TM_GMTOFF, AC_CACHE_CHECK( whether struct tm has tm_gmtoff member, @@ -187,13 +219,81 @@ PKG_CHECK_MODULES(TALLOC, talloc >= 2.1.0) +ENABLE_URING_DEFAULT="yes" +ENABLE_PCSC_DEFAULT="yes" +ENABLE_LIBUSB_DEFAULT="yes" +ENABLE_GNUTLS_DEFAULT="yes" +ENABLE_SYSLOG_LOGGING_DEFAULT="yes" +ENABLE_SYSTEMD_LOGGING_DEFAULT="no" +ENABLE_LIBMNL_DEFAULT="yes" +ENABLE_LIBSCTP_DEFAULT="yes" +ENABLE_SCTP_TESTS_DEFAULT="yes" +ENABLE_URING_TESTS_DEFAULT="yes" +ENABLE_PLUGIN_DEFAULT="yes" +ENABLE_VTY_DEFAULT="yes" +ENABLE_PANIC_INFLOOP_DEFAULT="no" +ENABLE_OSMO_FD_CHECK_DEFAULT="no" +ENABLE_FORCE_IO_SELECT_DEFAULT="no" +ENABLE_MSGFILE_DEFAULT="yes" +ENABLE_SERIAL_DEFAULT="yes" +ENABLE_UTILITIES_DEFAULT="yes" +ENABLE_GB_DEFAULT="yes" +ENABLE_CTRL_DEFAULT="yes" +ENABLE_PSEUDOTALLOC_DEFAULT="no" +ENABLE_EMBEDDED_DEFAULT="no" +ENABLE_LIBOSMOCORE_NO_LOGGING_DEFAULT="no" +ENABLE_SANITIZE_DEFAULT="no" +ENABLE_WERROR_DEFAULT="no" +ENABLE_EXT_TESTS_DEFAULT="no" +ENABLE_SIMD_SUPPORT_DEFAULT="yes" +ENABLE_NEON_SUPPORT_DEFAULT="no" +ENABLE_SYSTEMTAP_DEFAULT="no" + +AC_ARG_ENABLE(embedded, + AS_HELP_STRING( + --enable-embedded, + Enable building for embedded use and disable unsupported features + ), + embedded=$enableval, embedded=$ENABLE_EMBEDDED_DEFAULT) +AM_CONDITIONAL(EMBEDDED, test x"$embedded" = x"yes") +AM_CONDITIONAL(ENABLE_SERCOM_STUB, test x"$embedded" = x"yes") + +if test x"$embedded" = x"yes" +then + AC_DEFINE(EMBEDDED,1,Select building for embedded use) + ENABLE_PLUGIN_DEFAULT="no" + ENABLE_MSGFILE_DEFAULT="no" + ENABLE_SERIAL_DEFAULT="no" + ENABLE_GNUTLS_DEFAULT="no" + ENABLE_VTY_DEFAULT="no" + ENABLE_CTRL_DEFAULT="no" + ENABLE_UTILITIES_DEFAULT="no" + ENABLE_GB_DEFAULT="no" + ENABLE_LIBMNL_DEFAULT="no" + ENABLE_LIBSCTP_DEFAULT="no" + ENABLE_LIBUSB_DEFAULT="no" + ENABLE_PCSC_DEFAULT="no" + ENABLE_URING_DEFAULT="no" + ENABLE_PSEUDOTALLOC_DEFAULT="yes" + ENABLE_SYSLOG_LOGGING_DEFAULT="no" + ENABLE_PANIC_INFLOOP_DEFAULT="yes" + ENABLE_GNUTLS_DEFAULT="no" +fi + +if test "x$emscripten" = "xyes" +then + ENABLE_SERIAL_DEFAULT="no" + ENABLE_GNUTLS_DEFAULT="no" + ENABLE_GB_DEFAULT="no" + ENABLE_LIBMNL_DEFAULT="no" + ENABLE_LIBSCTP_DEFAULT="no" + ENABLE_LIBUSB_DEFAULT="no" + ENABLE_PCSC_DEFAULT="no" + ENABLE_URING_DEFAULT="no" +fi + AC_ARG_ENABLE(uring, AS_HELP_STRING(--disable-uring, Build without io_uring support), - - ENABLE_URING=$enableval - , - - ENABLE_URING="yes" - ) + ENABLE_URING=$enableval, ENABLE_URING=$ENABLE_URING_DEFAULT) AS_IF(test "x$ENABLE_URING" = "xyes", PKG_CHECK_MODULES(URING, liburing >= 0.7) AC_DEFINE(HAVE_URING,1,Build with io_uring support) @@ -202,12 +302,7 @@ AC_SUBST(ENABLE_URING) AC_ARG_ENABLE(pcsc, AS_HELP_STRING(--disable-pcsc, Build without PC/SC support), - - ENABLE_PCSC=$enableval - , - - ENABLE_PCSC="yes" - ) + ENABLE_PCSC=$enableval, ENABLE_PCSC=$ENABLE_PCSC_DEFAULT) AS_IF(test "x$ENABLE_PCSC" = "xyes", PKG_CHECK_MODULES(PCSC, libpcsclite) AC_DEFINE(HAVE_PCSC,1,Build with PC/SC support) @@ -216,12 +311,7 @@ AC_SUBST(ENABLE_PCSC) AC_ARG_ENABLE(libusb, AS_HELP_STRING(--disable-libusb, Build without libusb support), - - ENABLE_LIBUSB=$enableval - , - - ENABLE_LIBUSB="yes" - ) + ENABLE_LIBUSB=$enableval, ENABLE_LIBUSB=$ENABLE_LIBUSB_DEFAULT) AS_IF(test "x$ENABLE_LIBUSB" = "xyes", PKG_CHECK_MODULES(LIBUSB, libusb-1.0) ) @@ -229,7 +319,7 @@ AC_SUBST(ENABLE_LIBUSB) AC_ARG_ENABLE(gnutls, AS_HELP_STRING(--disable-gnutls, Do not use GnuTLS fallback for missing getrandom()), - ENABLE_GNUTLS=$enableval, ENABLE_GNUTLS="yes") + ENABLE_GNUTLS=$enableval, ENABLE_GNUTLS=$ENABLE_GNUTLS_DEFAULT) AM_CONDITIONAL(ENABLE_GNUTLS, test x"$ENABLE_GNUTLS" = x"yes") AS_IF(test "x$ENABLE_GNUTLS" = "xyes", PKG_CHECK_MODULES(LIBGNUTLS, gnutls >= 2.12.0) @@ -242,12 +332,27 @@ AC_DEFINE(USE_GNUTLS, 1, Use GnuTLS as a fallback for missing getrandom()) fi +AC_ARG_ENABLE(syslog_logging, + AS_HELP_STRING( + --disable-syslog-logging, + Build without syslog logging support + ), + syslog_logging=$enableval, syslog_logging=$ENABLE_SYSLOG_LOGGING_DEFAULT) +AS_IF(test "x$syslog_logging" = "xyes", + AC_CHECK_HEADER(syslog.h, SYSLOG_H_FOUND='yes', + SYSLOG_H_FOUND='no';
View file
libosmocore_1.12.1.tar.xz/contrib/jenkins_arm.sh -> libosmocore_1.13.0.tar.xz/contrib/jenkins_arm.sh
Changed
@@ -18,9 +18,6 @@ --enable-embedded \ --disable-doxygen \ --disable-shared \ - --disable-libsctp \ - --disable-libusb \ - --disable-libmnl \ CFLAGS="-Os -ffunction-sections -fdata-sections -nostartfiles -nodefaultlibs $WERROR_FLAGS" $MAKE $PARALLEL_MAKE
View file
libosmocore_1.12.1.tar.xz/debian/changelog -> libosmocore_1.13.0.tar.xz/debian/changelog
Changed
@@ -1,14 +1,87 @@ -libosmocore (1.12.1) unstable; urgency=medium +libosmocore (1.13.0) unstable; urgency=medium Pau Espin Pedrol + * osmo-release.sh: Fix coloring output under bash + * socket: Introduce API osmo_sock_set_nonblock() + * cosmetic: io_uring: Fix typo in comment + * io_uring: RECVMSG_SENDMSG: Reset fd to blocking after osmo_fd_register() workaround + * cosmetic: logging.h: Fix whitespace + * gsmtap_util: Get rid of unused wq * gsmtap_util: Fix fds not closed in ofd_wq_mode=0 * vty: assert in optional param followed by optional-multi-choice param: Fix 2/2 + * vty/test: Validate optional-multi-choice param followed by optional-multi-choice param * gsmtap_util: Avoid sink_fd leak gsmtap_source_add_sinki() called multiple times + * logging_vty: Allow setting gsmtap log tgt as (blocking-io|nonblocking-io|wq) + * logging_vty: Set 'gsmtap log nonblocking-io' as default + * gsmtap_util: Set sink_fd RCVBUF and SNDBUF to minimum + * gsmtap_util: Set source_fd RCVBUF to minimum + * gsmtap_util: Increase source_fd's SO_SNDBUF to 4MB + * omo_io: poll: Support multiple iov on all read/write variants + * osmo_io: Validate msghdr!=NULL after allocation + * osmo_io: io_uring: Fix batch mode in multithread process + * vty: Fix extern var declared inside ifdef + * Add --disable-syslog-logging configure option + * osmo_io: Introduce API osmo_iofd_set_name_f() + * configure.ac: EMBEDDED modifies default AC_ARG_ENABLE values + * gmstap_log: optimization: Add talloc_pool for transmitted messages + * select.c: Check for ENABLE_PSEUDOTALLOC instead of EMBEDDED + * select.c: Check for ENABLE_PLUGIN instead of EMBEDDED + * contrib/jenkins_arm.sh: Remove explicit configure.sh disable args + * osmo_io: Make iofd_handle_segmented_read() static + * osmo_io: Reorder iofd_handle_segmented_read() + * osmo_io: Assert osmo_iofd_set_alloc_info() params fit in a 16bit value + * logging: Add APIs to set/get log_{target,context} fields + * gb: Avoid accessing struct log_target members directly + * Remove unused private API log_target_create_file_stream() + * osmo_io: Support rx of segments up to ~UINT16_MAX + * osmo_io: Propagate segment_cb errors to the read_cb + * osmo_io.h: Avoid including sys/socket.h + * socket.h: Include netinet/in.h instead of arpa/inet.h + * configure.ac: Add arpa/inet.h to AC_CHECK_HEADERS + * osmo_io: Add assert to validate inconditional + * socket_compat.h improvements to always have struct osmo_sockaddr available + * remove references to define EMBEDDED in public headers + * logging: Move log target file to its own file + * osmo_io: Fix misalignment of iofd->cmsg used as struct cmsghdr + * logging_file: Avoid reopening file for stderr + * logging_file: Fix log_target_file_switch_to_stream on stderr + * stats_tcp.c: Remove unneeded EMBEDDED check + * logging: Avoid infinite loop logging inside logging path + * Fix 'logging: Avoid infinite loop logging inside logging path' + * logging: Also Avoid infinite loop/deadlock in log_check_level() + * osmo_io: Introduce API osmo_iofd_get_txqueue_max_length() + * logging_file: Clean log_target_file_reopen() + * Implement log file target using osmo_io + * Use same queue length for gsmtap_log and gsmtap_file + * osmo_io: Remove outdated comment in API doc of osmo_iofd_set_io_buffers() + * osmo_io: Allow fetching maximum value allowed by osmo_iofd_set_io_buffers() + * logging_file: Request up to 8 iofd write buffers if available + * vty: Use osmo_fd_{write,read}_enable() API helper + * osmo_io: Move function declaration to internal header + * osmo_io_uring: Split global init from per-thread init + * osmo_io: Lazy-initialize during osmo_iofd_setup() + * logging: Support nonblocking-io for log target stderr & file, make it default + + Mychaela N. Falconia + * gsm/protocol/gsm_48_103.h: add definition for TW-TS-007 + * gsm/rsl: add definition for TFO transparent container IE Vadim Yanitskiy * vty: assert in optional param followed by optional-multi-choice param: Reproduce 1/2 - -- Pau Espin Pedrol <pespin@sysmocom.de> Thu, 18 Dec 2025 14:34:32 +0100 + Timur Davydov + * Detect struct in6_addr.s6_addr32 via AC_CHECK_MEMBER and use HAVE_IN6_ADDR_S6_ADDR32 instead of __linux__. + * core: always build osmo_sock_multiaddr_* helpers + * core: fix printf format casts for struct timeval fields + * vty: guard definition of _XOPEN_SOURCE + * build: keep netns API public and gate features with HAVE_* + * core: remove SCTP include from osmo_io_internal.h + * core: guard TCP stats on availability of linux/tcp.h + * core: always build tun.c and gate TUN support by headers + * core: guard Linux netlink headers by libmnl usage + * Add Emscripten build support and JS callback logging backend + + -- Pau Espin Pedrol <pespin@sysmocom.de> Thu, 19 Feb 2026 12:39:15 +0100 libosmocore (1.12.0) unstable; urgency=medium
View file
libosmocore_1.12.1.tar.xz/include/osmocom/core/Makefile.am -> libosmocore_1.13.0.tar.xz/include/osmocom/core/Makefile.am
Changed
@@ -100,7 +100,9 @@ socket_compat.h: socket_compat.h.tpl $(AM_V_GEN)$(MKDIR_P) $(dir $@) - $(AM_V_GEN)sed -e's/XX/$(HAVE_SYS_SOCKET_H)/g' $< > $@ + $(AM_V_GEN)sed -e's/__LIBOSMOCORE_HAVE_SYS_SOCKET_H XX/__LIBOSMOCORE_HAVE_SYS_SOCKET_H $(HAVE_SYS_SOCKET_H)/g' \ + -e's/__LIBOSMOCORE_HAVE_NETINET_IN_H XX/__LIBOSMOCORE_HAVE_NETINET_IN_H $(HAVE_NETINET_IN_H)/g' \ + $< > $@ version.h: version.h.tpl $(AM_V_GEN)$(MKDIR_P) $(dir $@)
View file
libosmocore_1.12.1.tar.xz/include/osmocom/core/gsmtap_util.h -> libosmocore_1.13.0.tar.xz/include/osmocom/core/gsmtap_util.h
Changed
@@ -1,6 +1,7 @@ #pragma once #include <stdint.h> +#include <stdbool.h> #include <osmocom/core/write_queue.h> #include <osmocom/core/select.h> @@ -43,8 +44,11 @@ void gsmtap_source_free(struct gsmtap_inst *gti); +int gsmtap_source_set_nonblock(struct gsmtap_inst *gti, int on); int gsmtap_source_add_sink(struct gsmtap_inst *gti); +bool gsmtap_source_using_wq(const struct gsmtap_inst *gti); + int gsmtap_sendmsg(struct gsmtap_inst *gti, struct msgb *msg); int gsmtap_sendmsg_free(struct gsmtap_inst *gti, struct msgb *msg);
View file
libosmocore_1.12.1.tar.xz/include/osmocom/core/logging.h -> libosmocore_1.13.0.tar.xz/include/osmocom/core/logging.h
Changed
@@ -225,7 +225,7 @@ /*! Log context information, passed to filter */ struct log_context { - void *ctxLOG_MAX_CTX+1; + void *ctxLOG_MAX_CTX+1 OSMO_DEPRECATED_OUTSIDE("Accessing struct log_context members directly is deprecated"); }; /*! Compatibility with older libosmocore versions */ @@ -282,6 +282,7 @@ LOG_TGT_TYPE_STRRB, /*!< osmo_strrb-backed logging */ LOG_TGT_TYPE_GSMTAP, /*!< GSMTAP network logging */ LOG_TGT_TYPE_SYSTEMD, /*!< systemd journal logging */ + LOG_TGT_TYPE_EMSCRIPTEN, /*!< Emscripten logging using JS callback */ }; /*! Whether/how to log the source filename (and line number). */ @@ -298,13 +299,15 @@ }; /*! structure representing a logging target */ +#define OSMO_DEPRECATED_OUTSIDE_LIBOSMOCORE_LOG_TARGET \ + OSMO_DEPRECATED_OUTSIDE("Accessing struct log_target members directly is deprecated") struct log_target { struct llist_head entry; /*!< linked list */ /*! Internal data for filtering */ - int filter_map; + int filter_map OSMO_DEPRECATED_OUTSIDE_LIBOSMOCORE_LOG_TARGET; /*! Internal data for filtering */ - void *filter_dataLOG_MAX_FILTERS+1; + void *filter_dataLOG_MAX_FILTERS+1 OSMO_DEPRECATED_OUTSIDE_LIBOSMOCORE_LOG_TARGET; /*! logging categories */ struct log_category *categories; @@ -366,8 +369,8 @@ * \paramin level log level of currnet message * \paramin string the string that is to be written to the log */ - void (*output) (struct log_target *target, unsigned int level, - const char *string); + void (*output)(struct log_target *target, unsigned int level, + const char *string); /*! alternative call-back function to which the logging * framework passes the unfortmatted input arguments, @@ -406,10 +409,16 @@ /* context management */ void log_reset_context(void); -int log_set_context(uint8_t ctx, void *value); +int log_set_context(uint8_t ctx_nr, void *value); +void *log_get_context(const struct log_context *ctx, uint8_t ctx_nr); /* filter on the targets */ void log_set_all_filter(struct log_target *target, int); +bool log_get_filter(const struct log_target *target, int log_filter_index); +int log_set_filter(struct log_target *target, int log_filter_index, bool enable); +void *log_get_filter_data(const struct log_target *target, int log_filter_index); +int log_set_filter_data(struct log_target *target, int log_filter_index, void *data); + int log_cache_enable(void); void log_cache_update(int mapped_subsys, uint8_t enabled, uint8_t level); void log_set_use_color(struct log_target *target, int); @@ -443,10 +452,13 @@ bool ofd_wq_mode, bool add_sink); struct log_target *log_target_create_systemd(bool raw); +struct log_target *log_target_create_emscripten(void); void log_target_systemd_set_raw(struct log_target *target, bool raw); int log_target_file_reopen(struct log_target *tgt); int log_target_file_switch_to_stream(struct log_target *tgt); int log_target_file_switch_to_wqueue(struct log_target *tgt); +int log_target_file_get_nonblock(const struct log_target *target); +int log_target_file_set_nonblock(struct log_target *target, int on); int log_targets_reopen(void); void log_add_target(struct log_target *target);
View file
libosmocore_1.12.1.tar.xz/include/osmocom/core/logging_internal.h -> libosmocore_1.13.0.tar.xz/include/osmocom/core/logging_internal.h
Changed
@@ -4,13 +4,35 @@ * @{ * \file logging_internal.h */ +#include <stdbool.h> +#include <osmocom/core/logging.h> #include <osmocom/core/utils.h> +/* maximum length of the log string of a single log event (typically line) */ +#define MAX_LOG_SIZE 4096 + +/* maximum number of log statements we queue in file/stderr target write queue */ +#define LOG_WQUEUE_LEN 156 + +struct log_thread_state { + /* Whether we are inside a code path to generate logging output: */ + bool logging_active; + /* Cache TID: */ + long int tid; +}; + extern void *tall_log_ctx; extern struct log_info *osmo_log_info; extern const struct value_string loglevel_strs; extern struct llist_head osmo_log_target_list; +extern __thread struct log_thread_state log_thread_state; void assert_loginfo(const char *src); +int log_output_buf(char *buf, int buf_len, struct log_target *target, unsigned int subsys, + unsigned int level, const char *file, int line, int cont, + const char *format, va_list ap); + +void log_target_file_destroy(struct log_target *target); + /*! @} */
View file
libosmocore_1.12.1.tar.xz/include/osmocom/core/netdev.h -> libosmocore_1.13.0.tar.xz/include/osmocom/core/netdev.h
Changed
@@ -2,7 +2,6 @@ * network device (interface) convenience functions. */ #pragma once -#if (!EMBEDDED) #include <stddef.h> #include <stdint.h> @@ -47,5 +46,4 @@ uint8_t dst_prefixlen, const struct osmo_sockaddr *gw_addr); int osmo_netdev_ifupdown(struct osmo_netdev *netdev, bool ifupdown); -#endif /* (!EMBEDDED) */ /*! @} */
View file
libosmocore_1.12.1.tar.xz/include/osmocom/core/netns.h -> libosmocore_1.13.0.tar.xz/include/osmocom/core/netns.h
Changed
@@ -2,9 +2,6 @@ * Network namespace convenience functions. */ #pragma once -#if (!EMBEDDED) - -#if defined(__linux__) #include <signal.h> @@ -17,8 +14,4 @@ int osmo_netns_switch_enter(int nsfd, struct osmo_netns_switch_state *state); int osmo_netns_switch_exit(struct osmo_netns_switch_state *state); - -#endif /* defined(__linux__) */ - -#endif /* (!EMBEDDED) */ /*! @} */
View file
libosmocore_1.12.1.tar.xz/include/osmocom/core/osmo_io.h -> libosmocore_1.13.0.tar.xz/include/osmocom/core/osmo_io.h
Changed
@@ -4,14 +4,16 @@ #pragma once -#include <sys/socket.h> - #include <osmocom/core/linuxlist.h> #include <osmocom/core/logging.h> #include <osmocom/core/msgb.h> #include <osmocom/core/socket.h> #include <osmocom/core/utils.h> +/* struct msghdr is defined in sys/socket.h but that header may not be available. + * We only really need a forward declaration here: */ +struct msghdr; + /*! \defgroup osmo_io Osmocom I/O interface * @{ * @@ -231,6 +233,7 @@ void osmo_iofd_set_alloc_info(struct osmo_io_fd *iofd, unsigned int size, unsigned int headroom); void osmo_iofd_set_txqueue_max_length(struct osmo_io_fd *iofd, unsigned int size); +unsigned int osmo_iofd_get_txqueue_max_length(const struct osmo_io_fd *iofd); void *osmo_iofd_get_data(const struct osmo_io_fd *iofd); void osmo_iofd_set_data(struct osmo_io_fd *iofd, void *data); @@ -240,6 +243,7 @@ int osmo_iofd_get_fd(const struct osmo_io_fd *iofd); const char *osmo_iofd_get_name(const struct osmo_io_fd *iofd); void osmo_iofd_set_name(struct osmo_io_fd *iofd, const char *name); +void osmo_iofd_set_name_f(struct osmo_io_fd *iofd, const char *fmt, ...); int osmo_iofd_set_ioops(struct osmo_io_fd *iofd, const struct osmo_io_ops *ioops); void osmo_iofd_get_ioops(struct osmo_io_fd *iofd, struct osmo_io_ops *ioops);
View file
libosmocore_1.12.1.tar.xz/include/osmocom/core/socket.h -> libosmocore_1.13.0.tar.xz/include/osmocom/core/socket.h
Changed
@@ -2,7 +2,6 @@ * Osmocom socket convenience functions. */ #pragma once -#if (!EMBEDDED) /*! \defgroup socket Socket convenience functions * @{ @@ -12,9 +11,8 @@ #include <stdbool.h> #include <stddef.h> -#include <arpa/inet.h> - #include <osmocom/core/defs.h> +#include <osmocom/core/socket_compat.h> /*! maximum number of local or remote addresses supported by an osmo_sock instance */ #define OSMO_SOCK_MAX_ADDRS 32 @@ -29,9 +27,6 @@ /*! maximum length of a multia-address socket name ("r=(::2|1.2.3.4):123<->l=(5.6.7.8|::9):987") */ #define OSMO_SOCK_MULTIADDR_NAME_MAXLEN (OSMO_SOCK_MULTIADDR_PEER_STR_MAXLEN + 7) - -struct sockaddr_in; -struct sockaddr; struct osmo_fd; struct sctp_paddrinfo; @@ -59,7 +54,7 @@ { if (!addr) return 0; - +#if __LIBOSMOCORE_HAVE_SYS_SOCKET_H switch (addr->u.sa.sa_family) { case AF_INET: return sizeof(struct sockaddr_in); @@ -68,6 +63,9 @@ default: return sizeof(struct osmo_sockaddr); } +#else + return 0; +#endif /* if __LIBOSMOCORE_HAVE_SYS_SOCKET_H */ } unsigned int osmo_sockaddr_to_str_and_uint(char *addr, unsigned int addr_len, uint16_t *port, @@ -219,8 +217,9 @@ int osmo_sock_set_dscp(int fd, uint8_t dscp); int osmo_sock_set_priority(int fd, int prio); +int osmo_sock_get_nonblock(int fd); +int osmo_sock_set_nonblock(int fd, int on); int osmo_sock_sctp_get_peer_addr_info(int fd, struct sctp_paddrinfo *pinfo, size_t *pinfo_cnt); -#endif /* (!EMBEDDED) */ /*! @} */
View file
libosmocore_1.12.1.tar.xz/include/osmocom/core/socket_compat.h.tpl -> libosmocore_1.13.0.tar.xz/include/osmocom/core/socket_compat.h.tpl
Changed
@@ -1,10 +1,68 @@ -#define HAVE_STRUCT_SOCKADDR_STORAGE XX +#define __LIBOSMOCORE_HAVE_SYS_SOCKET_H XX +#define __LIBOSMOCORE_HAVE_NETINET_IN_H XX -#if HAVE_STRUCT_SOCKADDR_STORAGE +#if __LIBOSMOCORE_HAVE_SYS_SOCKET_H #include <sys/socket.h> #else +/* Minimal netinet/in.h as per POSIX https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html */ +#include <stdint.h> +typedef uint32_t socklen_t; +typedef unsigned short sa_family_t; + +struct sockaddr { + sa_family_t sa_family; + char sa_data14; +}; + struct sockaddr_storage { - unsigned short ss_family; - char __data128 - sizeof(unsigned short); + sa_family_t ss_family; + char __data128 - sizeof(sa_family_t); +}; +#endif /* if __LIBOSMOCORE_HAVE_SYS_SOCKET_H */ + +#if __LIBOSMOCORE_HAVE_NETINET_IN_H + #include <netinet/in.h> +#else +/* Minimal netinet/in.h as per POSIX https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html */ +#include <stdint.h> + +typedef uint32_t in_addr_t; +struct in_addr { + in_addr_t s_addr; +}; + +typedef uint16_t in_port_t; + +struct in6_addr { + union { + uint8_t __u6_addr816; + uint16_t __u6_addr168; + uint32_t __u6_addr324; + } __in6_u; + #define s6_addr __in6_u.__u6_addr8 + #define s6_addr16 __in6_u.__u6_addr16 + #define s6_addr32 __in6_u.__u6_addr32 +}; + +#define INET_ADDRSTRLEN 16 +#define INET6_ADDRSTRLEN 46 + +struct sockaddr_in { + sa_family_t sin_family; + in_port_t sin_port; + struct in_addr sin_addr; + unsigned char sin_zerosizeof (struct sockaddr) + - sizeof (sa_family_t) + - sizeof (in_port_t) + - sizeof (struct in_addr); +}; + +struct sockaddr_in6 { + sa_family_t sin6_family; + in_port_t sin6_port; + uint32_t sin6_flowinfo; + struct in6_addr sin6_addr; + uint32_t sin6_scope_id; }; -#endif + +#endif /* if __LIBOSMOCORE_HAVE_NETINET_IN_H */
View file
libosmocore_1.12.1.tar.xz/include/osmocom/core/tun.h -> libosmocore_1.13.0.tar.xz/include/osmocom/core/tun.h
Changed
@@ -2,7 +2,6 @@ * tunnel network device convenience functions. */ #pragma once -#if (!EMBEDDED) #include <stddef.h> #include <stdint.h> @@ -40,6 +39,4 @@ struct osmo_netdev *osmo_tundev_get_netdev(struct osmo_tundev *tundev); int osmo_tundev_send(struct osmo_tundev *tundev, struct msgb *msg); - -#endif /* (!EMBEDDED) */ /*! @} */
View file
libosmocore_1.12.1.tar.xz/include/osmocom/gsm/gsup.h -> libosmocore_1.13.0.tar.xz/include/osmocom/gsm/gsup.h
Changed
@@ -37,7 +37,6 @@ * */ #pragma once -#if (!EMBEDDED) #include <stdint.h> #include <osmocom/core/msgb.h> @@ -421,6 +420,4 @@ int osmo_gsup_encode(struct msgb *msg, const struct osmo_gsup_message *gsup_msg); int osmo_gsup_get_err_msg_type(enum osmo_gsup_message_type type_in) OSMO_DEPRECATED("Use OSMO_GSUP_TO_MSGT_ERROR() instead"); - -#endif /* (!EMBEDDED) */ /*! @} */
View file
libosmocore_1.12.1.tar.xz/include/osmocom/gsm/protocol/gsm_08_58.h -> libosmocore_1.13.0.tar.xz/include/osmocom/gsm/protocol/gsm_08_58.h
Changed
@@ -358,6 +358,7 @@ RSL_IE_RTD, RSL_IE_TFO_STATUS, RSL_IE_LLP_APDU, + RSL_IE_TFO_XPAR_CONT, /* Siemens vendor-specific */ RSL_IE_SIEMENS_MRPCI = 0x40, RSL_IE_SIEMENS_PREF_AREA_TYPE = 0x43,
View file
libosmocore_1.12.1.tar.xz/include/osmocom/gsm/protocol/gsm_48_103.h -> libosmocore_1.13.0.tar.xz/include/osmocom/gsm/protocol/gsm_48_103.h
Changed
@@ -19,3 +19,6 @@ /* circuit-switched data */ #define OSMO_AOIP_RTP_PT_CSD 120 /* without redundancy */ #define OSMO_AOIP_RTP_PT_CSD_RED 121 /* with redundancy */ + +/* Osmocom and Themyscira extensions */ +#define OSMO_AOIP_RTP_PT_TWTS007 127 /* compressed form of CSD */
View file
libosmocore_1.12.1.tar.xz/osmo-release.sh -> libosmocore_1.13.0.tar.xz/osmo-release.sh
Changed
@@ -36,15 +36,15 @@ YELLOW="\0331;33m" ok() { - echo "${GREEN}OK:${RESET} $@" + printf "${GREEN}OK:${RESET} %s\n" "$1" } warn() { - echo "${YELLOW}WARN:${RESET} $@" + printf "${YELLOW}WARN:${RESET} %s\n" "$1" } error() { - echo "${RED}ERROR:${RESET} $@" + printf "${RED}ERROR:${RESET} %s\n" "$1" } libversion_to_lib_major() {
View file
libosmocore_1.12.1.tar.xz/src/core/Makefile.am -> libosmocore_1.13.0.tar.xz/src/core/Makefile.am
Changed
@@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=24:1:2 +LIBVERSION=25:0:3 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) AM_CFLAGS = -Wall $(TALLOC_CFLAGS) $(PTHREAD_CFLAGS) $(LIBSCTP_CFLAGS) $(LIBMNL_CFLAGS) $(URING_CFLAGS) @@ -44,7 +44,7 @@ isdnhdlc.c \ it_q.c \ logging.c \ - logging_syslog.c \ + logging_file.c \ logging_gsmtap.c \ loggingrb.c \ macaddr.c \ @@ -82,6 +82,10 @@ probes.d \ $(NULL) +if HAVE_EMSCRIPTEN +libosmocore_la_SOURCES += logging_emscripten.c +endif + if HAVE_SSSE3 libosmocore_la_SOURCES += conv_acc_sse.c if HAVE_SSE4_1 @@ -137,6 +141,10 @@ libosmocore_la_SOURCES += serial.c endif +if ENABLE_SYSLOG_LOGGING +libosmocore_la_SOURCES += logging_syslog.c +endif + if ENABLE_SYSTEMD_LOGGING libosmocore_la_SOURCES += logging_systemd.c libosmocore_la_LIBADD += $(SYSTEMD_LIBS)
View file
libosmocore_1.12.1.tar.xz/src/core/fsm.c -> libosmocore_1.13.0.tar.xz/src/core/fsm.c
Changed
@@ -660,7 +660,7 @@ else snprintf(trailer, sizeof(trailer), "(keeping " OSMO_T_FMT ", %ld.%03lds remaining)", OSMO_T_FMT_ARGS(fi->T), - (long) remaining.tv_sec, remaining.tv_usec / 1000); + (long) remaining.tv_sec, (long) (remaining.tv_usec / 1000)); } else if (timeout_ms) { if (timeout_ms % 1000 == 0) /* keep log output legacy compatible to avoid autotest failures */
View file
libosmocore_1.12.1.tar.xz/src/core/gsmtap_util.c -> libosmocore_1.13.0.tar.xz/src/core/gsmtap_util.c
Changed
@@ -47,28 +47,14 @@ * * \file gsmtap_util.c */ -/*! one gsmtap instance - * Until gsmtap_inst_fd() is removed from the API at some point in the future, we have to keep the first member as - * 'int' and the second as 'struct osmo_wqueue' (this effectively makes sure that the struct member wq.bfd.fd maintains - * the same memory offset from the start of the struct) to ensure that inlined static 'instances' of gsmtap_inst_fd() in - * old binaries keep working the way they used to even with gsmtap_inst objects obtained from newer versions of libosmocore */ +/*! one gsmtap instance */ struct gsmtap_inst { - int osmo_io_mode; /*!< Indicates whether or not to use Osmo IO mode for message output (thus enabling use of tx queues). - * This field member may not be changed or moved (backwards compatibility) */ - struct osmo_wqueue wq; /*!< the wait queue. This field member may not be changed or moved (backwards compatibility) */ - - struct osmo_io_fd *out; /*!< Used when osmo_io_mode is nonzero */ + int osmo_io_mode; /*!< Indicates whether or not to use Osmo IO mode for message output (thus enabling use of tx queues) */ + int source_fd; /*!< the gsmtap source FD */ + struct osmo_io_fd *out; /*!< Used when osmo_io_mode is nonzero */ int sink_fd; }; -struct _gsmtap_inst_legacy { - int ofd_wq_mode; - struct osmo_wqueue wq; - struct osmo_fd sink_ofd; -}; -osmo_static_assert(offsetof(struct gsmtap_inst, wq) == offsetof(struct _gsmtap_inst_legacy, wq), - gsmtap_inst_new_wq_offset_equals_legacy_wq_offset); - /*! Deprecated, use gsmtap_inst_fd2() instead * \paramin gti GSMTAP instance * \returns file descriptor of GSMTAP instance */ @@ -82,7 +68,7 @@ * \returns file descriptor of GSMTAP instance */ int gsmtap_inst_fd2(const struct gsmtap_inst *gti) { - return gti->wq.bfd.fd; + return gti->source_fd; } /*! convert RSL channel number to GSMTAP channel type @@ -339,12 +325,18 @@ return rc; if (osmo_sockaddr_is_local((struct sockaddr *)&ss, ss_len) == 1) { - rc = osmo_sock_init_sa((struct sockaddr *)&ss, SOCK_DGRAM, + int zero = 0; + int fd = osmo_sock_init_sa((struct sockaddr *)&ss, SOCK_DGRAM, IPPROTO_UDP, OSMO_SOCK_F_BIND | OSMO_SOCK_F_UDP_REUSEADDR); - if (rc >= 0) - return rc; + if (fd < 0) + return fd; + /* We never read nor write from this socket, so tell the kernel + * to set the RCVBUF/SNDBUF to the minimum possible value */ + setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &zero, sizeof(zero)); + setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &zero, sizeof(zero)); + return fd; } return -ENODEV; @@ -433,6 +425,20 @@ signal_dbm, snr, data, len); } +/*! Set the gsmtap source socket as non-blocking (see sockopt O_NONBLOCK). + * \paramin gti existing GSMTAP source + * \paramin on set to 1 to set as non-blocking, 0 to set as blocking. + * \returns 0 on success; negative on error + * + * This setting is ignored when \ref gti was initialied in ofd_wq_mode=1 mode. + */ +int gsmtap_source_set_nonblock(struct gsmtap_inst *gti, int on) +{ + if (gti->osmo_io_mode) + return 0; + return osmo_sock_set_nonblock(gti->source_fd, on); +} + /*! Add a local sink to an existing GSMTAP source and return fd * \paramin gti existing GSMTAP source * \returns file descriptor of locally bound receive socket; negative on error @@ -461,6 +467,15 @@ return rc; } +/*! Was GSMTAP source configured to use a workqueue (ofd_wq_mode=1)? + * \paramin gti existing GSMTAP source + * \returns Whether GSMTAP source was configured to use a workqueue (ofd_wq_mode=1) + */ +bool gsmtap_source_using_wq(const struct gsmtap_inst *gti) +{ + return gti->osmo_io_mode; +} + /* Registered in Osmo IO as a no-op to set the write callback. */ static void gsmtap_ops_noop_cb(struct osmo_io_fd *iofd, int res, struct msgb *msg) { @@ -486,6 +501,7 @@ { struct gsmtap_inst *gti; int fd; + int buflen; fd = gsmtap_source_init_fd2(local_host, local_port, rem_host, rem_port); if (fd < 0) @@ -493,21 +509,35 @@ gti = talloc_zero(NULL, struct gsmtap_inst); gti->osmo_io_mode = ofd_wq_mode; - /* Still using the wq member for its 'fd' field only, since we are keeping it for now, anyways */ - gti->wq.bfd.fd = fd; + gti->source_fd = fd; gti->sink_fd = -1; if (ofd_wq_mode) { - gti->out = osmo_iofd_setup(gti, gti->wq.bfd.fd, "gsmtap_inst.io_fd", OSMO_IO_FD_MODE_READ_WRITE, &gsmtap_ops, NULL); + gti->out = osmo_iofd_setup(gti, gti->source_fd, "gsmtap_inst.io_fd", OSMO_IO_FD_MODE_READ_WRITE, &gsmtap_ops, NULL); if (gti->out == NULL) goto err_cleanup; - if (osmo_iofd_register(gti->out, gti->wq.bfd.fd) < 0) + if (osmo_iofd_register(gti->out, gti->source_fd) < 0) goto err_cleanup; /* Use a big enough tx queue to avoid gsmtap messages being dropped: */ osmo_iofd_set_txqueue_max_length(gti->out, 1024); } + /* We never read from this socket, so tell the kernel + * to set the RCVBUF to the minimum possible value */ + buflen = 0; + setsockopt(gti->source_fd, SOL_SOCKET, SO_RCVBUF, &buflen, sizeof(buflen)); + + /* The wmem_default of 212992B is too low for heavy bursty gsmtap transmission (eg. tons of DEBUG logging). + * A full UDP socket send buffer can cause blocks (or drops if sk is later configured non-blocking), + * so let's try to increase it to a safer value of 4MB (newer default net.core.wmem_max in linux kernel since + * 2025 a6d4f25888b83b8300aef28d9ee22765c1cc9b34). + * The kernel will trim the size set to the configured net.core.wmem_max if lower. + * In case you wonder, YES! blocking of 2-4s was seen in osmo-bts gsmtap_log's send() during ttcn3-bts-test execution. + */ + buflen = 4194304; /* 4 << 20 */ + setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buflen, sizeof(buflen)); + return gti; err_cleanup: @@ -540,7 +570,7 @@ if (gti->osmo_io_mode) osmo_iofd_free(gti->out); else - close(gti->wq.bfd.fd); + close(gti->source_fd); if (gti->sink_fd >= 0) {
View file
libosmocore_1.12.1.tar.xz/src/core/libosmocore.map -> libosmocore_1.13.0.tar.xz/src/core/libosmocore.map
Changed
@@ -54,6 +54,8 @@ gsmtap_source_init2; gsmtap_source_init_fd; gsmtap_source_init_fd2; +gsmtap_source_set_nonblock; +gsmtap_source_using_wq; gsmtap_type_names; log_add_target; log_category_name; @@ -73,8 +75,13 @@ log_parse_level; logp_stub; log_reset_context; +log_get_context; +log_get_filter; +log_get_filter_data; log_set_all_filter; log_set_category_filter; +log_set_filter; +log_set_filter_data; log_set_context; log_set_log_level; log_set_print_category; @@ -89,14 +96,16 @@ log_set_use_color; log_target_create; log_target_create_file; -log_target_create_file_stream; log_target_create_gsmtap; log_target_create_rb; log_target_create_stderr; log_target_create_syslog; log_target_create_systemd; +log_target_create_emscripten; log_target_destroy; +log_target_file_get_nonblock; log_target_file_reopen; +log_target_file_set_nonblock; log_target_file_switch_to_stream; log_target_file_switch_to_wqueue; log_target_find; @@ -265,7 +274,9 @@ osmo_iofd_get_fd; osmo_iofd_get_name; osmo_iofd_set_name; +osmo_iofd_set_name_f; osmo_iofd_get_priv_nr; +osmo_iofd_get_txqueue_max_length; osmo_iofd_init; osmo_iofd_mode_names; osmo_iofd_ops; @@ -453,7 +464,9 @@ osmo_sock_multiaddr_get_ip_and_port; osmo_sock_multiaddr_get_name_buf; osmo_sock_sctp_get_peer_addr_info; +osmo_sock_get_nonblock; osmo_sock_set_dscp; +osmo_sock_set_nonblock; osmo_sock_set_priority; osmo_sock_unix_init; osmo_sock_unix_init_ofd;
View file
libosmocore_1.12.1.tar.xz/src/core/logging.c -> libosmocore_1.13.0.tar.xz/src/core/logging.c
Changed
@@ -37,7 +37,7 @@ #include <strings.h> #endif -#ifdef HAVE_SYSLOG_H +#ifdef ENABLE_SYSLOG_LOGGING #include <syslog.h> #endif @@ -62,7 +62,7 @@ #include <osmocom/core/talloc.h> #include <osmocom/core/utils.h> -#include <osmocom/core/logging.h> +#include <osmocom/core/logging_internal.h> #include <osmocom/core/timer.h> #include <osmocom/core/thread.h> #include <osmocom/core/select.h> @@ -71,12 +71,6 @@ #include <osmocom/vty/logging.h> /* for LOGGING_STR. */ -/* maximum length of the log string of a single log event (typically line) */ -#define MAX_LOG_SIZE 4096 - -/* maximum number of log statements we queue in file/stderr target write queue */ -#define LOG_WQUEUE_LEN 156 - osmo_static_assert(_LOG_CTX_COUNT <= ARRAY_SIZE(((struct log_context*)NULL)->ctx), enum_logging_ctx_items_fit_in_struct_log_context); osmo_static_assert(_LOG_FLT_COUNT <= ARRAY_SIZE(((struct log_target*)NULL)->filter_data), @@ -90,7 +84,7 @@ void *tall_log_ctx = NULL; LLIST_HEAD(osmo_log_target_list); -static __thread long int logging_tid; +__thread struct log_thread_state log_thread_state; #if (!EMBEDDED) /*! One global copy that contains the union of log levels for all targets @@ -566,9 +560,9 @@ * \paramin format format string * \paramin ap variable argument list for format * \returns number of bytes written to out */ -static int _output_buf(char *buf, int buf_len, struct log_target *target, unsigned int subsys, - unsigned int level, const char *file, int line, int cont, - const char *format, va_list ap) +int log_output_buf(char *buf, int buf_len, struct log_target *target, unsigned int subsys, + unsigned int level, const char *file, int line, int cont, + const char *format, va_list ap) { int ret; const char *c_subsys = NULL; @@ -612,9 +606,9 @@ OSMO_STRBUF_PRINTF(sb, " "); } if (target->print_tid) { - if (logging_tid == 0) - logging_tid = (long int)osmo_gettid(); - OSMO_STRBUF_PRINTF(sb, "%ld ", logging_tid); + if (log_thread_state.tid == 0) + log_thread_state.tid = (long int)osmo_gettid(); + OSMO_STRBUF_PRINTF(sb, "%ld ", log_thread_state.tid); } if (target->print_category) OSMO_STRBUF_PRINTF(sb, "%s%s%s%s ", @@ -679,19 +673,6 @@ return OSMO_STRBUF_CHAR_COUNT(sb); } -/* Format the log line for given target; use a stack buffer and call target->output */ -static void _output(struct log_target *target, unsigned int subsys, - unsigned int level, const char *file, int line, int cont, - const char *format, va_list ap) -{ - char bufMAX_LOG_SIZE; - int rc; - - rc = _output_buf(buf, sizeof(buf), target, subsys, level, file, line, cont, format, ap); - if (rc > 0) - target->output(target, level, buf); -} - /* Catch internal logging category indexes as well as out-of-bounds indexes. * For internal categories, the ID is negative starting with -1; and internal * logging categories are added behind the user categories. For out-of-bounds @@ -769,6 +750,14 @@ return; #endif + if (OSMO_UNLIKELY(log_thread_state.logging_active)) { + /* Avoid re-entrant logging: If logging to log target generates + * extra logging (eg. an error log line due to some wqueue being full), + * we may end up in an infinite loop, or deadlock trying to re-acquire + * this same lock. */ + return; + } + log_thread_state.logging_active = true; log_tgt_mutex_lock(); llist_for_each_entry(tar, &osmo_log_target_list, entry) { @@ -778,17 +767,24 @@ continue; /* According to the manpage, vsnprintf leaves the value of ap - * in undefined state. Since _output uses vsnprintf and it may + * in undefined state. Since log_output_buf uses vsnprintf and it may * be called several times, we have to pass a copy of ap. */ va_copy(bp, ap); - if (tar->raw_output) + if (tar->raw_output) { tar->raw_output(tar, subsys, level, file, line, cont, format, bp); - else - _output(tar, subsys, level, file, line, cont, format, bp); + } else { + /* Format the log line for given target; use a stack buffer and call target->output */ + char bufMAX_LOG_SIZE; + int rc = log_output_buf(buf, sizeof(buf), tar, subsys, level, + file, line, cont, format, bp); + if (rc > 0) + tar->output(tar, level, buf); + } va_end(bp); } log_tgt_mutex_unlock(); + log_thread_state.logging_active = false; } /*! logging function used by DEBUGP() macro @@ -886,7 +882,42 @@ return 0; } -/*! Enable the \ref LOG_FLT_ALL log filter +/*! Get the logging context + * \paramin ctx logging context + * \paramin ctx_nr logging context number + * \returns value set for the context + * + * A logging context is something like the subscriber identity to which + * the currently processed message relates, or the BTS through which it + * was received. The main use of this API is during + * (struct log_info)->filter_fn(ctx, log_tgt). + */ +void *log_get_context(const struct log_context *ctx, uint8_t ctx_nr) +{ + if (ctx_nr > LOG_MAX_CTX) + return NULL; + return ctx->ctxctx_nr; +} + +/*! Query whether a log filter is enabled or disabled + * \paramin target Log target to be queried + * \paramin log_filter_index the index of the log filter to query + * \returns whether the filtering is enabled (true) or disabled (false) + */ +bool log_get_filter(const struct log_target *target, int log_filter_index) +{ + /* TODO: in the future we can support app-specified log filters here, + * similar to how we do dynamic cateogries defined by apps. */ + if (log_filter_index < 0) + return false; + + if (log_filter_index >= LOG_MAX_FILTERS) + return false; + + return target->filter_map & (1 << log_filter_index); +} + +/*! Enable/disable the \ref LOG_FLT_ALL log filter * \paramin target Log target to be affected * \paramin all enable (1) or disable (0) the ALL filter * @@ -902,6 +933,67 @@ target->filter_map &= ~(1 << LOG_FLT_ALL); } +/*! Enable/disable a log filter + * \paramin target Log target to be affected + * \paramin log_filter_index the index of the log filter to set + * \paramin enable enable (true) or disable (false) the ALL filter + * \returns 0 on success, negative on error. + */ +int log_set_filter(struct log_target *target, int log_filter_index, bool enable) +{ + /* TODO: in the future we can support app-specified log filters here, + * similar to how we do dynamic cateogries defined by apps. */ + if (log_filter_index < 0) + return -EINVAL; + + if (log_filter_index >= LOG_MAX_FILTERS) + return -EINVAL; + + if (enable) + target->filter_map |= (1 << log_filter_index); + else + target->filter_map &= ~(1 << log_filter_index); + return 0; +}
View file
libosmocore_1.13.0.tar.xz/src/core/logging_emscripten.c
Added
@@ -0,0 +1,79 @@ +/*! \file logging_emscripten.c + * Logging support code using a JS callback. This module sends log + * messages to a JavaScript callback named `on_log` + * with interface on_log(const char *subsys, int level, const char *msg). + * */ +/* + * (C) 2026 by Timur Davydov <dtv.comp@gmail.com> + * All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/*! \addtogroup logging + * @{ + * \file logging_emscripten.c */ + +#include <stdarg.h> +#include <stdio.h> +#include <osmocom/core/utils.h> +#include <osmocom/core/logging.h> +#include <osmocom/core/logging_internal.h> + +#include <emscripten.h> + +EM_JS(void, on_log_wrapper, (const char *subsys, int level, const char *msg), { + return on_log(subsys, level, msg); +}); + +static void _emscripten_raw_output(struct log_target *target, int subsys, + unsigned int level, const char *file, + int line, int cont, const char *format, + va_list ap) +{ + char msgMAX_LOG_SIZE; + const char *subsys_name = log_category_name(subsys); + int rc; + + rc = vsnprintf(msg, sizeof(msg), format, ap); + if (rc <= 0) + return; + if (rc >= sizeof(msg)) + rc = sizeof(msg) - 1; + + /* Drop newline at the end if exists: */ + if (msgrc - 1 == '\n') + msgrc - 1 = '\0'; + + on_log_wrapper(subsys_name ? subsys_name : "", level, msg); +} + +/*! Create a new logging target for JS callback logging (uses `on_log`) + * \returns Log target in case of success, NULL in case of error + */ +struct log_target *log_target_create_emscripten(void) +{ + struct log_target *target; + + target = log_target_create(); + if (!target) + return NULL; + + target->type = LOG_TGT_TYPE_EMSCRIPTEN; + target->raw_output = _emscripten_raw_output; + + return target; +} + +/* @} */
View file
libosmocore_1.13.0.tar.xz/src/core/logging_file.c
Added
@@ -0,0 +1,421 @@ +/*! \file logging_file.c + * File & stderr logging support code. */ +/* + * (C) 2025-2026 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * (C) 2008-2010 by Harald Welte <laforge@gnumonks.org> + * (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org> + * All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/*! \addtogroup logging + * @{ + * \file logging_file.c */ + +#include "config.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <osmocom/core/talloc.h> +#include <osmocom/core/utils.h> +#include <osmocom/core/select.h> +#include <osmocom/core/write_queue.h> +#include <osmocom/core/osmo_io.h> +#include <osmocom/core/logging_internal.h> + +/* NOTE: We use target->tgt_file.wqueue->except_cb to store the struct osmo_io_fd, because the + * struct log_target is public and we cannot add pointers to it under tgt->tgt_file... + * It can be moved to target->tgt_file.iofd if we are ever able to make struct log_target private... */ + +/*! close and re-open a log file (for log file rotation) + * \paramin target log target to re-open + * \returns 0 in case of success; negative otherwise */ +int log_target_file_reopen(struct log_target *target) +{ + struct osmo_io_fd *iofd; + int rc; + + OSMO_ASSERT(target->type == LOG_TGT_TYPE_FILE || + target->type == LOG_TGT_TYPE_STDERR); + + if (target->type == LOG_TGT_TYPE_STDERR) + return -ENOTSUP; + + if (target->tgt_file.out) { /* stream mode */ + int nonblock_flag = log_target_file_get_nonblock(target) != 0 ? 1 : 0; + fclose(target->tgt_file.out); + target->tgt_file.out = fopen(target->tgt_file.fname, "a"); + if (!target->tgt_file.out) + return -errno; + log_target_file_set_nonblock(target, nonblock_flag); + return 0; + } + + OSMO_ASSERT(target->tgt_file.wqueue); + iofd = (struct osmo_io_fd *)target->tgt_file.wqueue->except_cb; + OSMO_ASSERT(iofd); + osmo_iofd_close(iofd); + target->tgt_file.wqueue->bfd.fd = -1; /* Keep public field changes despite not used internally... */ + + rc = open(target->tgt_file.fname, O_WRONLY|O_APPEND|O_CREAT|O_NONBLOCK, 0660); + if (rc < 0) + return -errno; + + rc = osmo_iofd_register(iofd, rc); + if (rc < 0) { + osmo_iofd_free(iofd); + target->tgt_file.wqueue->except_cb = NULL; /* target->tgt_file.iofd = NULL */ + return -EIO; + } + target->tgt_file.wqueue->bfd.fd = rc; /* Keep public field changes despite not used internally... */ + return 0; +} + +#if (!EMBEDDED) + +/*! Set the log target fd as non-blocking (see sockopt O_NONBLOCK). + * \paramin target log target which we should switch + * \paramin on set to 1 to set as non-blocking, 0 to set as blocking. + * \returns 0 on success; negative on error + * + * This setting is ignored when \ref target is in wqueue mode. + */ +int log_target_file_set_nonblock(struct log_target *target, int on) +{ + int flags; + int fd; + + if (!target->tgt_file.out) + return 0; + + fd = fileno(target->tgt_file.out); + if (fd < 0) + return fd; + + flags = fcntl(fd, F_GETFL); + if (flags < 0) + return flags; + + if (on) + flags |= O_NONBLOCK; + else + flags &= ~O_NONBLOCK; + + flags = fcntl(fd, F_SETFL, flags); + if (flags < 0) + return flags; + return 0; +} + +/*! Find whether the log target fd is configured as non-blocking (see sockopt O_NONBLOCK). + * \paramin target log target which we should switch + * \returns 1 if set as non-block; 0 otherwise; negative on error + */ +int log_target_file_get_nonblock(const struct log_target *target) +{ + int flags; + int fd; + + if (!target->tgt_file.out) + return -1; + + fd = fileno(target->tgt_file.out); + if (fd < 0) + return fd; + + flags = fcntl(fd, F_GETFL); + if (flags < 0) + return flags; + return (flags & O_NONBLOCK) ? 1 : 0; +} + +/* This is the file-specific subclass destructor logic, called from + * log_target_destroy(). User should call log_target_destroy() to destroy this + * object. */ +void log_target_file_destroy(struct log_target *target) +{ + + OSMO_ASSERT(target->type == LOG_TGT_TYPE_FILE || + target->type == LOG_TGT_TYPE_STDERR); + + if (target->tgt_file.out) { + if (target->type == LOG_TGT_TYPE_FILE) + fclose(target->tgt_file.out); + target->tgt_file.out = NULL; + } + + if (target->tgt_file.wqueue && target->tgt_file.wqueue->except_cb) { /* target->tgt_file.iofd */ + osmo_iofd_free((struct osmo_io_fd *)target->tgt_file.wqueue->except_cb); + target->tgt_file.wqueue->except_cb = NULL; /* target->tgt_file.iofd = NULL */ + target->tgt_file.wqueue->bfd.fd = -1; /* Keep public field changes despite not used internally... */ + } + + talloc_free((void *)target->tgt_file.fname); + target->tgt_file.fname = NULL; +} + +static struct osmo_io_ops log_target_file_io_ops = { + .read_cb = NULL, + .write_cb = NULL, +}; + +/* output via buffered, blocking stdio streams */ +static void _file_output_stream(struct log_target *target, unsigned int level, + const char *log) +{ + OSMO_ASSERT(target->tgt_file.out); + fputs(log, target->tgt_file.out); + fflush(target->tgt_file.out); +} + +/* output via non-blocking write_queue, doing internal buffering */ +static void _file_raw_output(struct log_target *target, int subsys, unsigned int level, const char *file, + int line, int cont, const char *format, va_list ap) +{ + OSMO_ASSERT(target->tgt_file.wqueue && target->tgt_file.wqueue->except_cb); + struct msgb *msg; + struct osmo_io_fd *iofd = (struct osmo_io_fd *)target->tgt_file.wqueue->except_cb; + void *pool_ctx = osmo_iofd_get_data(iofd); + int rc; +
View file
libosmocore_1.12.1.tar.xz/src/core/logging_gsmtap.c -> libosmocore_1.13.0.tar.xz/src/core/logging_gsmtap.c
Changed
@@ -44,12 +44,14 @@ #include <osmocom/core/utils.h> #include <osmocom/core/gsmtap.h> #include <osmocom/core/gsmtap_util.h> -#include <osmocom/core/logging.h> +#include <osmocom/core/logging_internal.h> #include <osmocom/core/timer.h> #include <osmocom/core/byteswap.h> #include <osmocom/core/thread.h> -#define GSMTAP_LOG_MAX_SIZE 4096 +#define GSMTAP_MSG_MAX_SIZE (sizeof(struct gsmtap_hdr) + \ + sizeof(struct gsmtap_osmocore_log_hdr) + \ + MAX_LOG_SIZE) static __thread uint32_t logging_gsmtap_tid; @@ -70,8 +72,8 @@ /* get timestamp ASAP */ osmo_gettimeofday(&tv, NULL); - msg = msgb_alloc(sizeof(*gh)+sizeof(*golh)+GSMTAP_LOG_MAX_SIZE, - "GSMTAP logging"); + + msg = msgb_alloc_c((void *)target->output, GSMTAP_MSG_MAX_SIZE, "GSMTAP logging"); /* GSMTAP header */ gh = (struct gsmtap_hdr *) msgb_put(msg, sizeof(*gh)); @@ -150,6 +152,32 @@ return NULL; } +#ifndef ENABLE_PSEUDOTALLOC + size_t num_pool_objects; + if (ofd_wq_mode) { + /* Allocate a talloc pool to avoid malloc() on the first 156 + * concurrently queued msgbs (~624KB per gsmtap_log target). + * Once the talloc_pool is full, new normal talloc chunks will be used. */ + num_pool_objects = LOG_WQUEUE_LEN; + } else { + /* When in synchronous mode (blocking & non-blocking), there's + * no queueing in gsmtap_sendmsg() so there's no need to have a + * pool with multiple msgbs. */ + num_pool_objects = 1; + } + /* XXX: Abuse "output" field to store the talloc_pool, since it's not + * used in gsmtap log target. This can be moved to its own field once we + * make "struct log_target" private. + */ + target->output = _talloc_pooled_object(target, 0, "gsmtap_log_msgb_pool", + num_pool_objects, + (sizeof(struct msgb) + GSMTAP_MSG_MAX_SIZE) * num_pool_objects); +#else + /* talloc pools not supported by pseudotalloc, allocate on usual msgb ctx instead: */ + extern void *tall_msgb_ctx; + target->output = tall_msgb_ctx; +#endif /* ifndef ENABLE_PSEUDOTALLOC */ + if (add_sink) gsmtap_source_add_sink(gti);
View file
libosmocore_1.12.1.tar.xz/src/core/logging_syslog.c -> libosmocore_1.13.0.tar.xz/src/core/logging_syslog.c
Changed
@@ -24,8 +24,6 @@ #include "config.h" -#ifdef HAVE_SYSLOG_H - #include <stdarg.h> #include <stdlib.h> #include <stdio.h> @@ -84,6 +82,4 @@ return target; } -#endif /* HAVE_SYSLOG_H */ - /* @} */
View file
libosmocore_1.12.1.tar.xz/src/core/netdev.c -> libosmocore_1.13.0.tar.xz/src/core/netdev.c
Changed
@@ -82,6 +82,8 @@ #include <net/if.h> #include <net/route.h> +#if ENABLE_LIBMNL + #if defined(__linux__) #include <linux/if_link.h> #include <linux/rtnetlink.h> @@ -89,6 +91,8 @@ #error "Unknown platform!" #endif +#endif /* ENABLE_LIBMNL */ + #include <osmocom/core/utils.h> #include <osmocom/core/select.h> #include <osmocom/core/linuxlist.h>
View file
libosmocore_1.12.1.tar.xz/src/core/netns.c -> libosmocore_1.13.0.tar.xz/src/core/netns.c
Changed
@@ -26,8 +26,6 @@ * * \file netns.c */ -#if defined(__linux__) - #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif @@ -36,13 +34,21 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#ifdef HAVE_SCHED_H #include <sched.h> +#endif #include <signal.h> #include <sys/types.h> #include <sys/stat.h> +#ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> +#endif +#ifdef HAVE_SYS_MOUNT_H #include <sys/mount.h> +#endif +#ifdef HAVE_SYS_PARAM_H #include <sys/param.h> +#endif #include <fcntl.h> #include <errno.h> @@ -52,6 +58,8 @@ #define NETNS_PREFIX_PATH "/var/run/netns" #define NETNS_CURRENT_PATH "/proc/self/ns/net" +// To prevent unused function errors when neither setns nor CLONE_NEWNET are available +#if (HAVE_SETNS && HAVE_CLONE_NEWNET) /*! Open a file descriptor for the current network namespace. * \returns fd of the current network namespace on success; negative in case of error */ @@ -63,6 +71,7 @@ return -errno; return fd; } +#endif /* HAVE_SETNS && HAVE_CLONE_NEWNET */ /*! switch to a (non-default) namespace, store existing signal mask in oldmask. * \paramin nsfd file descriptor representing the namespace to which we shall switch @@ -70,6 +79,7 @@ * \returns 0 on success; negative on error */ int osmo_netns_switch_enter(int nsfd, struct osmo_netns_switch_state *state) { +#if (HAVE_SETNS && HAVE_CLONE_NEWNET) sigset_t intmask; int rc; @@ -89,6 +99,9 @@ return -errno; } return 0; +#else + return -ENOTSUP; +#endif /* HAVE_SETNS && HAVE_CLONE_NEWNET */ } /*! switch back to the previous namespace, restoring signal mask. @@ -96,6 +109,7 @@ * \returns 0 on successs; negative on error */ int osmo_netns_switch_exit(struct osmo_netns_switch_state *state) { +#if (HAVE_SETNS && HAVE_CLONE_NEWNET) if (state->prev_nsfd < 0) return -EINVAL; @@ -109,10 +123,14 @@ if ((rc = sigprocmask(SIG_SETMASK, &state->prev_sigmask, NULL)) != 0) return -rc; return 0; +#else + return -ENOTSUP; +#endif /* HAVE_SETNS && HAVE_CLONE_NEWNET */ } static int create_netns(const char *name) { +#if (HAVE_UNSHARE && HAVE_MOUNT && HAVE_SETNS && HAVE_CLONE_NEWNET) char pathMAXPATHLEN; sigset_t intmask, oldmask; int fd, prev_nsfd; @@ -175,6 +193,9 @@ return -errno; return fd; +#else + return -ENOTSUP; +#endif /* HAVE_UNSHARE && HAVE_MOUNT && HAVE_SETNS && HAVE_CLONE_NEWNET */ } /*! Open a file descriptor for the network namespace with provided name. @@ -203,6 +224,4 @@ return fd; } -#endif /* defined(__linux__) */ - /*! @} */
View file
libosmocore_1.12.1.tar.xz/src/core/osmo_io.c -> libosmocore_1.13.0.tar.xz/src/core/osmo_io.c
Changed
@@ -31,6 +31,7 @@ #include <string.h> #include <stdbool.h> #include <errno.h> +#include <inttypes.h> #include <osmocom/core/osmo_io.h> #include <osmocom/core/linuxlist.h> @@ -68,13 +69,14 @@ /* Used by some tests, can't be static */ struct iofd_backend_ops osmo_iofd_ops; -#if defined(HAVE_URING) -void osmo_iofd_uring_init(void); -#endif +static __thread bool g_thread_initialized = false; /*! initialize osmo_io for the current thread */ void osmo_iofd_init(void) { + if (g_thread_initialized) + return; + switch (g_io_backend) { case OSMO_IO_BACKEND_POLL: break; @@ -87,6 +89,7 @@ OSMO_ASSERT(0); break; } + g_thread_initialized = true; } /* ensure main thread always has pre-initialized osmo_io @@ -104,6 +107,7 @@ } else if (!strcmp("IO_URING", backend)) { g_io_backend = OSMO_IO_BACKEND_IO_URING; osmo_iofd_ops = iofd_uring_ops; + osmo_iofd_uring_constructor(); #endif } else { fprintf(stderr, "Invalid osmo_io backend requested: \"%s\"\nCheck the environment variable %s\n", backend, OSMO_IO_BACKEND_ENV); @@ -296,8 +300,11 @@ } /*! 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. + * one complete message. + * If there are bytes left over, *pending_out will point to a msgb with the remaining data. + * Upon IOFD_SEG_ACT_DEFER is returned, errno is set to error value providing reason: + * EAGAIN is returned when data is still missing to fill the segment; other error codes are + * propagated through read_cb(). */ static enum iofd_seg_act iofd_handle_segmentation(struct osmo_io_fd *iofd, struct msgb *msg, struct msgb **pending_out) { @@ -318,15 +325,12 @@ return IOFD_SEG_ACT_HANDLE_ONE; } - if (expected_len == -EAGAIN) { + if (expected_len < 0) { + if (expected_len != -EAGAIN) + LOGPIO(iofd, LOGL_ERROR, "segmentation_cb returned error (%d), skipping msg of size %d\n", + expected_len, received_len); + errno = -expected_len; goto defer; - } else if (expected_len < 0) { - /* Something is wrong, skip this msgb */ - LOGPIO(iofd, LOGL_ERROR, "segmentation_cb returned error (%d), skipping msg of size %d\n", - expected_len, received_len); - *pending_out = NULL; - msgb_free(msg); - return IOFD_SEG_ACT_DEFER; } extra_len = received_len - expected_len; @@ -334,8 +338,11 @@ if (extra_len == 0) { *pending_out = NULL; return IOFD_SEG_ACT_HANDLE_ONE; + } + /* segment is incomplete */ - } else if (extra_len < 0) { + if (extra_len < 0) { + errno = EAGAIN; goto defer; } @@ -357,63 +364,124 @@ return IOFD_SEG_ACT_DEFER; } +static void _call_read_cb(struct osmo_io_fd *iofd, int rc, struct msgb *msg) +{ + talloc_steal(iofd->msgb_alloc.ctx, msg); + iofd->io_ops.read_cb(iofd, rc, msg); +} + +static inline uint16_t iofd_msgb_length_max(const struct osmo_io_fd *iofd) +{ + return UINT16_MAX - iofd->msgb_alloc.headroom; +} + +/* Update iofd->pending copying as much data as possible from in_msg. + * Return unprocessed tail of in_msg, or NULL if all in_msg was copied into iofd->pending. +*/ +static struct msgb *iofd_prepare_handle_segmentation(struct osmo_io_fd *iofd, struct msgb *in_msg) +{ + if (OSMO_LIKELY(msgb_tailroom(iofd->pending) >= msgb_length(in_msg))) { + /* Append incoming msg into iofd->pending. */ + memcpy(msgb_put(iofd->pending, msgb_length(in_msg)), + msgb_data(in_msg), + msgb_length(in_msg)); + msgb_free(in_msg); + return NULL; + } + + /* Data of msg does not fit into pending message. Allocate a new message that is larger. + * This implies that msgb_length(iofd->pending) + msgb_length(msg) > iofd.msgb_alloc.size. + * Limit allowed segment size to maximum a msgb can contain. */ + uint16_t append_bytes = OSMO_MIN(msgb_length(in_msg), iofd_msgb_length_max(iofd) - msgb_length(iofd->pending)); + + /* Recreate iofd->pending to contain as much data as possible: */ + struct msgb *new_pending = iofd_msgb_alloc2(iofd, msgb_length(iofd->pending) + append_bytes); + OSMO_ASSERT(new_pending); + memcpy(msgb_put(new_pending, msgb_length(iofd->pending)), + msgb_data(iofd->pending), + msgb_length(iofd->pending)); + msgb_free(iofd->pending); + iofd->pending = new_pending; + + /* Append as much new data as possible into iofd->pending: */ + memcpy(msgb_put(iofd->pending, append_bytes), + msgb_data(in_msg), + append_bytes); + if (OSMO_LIKELY(msgb_length(in_msg) == 0)) { + msgb_free(in_msg); + return NULL; + } + msgb_pull(in_msg, append_bytes); + return in_msg; +} + /*! Restore message boundaries on read() and pass individual messages to the read callback */ -void iofd_handle_segmented_read(struct osmo_io_fd *iofd, struct msgb *msg, int rc) +static void iofd_handle_segmented_read(struct osmo_io_fd *iofd, int rc, struct msgb *msg) { int res; - struct msgb *pending; + struct msgb *tail_msg; OSMO_ASSERT(iofd->mode == OSMO_IO_FD_MODE_READ_WRITE); if (rc <= 0) { - talloc_steal(iofd->msgb_alloc.ctx, msg); - iofd->io_ops.read_cb(iofd, rc, msg); + _call_read_cb(iofd, rc, msg); return; } - /* If we have a pending message, append the received message. - * If the pending message is not large enough, create a larger message. */ - if (OSMO_UNLIKELY(iofd->pending)) { - if (OSMO_UNLIKELY(msgb_tailroom(iofd->pending) < msgb_length(msg))) { - /* Data of msg does not fit into pending message. Allocate a new message that is larger. - * This implies that msgb_length(iofd->pending) + msgb_length(msg) > iofd.msgb_alloc.size. */ - pending = iofd_msgb_alloc2(iofd, msgb_length(iofd->pending) + msgb_length(msg)); - OSMO_ASSERT(pending); - memcpy(msgb_put(pending, msgb_length(iofd->pending)), msgb_data(iofd->pending), - msgb_length(iofd->pending)); - msgb_free(iofd->pending); - iofd->pending = pending; + /* Base case: our tail msg is the just received chunk */ + tail_msg = msg; + do { + if (OSMO_UNLIKELY(iofd->pending)) { + /* If we have a pending message, append the received message. + * If the pending message is not large enough, create a larger message. */ + if (tail_msg) + tail_msg = iofd_prepare_handle_segmentation(iofd, tail_msg); + msg = iofd->pending; + iofd->pending = NULL; + } else { + OSMO_ASSERT(tail_msg); + msg = tail_msg; + tail_msg = NULL; } - memcpy(msgb_put(iofd->pending, msgb_length(msg)), msgb_data(msg), msgb_length(msg)); - msgb_free(msg); - msg = iofd->pending; - iofd->pending = NULL; - } - do { - pending = NULL; - res = iofd_handle_segmentation(iofd, msg, &pending); + /* At this point:
View file
libosmocore_1.12.1.tar.xz/src/core/osmo_io_internal.h -> libosmocore_1.13.0.tar.xz/src/core/osmo_io_internal.h
Changed
@@ -2,9 +2,10 @@ #pragma once +#include "../config.h" + #include <unistd.h> #include <stdbool.h> -#include <netinet/sctp.h> #include <osmocom/core/osmo_io.h> #include <osmocom/core/linuxlist.h> @@ -12,8 +13,6 @@ #include <osmocom/core/select.h> #include <osmocom/core/socket.h> -#include "../config.h" - #define OSMO_IO_DEFAULT_MSGB_SIZE 1024 #define OSMO_IO_DEFAULT_MSGB_HEADROOM 128 @@ -22,6 +21,8 @@ #if defined(HAVE_URING) extern const struct iofd_backend_ops iofd_uring_ops; +void osmo_iofd_uring_constructor(void); +void osmo_iofd_uring_init(void); #endif struct iofd_backend_ops { @@ -171,8 +172,11 @@ /*! msghdr is in the cancel_queue list */ bool in_cancel_queue; - /*! control message buffer for passing sctp_sndrcvinfo along */ - char cmsg0; /* size is determined by iofd->cmsg_size on recvmsg, and by mcghdr->msg_controllen on sendmsg */ + /*! control message buffer for passing sctp_sndrcvinfo along. + * Size is determined by iofd->cmsg_size on recvmsg, and by mcghdr->msg_controllen on sendmsg. + * Alignment of the array is required due to cast to "struct cmsghdr", eg. by CMSG_FIRSTHDR(). + */ + char _Alignas(struct cmsghdr) cmsg0; }; enum iofd_seg_act { @@ -189,7 +193,6 @@ void iofd_handle_recv(struct osmo_io_fd *iofd, struct msgb *msg, int rc, struct iofd_msghdr *msghdr); void iofd_handle_send_completion(struct osmo_io_fd *iofd, int rc, struct iofd_msghdr *msghdr); -void iofd_handle_segmented_read(struct osmo_io_fd *iofd, struct msgb *msg, int rc); int iofd_txqueue_enqueue(struct osmo_io_fd *iofd, struct iofd_msghdr *msghdr); void iofd_txqueue_enqueue_front(struct osmo_io_fd *iofd, struct iofd_msghdr *msghdr);
View file
libosmocore_1.12.1.tar.xz/src/core/osmo_io_poll.c -> libosmocore_1.13.0.tar.xz/src/core/osmo_io_poll.c
Changed
@@ -29,6 +29,7 @@ #include <unistd.h> #include <stdbool.h> #include <sys/socket.h> +#include <sys/uio.h> #include <osmocom/core/osmo_io.h> #include <osmocom/core/linuxlist.h> @@ -41,62 +42,121 @@ #include "osmo_io_internal.h" +/*! completion call-back for READ */ +static void iofd_poll_handle_recv(struct iofd_msghdr *msghdr, int rc) +{ + struct osmo_io_fd *iofd = msghdr->iofd; + uint8_t idx; + + for (idx = 0; idx < msghdr->io_len; idx++) { + struct msgb *msg = msghdr->msgidx; + int chunk; + + msghdr->msgidx = NULL; + if (rc > 0) { + if (rc > msghdr->iovidx.iov_len) + chunk = msghdr->iovidx.iov_len; + else + chunk = rc; + rc -= chunk; + msgb_put(msg, chunk); + } else { + chunk = rc; + } + + /* Check for every iteration, because iofd might get unregistered/closed during receive function. */ + if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_FD_REGISTERED) && (iofd->u.poll.ofd.when & OSMO_FD_READ)) + iofd_handle_recv(iofd, msg, chunk, msghdr); + else + msgb_free(msg); + + if (rc <= 0) + break; + } + while (++idx < msghdr->io_len) { + msgb_free(msghdr->msgidx); + msghdr->msgidx = NULL; + } + + iofd_msghdr_free(msghdr); +} + static void iofd_poll_ofd_cb_recvmsg_sendmsg(struct osmo_fd *ofd, unsigned int what) { struct osmo_io_fd *iofd = ofd->data; - struct msgb *msg; - int rc, flags = 0; + enum iofd_msg_action action; + struct iofd_msghdr *msghdr; + int rc; + uint8_t idx; if (what & OSMO_FD_READ) { - struct iofd_msghdr hdr; - - msg = iofd_msgb_alloc(iofd); - if (!msg) { - LOGPIO(iofd, LOGL_ERROR, "Could not allocate msgb for reading\n"); - OSMO_ASSERT(0); - } switch (iofd->mode) { case OSMO_IO_FD_MODE_READ_WRITE: - rc = read(ofd->fd, msg->tail, msgb_tailroom(msg)); - if (rc > 0) - msgb_put(msg, rc); - iofd_handle_recv(iofd, msg, (rc < 0 && errno > 0) ? -errno : rc, NULL); + action = IOFD_ACT_READ; break; case OSMO_IO_FD_MODE_RECVFROM_SENDTO: + action = IOFD_ACT_RECVFROM; + break; case OSMO_IO_FD_MODE_RECVMSG_SENDMSG: - hdr.msg0 = msg; - hdr.iov0.iov_base = msg->tail; - hdr.iov0.iov_len = msgb_tailroom(msg); - hdr.hdr = (struct msghdr) { - .msg_iov = &hdr.iov0, - .msg_iovlen = 1, - .msg_name = &hdr.osa.u.sa, - .msg_namelen = sizeof(struct osmo_sockaddr), - }; - if (iofd->mode == OSMO_IO_FD_MODE_RECVMSG_SENDMSG) { - hdr.hdr.msg_control = alloca(iofd->cmsg_size); - hdr.hdr.msg_controllen = iofd->cmsg_size; - } - rc = recvmsg(ofd->fd, &hdr.hdr, flags); - if (rc > 0) - msgb_put(msg, rc); - iofd_handle_recv(iofd, msg, (rc < 0 && errno > 0) ? -errno : rc, &hdr); + action = IOFD_ACT_RECVMSG; break; default: OSMO_ASSERT(0); } + + msghdr = iofd_msghdr_alloc(iofd, action, NULL, iofd->cmsg_size); + if (!msghdr) { + LOGPIO(iofd, LOGL_ERROR, "Could not allocate msghdr for reading\n"); + OSMO_ASSERT(0); + } + + for (idx = 0; idx < msghdr->io_len; idx++) { + msghdr->iovidx.iov_base = msghdr->msgidx->tail; + msghdr->iovidx.iov_len = msgb_tailroom(msghdr->msgidx); + } + + switch (action) { + case IOFD_ACT_RECVMSG: + msghdr->hdr.msg_control = msghdr->cmsg; + msghdr->hdr.msg_controllen = iofd->cmsg_size; + /* fall-through */ + case IOFD_ACT_RECVFROM: + msghdr->hdr.msg_name = &msghdr->osa.u.sa; + msghdr->hdr.msg_namelen = osmo_sockaddr_size(&msghdr->osa); + /* fall-through */ + case IOFD_ACT_READ: + msghdr->hdr.msg_iov = &msghdr->iov0; + msghdr->hdr.msg_iovlen = msghdr->io_len; + break; + default: + OSMO_ASSERT(0); + } + + switch (action) { + case IOFD_ACT_READ: + rc = readv(ofd->fd, msghdr->hdr.msg_iov, msghdr->hdr.msg_iovlen); + break; + case IOFD_ACT_RECVFROM: + case IOFD_ACT_RECVMSG: + rc = recvmsg(ofd->fd, &msghdr->hdr, msghdr->flags); + break; + default: + OSMO_ASSERT(0); + } + + iofd_poll_handle_recv(msghdr, (rc < 0 && errno > 0) ? -errno : rc); } if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_CLOSED)) return; if (what & OSMO_FD_WRITE) { - struct iofd_msghdr *msghdr = iofd_txqueue_dequeue(iofd); + msghdr = iofd_txqueue_dequeue(iofd); if (msghdr) { switch (iofd->mode) { case OSMO_IO_FD_MODE_READ_WRITE: - rc = write(ofd->fd, msghdr->iov0.iov_base, msghdr->iov0.iov_len); + rc = writev(ofd->fd, msghdr->iov, msghdr->io_len); break; case OSMO_IO_FD_MODE_RECVFROM_SENDTO: case OSMO_IO_FD_MODE_RECVMSG_SENDMSG:
View file
libosmocore_1.12.1.tar.xz/src/core/osmo_io_uring.c -> libosmocore_1.13.0.tar.xz/src/core/osmo_io_uring.c
Changed
@@ -34,6 +34,7 @@ #include <unistd.h> #include <string.h> #include <stdbool.h> +#include <fcntl.h> #include <errno.h> #include <limits.h> @@ -64,7 +65,6 @@ #define OSMO_IO_URING_READ_SQE "LIBOSMO_IO_URING_READ_SQE" bool g_io_uring_batch = false; -bool g_io_uring_submit_needed = false; static int g_io_uring_size = IOFD_URING_INITIAL_SIZE; @@ -75,6 +75,7 @@ struct io_uring ring; struct llist_head cancel_queue; unsigned int num_pending_submissions; + bool submit_needed; }; static __thread struct osmo_io_uring *g_ring = NULL; @@ -106,15 +107,15 @@ } /*! initialize the uring and tie it into our event loop */ -void osmo_iofd_uring_init(void) +void osmo_iofd_uring_constructor(void) { const char *env; - int rc, evfd; + int rc; if ((env = getenv(OSMO_IO_URING_BATCH))) g_io_uring_batch = true; - if (!g_ring && (env = getenv(OSMO_IO_URING_INITIAL_SIZE))) { + if ((env = getenv(OSMO_IO_URING_INITIAL_SIZE))) { int env_value; rc = osmo_str_to_int(&env_value, env, 10, 1, IOFD_URING_MAXIMUM_SIZE); if (rc < 0) { @@ -129,13 +130,6 @@ g_io_uring_size = env_value; } - g_ring = talloc_zero(OTC_GLOBAL, struct osmo_io_uring); - INIT_LLIST_HEAD(&g_ring->cancel_queue); - - rc = io_uring_queue_init(g_io_uring_size, &g_ring->ring, 0); - if (rc < 0) - osmo_panic("failure during io_uring_queue_init(): %s\n", strerror(-rc)); - if ((env = getenv(OSMO_IO_URING_READ_SQE))) { g_io_uring_read_sqes = atoi(env); if (g_io_uring_read_sqes < 1 || g_io_uring_read_sqes > IOFD_MSGHDR_MAX_READ_SQES) { @@ -144,6 +138,20 @@ exit(1); } } +} + +/*! Per-thread: initialize the uring and tie it into our event loop */ +void osmo_iofd_uring_init(void) +{ + int rc, evfd; + + g_ring = talloc_zero(OTC_GLOBAL, struct osmo_io_uring); + OSMO_ASSERT(g_ring); + INIT_LLIST_HEAD(&g_ring->cancel_queue); + + rc = io_uring_queue_init(g_io_uring_size, &g_ring->ring, 0); + if (rc < 0) + osmo_panic("failure during io_uring_queue_init(): %s\n", strerror(-rc)); rc = eventfd(0, 0); if (rc < 0) { @@ -233,7 +241,7 @@ if (OSMO_LIKELY(!g_io_uring_batch)) io_uring_submit(&g_ring->ring); else - g_io_uring_submit_needed = true; + g_ring->submit_needed = true; } static inline int iofd_uring_submit_recv_sqe(struct osmo_io_fd *iofd, enum iofd_msg_action action) @@ -534,6 +542,23 @@ static void iofd_uring_write_enable(struct osmo_io_fd *iofd); static void iofd_uring_read_enable(struct osmo_io_fd *iofd); +/* make an FD blockig: + * osmo_fd_register(ofd) did set fd flag O_NONBLOCK previously. We don't + * want to keep the fd as O_NONBLOCK once we start using io_uring, + * otherwise we'd end up getting cqes with -EAGAIN; better let the kernel + * wait internally for the sqe to complete. */ +static int iofd_reset_fd_blocking(int fd) +{ + int flags; + + /* make FD nonblocking */ + flags = fcntl(fd, F_GETFL); + if (flags < 0) + return flags; + flags &= ~O_NONBLOCK; + flags = fcntl(fd, F_SETFL, flags); + return flags; +} /* called via osmocom poll/select main handling once outbound non-blocking connect() completes */ static int iofd_uring_connected_cb(struct osmo_fd *ofd, unsigned int what) @@ -547,6 +572,7 @@ /* Unregister from poll/select handling. */ osmo_fd_unregister(ofd); + iofd_reset_fd_blocking(ofd->fd); IOFD_FLAG_UNSET(iofd, IOFD_FLAG_NOTIFY_CONNECTED); /* Notify the application about this via a zero-length write completion call-back. */ @@ -590,8 +616,9 @@ /* OSMO_IO_FD_MODE_RECVMSG_SENDMSG: * Use a temporary osmo_fd which we can use to notify us once the connection is established * or failed (indicated by FD becoming writable). This is needed as (at least for SCTP sockets) - * one cannot submit a zero-length writev/sendmsg in order to get notification when the socekt - * is writable.*/ + * one cannot submit a zero-length writev/sendmsg in order to get notification when the socket + * is writable. + * NOTE: osmo_fd_register() sets iofd->fd as O_NONBLOCK. */ if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_NOTIFY_CONNECTED)) { osmo_fd_setup(&iofd->u.uring.connect_ofd, iofd->fd, OSMO_FD_WRITE, iofd_uring_connected_cb, iofd, 0); @@ -664,6 +691,7 @@ if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_NOTIFY_CONNECTED)) { osmo_fd_unregister(&iofd->u.uring.connect_ofd); + iofd_reset_fd_blocking(iofd->u.uring.connect_ofd.fd); IOFD_FLAG_UNSET(iofd, IOFD_FLAG_NOTIFY_CONNECTED); } @@ -785,9 +813,9 @@ void osmo_io_uring_submit(void) { - if (OSMO_LIKELY(g_io_uring_submit_needed)) { + if (OSMO_LIKELY(g_ring->submit_needed)) { io_uring_submit(&g_ring->ring); - g_io_uring_submit_needed = false; + g_ring->submit_needed = false; } }
View file
libosmocore_1.12.1.tar.xz/src/core/select.c -> libosmocore_1.13.0.tar.xz/src/core/select.c
Changed
@@ -509,12 +509,12 @@ int osmo_select_main(int polling) { int rc = _osmo_select_main(polling); -#ifndef EMBEDDED +#ifndef ENABLE_PSEUDOTALLOC if (talloc_total_size(osmo_ctx->select) != 0) { osmo_panic("You cannot use the 'select' volatile " "context if you don't use osmo_select_main_ctx()!\n"); } -#endif +#endif /* ifndef ENABLE_PSEUDOTALLOC */ return rc; }
View file
libosmocore_1.12.1.tar.xz/src/core/socket.c -> libosmocore_1.13.0.tar.xz/src/core/socket.c
Changed
@@ -46,6 +46,7 @@ #include <netinet/in.h> #include <arpa/inet.h> +#include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <stdint.h> @@ -133,12 +134,12 @@ static int socket_helper_tail(int sfd, unsigned int flags) { - int rc, on = 1; + int rc; uint8_t dscp = GET_OSMO_SOCK_F_DSCP(flags); uint8_t prio = GET_OSMO_SOCK_F_PRIO(flags); if (flags & OSMO_SOCK_F_NONBLOCK) { - if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { + if (osmo_sock_set_nonblock(sfd, 1) < 0) { LOGP(DLGLOBAL, LOGL_ERROR, "cannot set this socket unblocking: %s\n", strerror(errno)); @@ -1694,7 +1695,7 @@ static unsigned int in6_addr_netmask_to_prefixlen(const struct in6_addr *netmask) { - #if defined(__linux__) + #if (HAVE_IN6_ADDR_S6_ADDR32) #define ADDRFIELD(i) s6_addr32i #else #define ADDRFIELD(i) __u6_addr.__u6_addr32i @@ -1894,7 +1895,6 @@ return 0; } -#ifdef HAVE_LIBSCTP /*! Get multiple IP addresses and/or port number on socket in separate string buffers * \paramin fd file descriptor of socket. * \paramout ip_proto IPPROTO of the socket, eg: IPPROTO_SCTP. @@ -1925,10 +1925,12 @@ int osmo_sock_multiaddr_get_ip_and_port(int fd, int ip_proto, char *ip, size_t *ip_cnt, size_t ip_len, char *port, size_t port_len, bool local) { +#ifdef HAVE_LIBSCTP struct sockaddr *addrs = NULL; unsigned int n_addrs, i; void *addr_buf; int rc; +#endif /* HAVE_LIBSCTP */ switch (ip_proto) { case IPPROTO_SCTP: @@ -1942,6 +1944,7 @@ return osmo_sock_get_ip_and_port(fd, ip, ip_len, port, port_len, local); } +#ifdef HAVE_LIBSCTP rc = local ? sctp_getladdrs(fd, 0, &addrs) : sctp_getpaddrs(fd, 0, &addrs); if (rc < 0) return rc; @@ -1982,8 +1985,10 @@ free_addrs_ret: local ? sctp_freeladdrs(addrs) : sctp_freepaddrs(addrs); return rc; +#else + return -ENOTSUP; +#endif /* HAVE_LIBSCTP */ } -#endif /*! Get local IP address on socket * \paramin fd file descriptor of socket @@ -2046,7 +2051,6 @@ return talloc_asprintf(ctx, "(%s)", str); } -#ifdef HAVE_LIBSCTP /*! Format multiple IP addresses and/or port number into a combined string buffer * \paramout str Destination string buffer. * \paramin str_len sizeof(str), usually OSMO_SOCK_MULTIADDR_PEER_STR_MAXLEN. @@ -2152,7 +2156,6 @@ return sb.chars_needed; } -#endif /*! Get address/port information on socket in provided string buffer, like "r=1.2.3.4:5<->l=6.7.8.9:10". * This does not include braces like osmo_sock_get_name(). @@ -2746,6 +2749,27 @@ return setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio)); } +/*! Set the socket as non-blocking or blocking. + * \paramin fd File descriptor of the socket + * \paramin on set to 1 to set as non-blocking, 0 to set as blocking. + * \returns 0 on success; negative on error. */ +int osmo_sock_set_nonblock(int fd, int on) +{ + /* and write it back to the kernel */ + return ioctl(fd, FIONBIO, (unsigned char *)&on); +} + +/*! Find out whether the socket is configured as non-blocking or blocking. + * \paramin fd File descriptor of the socket + * \returns 1 == nonblocking, 0 == blocking, < 0 error */ +int osmo_sock_get_nonblock(int fd) +{ + int flags = fcntl(fd, F_GETFL); + if (flags < 0) + return flags; + return (flags & O_NONBLOCK) ? 1 : 0; +} + #ifdef HAVE_LIBSCTP /*! Fill in array of struct sctp_paddrinfo with each of the remote addresses of an SCTP socket * \paramin fd file descriptor of SCTP socket
View file
libosmocore_1.12.1.tar.xz/src/core/stats_tcp.c -> libosmocore_1.13.0.tar.xz/src/core/stats_tcp.c
Changed
@@ -22,7 +22,13 @@ * \file stats_tcp.c */ #include "config.h" -#if !defined(EMBEDDED) + +#include <errno.h> + +#include <osmocom/core/select.h> +#include <osmocom/core/stats_tcp.h> + +#ifdef HAVE_LINUX_TCP_H #include <sys/types.h> #include <sys/stat.h> @@ -30,10 +36,8 @@ #include <netinet/in.h> #include <netinet/ip.h> #include <linux/tcp.h> -#include <errno.h> #include <pthread.h> -#include <osmocom/core/select.h> #include <osmocom/core/linuxlist.h> #include <osmocom/core/talloc.h> #include <osmocom/core/utils.h> @@ -41,7 +45,8 @@ #include <osmocom/core/stat_item.h> #include <osmocom/core/stats.h> #include <osmocom/core/socket.h> -#include <osmocom/core/stats_tcp.h> + +#endif /* HAVE_LINUX_TCP_H */ static struct osmo_tcp_stats_config s_tcp_stats_config = { .interval = TCP_STATS_DEFAULT_INTERVAL, @@ -49,6 +54,8 @@ struct osmo_tcp_stats_config *osmo_tcp_stats_config = &s_tcp_stats_config; +#ifdef HAVE_LINUX_TCP_H + static struct osmo_timer_list stats_tcp_poll_timer; static LLIST_HEAD(stats_tcp); @@ -160,7 +167,6 @@ #else osmo_stat_item_set(osmo_stat_item_group_get_item(stats_tcp_entry->stats_tcp, STATS_TCP_REORD_SEEN), -1); #endif - } static bool is_tcp(const struct osmo_fd *fd) @@ -322,6 +328,25 @@ osmo_timer_setup(&stats_tcp_poll_timer, stats_tcp_poll_timer_cb, NULL); } -#endif /* !EMBEDDED */ +#else + +/* Stubs for systems that do not have header <linux/tcp.h> and TCP_INFO struct */ + +int osmo_stats_tcp_osmo_fd_register(const struct osmo_fd *fd, const char *name) +{ + return -ENOTSUP; +} + +int osmo_stats_tcp_osmo_fd_unregister(const struct osmo_fd *fd) +{ + return -ENOTSUP; +} + +int osmo_stats_tcp_set_interval(int interval) +{ + return -ENOTSUP; +} + +#endif /* HAVE_LINUX_TCP_H */ /* @} */
View file
libosmocore_1.12.1.tar.xz/src/core/tun.c -> libosmocore_1.13.0.tar.xz/src/core/tun.c
Changed
@@ -84,10 +84,8 @@ #include <sys/time.h> #include <net/if.h> -#if defined(__linux__) +#ifdef HAVE_LINUX_IF_TUN_H #include <linux/if_tun.h> -#else -#error "Unknown platform!" #endif #include <osmocom/core/utils.h> @@ -265,6 +263,7 @@ talloc_free(tundev); } +#ifdef HAVE_LINUX_IF_TUN_H /*! Open and configure fd of the tunnel device. * \paramin tundev The tundev object whose tunnel interface to open * \paramin flags internal linux flags to pass when creating the device (not used yet) @@ -337,6 +336,7 @@ close(fd); return rc; } +#endif /* HAVE_LINUX_IF_TUN_H */ /*! Open the tunnel device owned by the tundev object. * \paramin tundev The tundev object to open @@ -344,6 +344,7 @@ */ int osmo_tundev_open(struct osmo_tundev *tundev) { +#ifdef HAVE_LINUX_IF_TUN_H struct osmo_netns_switch_state switch_state; int rc; int netns_fd = -1; @@ -418,6 +419,9 @@ if (netns_fd >= 0) close(netns_fd); return rc; +#else + return -ENOTSUP; +#endif /* HAVE_LINUX_IF_TUN_H */ } /*! Close the tunnel device owned by the tundev object.
View file
libosmocore_1.12.1.tar.xz/src/ctrl/Makefile.am -> libosmocore_1.13.0.tar.xz/src/ctrl/Makefile.am
Changed
@@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=9:1:9 +LIBVERSION=9:2:9 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) AM_CFLAGS = -Wall $(TALLOC_CFLAGS)
View file
libosmocore_1.12.1.tar.xz/src/ctrl/fsm_ctrl_commands.c -> libosmocore_1.13.0.tar.xz/src/ctrl/fsm_ctrl_commands.c
Changed
@@ -120,7 +120,7 @@ if (osmo_timer_remaining(&fi->timer, NULL, &remaining) < 0) cmd->reply = "0,0,0"; else - cmd->reply = talloc_asprintf(cmd, "%u,%ld,%ld", fi->T, remaining.tv_sec, remaining.tv_usec); + cmd->reply = talloc_asprintf(cmd, "%u,%ld,%ld", fi->T, (long) remaining.tv_sec, (long) remaining.tv_usec); return CTRL_CMD_REPLY; } @@ -149,7 +149,7 @@ rc = osmo_timer_remaining(&fi->timer, NULL, &remaining); if (rc == 0) { cmd->reply = talloc_asprintf_append(cmd->reply, ",timeout_sec=%ld,timeout_usec=%ld", - remaining.tv_sec, remaining.tv_usec); + (long) remaining.tv_sec, (long) remaining.tv_usec); } }
View file
libosmocore_1.12.1.tar.xz/src/gb/Makefile.am -> libosmocore_1.13.0.tar.xz/src/gb/Makefile.am
Changed
@@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=17:1:3 +LIBVERSION=17:2:3 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_builddir) AM_CFLAGS = -Wall -fno-strict-aliasing \
View file
libosmocore_1.12.1.tar.xz/src/gb/common_vty.c -> libosmocore_1.13.0.tar.xz/src/gb/common_vty.c
Changed
@@ -40,23 +40,23 @@ int gprs_log_filter_fn(const struct log_context *ctx, struct log_target *tar) { - const void *nse = ctx->ctxLOG_CTX_GB_NSE; - const void *nsvc = ctx->ctxLOG_CTX_GB_NSVC; - const void *bvc = ctx->ctxLOG_CTX_GB_BVC; + const void *nse = log_get_context(ctx, LOG_CTX_GB_NSE); + const void *nsvc = log_get_context(ctx, LOG_CTX_GB_NSVC); + const void *bvc = log_get_context(ctx, LOG_CTX_GB_BVC); /* Filter on the NS Entity */ - if ((tar->filter_map & (1 << LOG_FLT_GB_NSE)) != 0 - && nse && (nse == tar->filter_dataLOG_FLT_GB_NSE)) + if (log_get_filter(tar, LOG_FLT_GB_NSE) && + nse && (nse == log_get_filter_data(tar, LOG_FLT_GB_NSE))) return 1; /* Filter on the NS Virtual Connection */ - if ((tar->filter_map & (1 << LOG_FLT_GB_NSVC)) != 0 - && nsvc && (nsvc == tar->filter_dataLOG_FLT_GB_NSVC)) + if (log_get_filter(tar, LOG_FLT_GB_NSVC) && + nsvc && (nsvc == log_get_filter_data(tar, LOG_FLT_GB_NSVC))) return 1; /* Filter on the BSSGP Virtual Connection */ - if ((tar->filter_map & (1 << LOG_FLT_GB_BVC)) != 0 - && bvc && (bvc == tar->filter_dataLOG_FLT_GB_BVC)) + if (log_get_filter(tar, LOG_FLT_GB_BVC) && + bvc && (bvc == log_get_filter_data(tar, LOG_FLT_GB_BVC))) return 1; return 0;
View file
libosmocore_1.12.1.tar.xz/src/gb/gprs_bssgp_vty.c -> libosmocore_1.13.0.tar.xz/src/gb/gprs_bssgp_vty.c
Changed
@@ -48,11 +48,11 @@ struct bssgp_bvc_ctx *bctx) { if (bctx) { - target->filter_map |= (1 << LOG_FLT_GB_BVC); - target->filter_dataLOG_FLT_GB_BVC = bctx; - } else if (target->filter_dataLOG_FLT_GB_BVC) { - target->filter_map = ~(1 << LOG_FLT_GB_BVC); - target->filter_dataLOG_FLT_GB_BVC = NULL; + log_set_filter(target, LOG_FLT_GB_BVC, true); + log_set_filter_data(target, LOG_FLT_GB_BVC, bctx); + } else if (log_get_filter(target, LOG_FLT_GB_BVC)) { + log_set_filter(target, LOG_FLT_GB_BVC, false); + log_set_filter_data(target, LOG_FLT_GB_BVC, NULL); } }
View file
libosmocore_1.12.1.tar.xz/src/gb/gprs_ns2_vty.c -> libosmocore_1.13.0.tar.xz/src/gb/gprs_ns2_vty.c
Changed
@@ -2180,11 +2180,11 @@ struct gprs_ns2_nse *nse) { if (nse) { - target->filter_map |= (1 << LOG_FLT_GB_NSE); - target->filter_dataLOG_FLT_GB_NSE = nse; - } else if (target->filter_dataLOG_FLT_GB_NSE) { - target->filter_map = ~(1 << LOG_FLT_GB_NSE); - target->filter_dataLOG_FLT_GB_NSE = NULL; + log_set_filter(target, LOG_FLT_GB_NSE, true); + log_set_filter_data(target, LOG_FLT_GB_NSE, nse); + } else if (log_get_filter(target, LOG_FLT_GB_NSE)) { + log_set_filter(target, LOG_FLT_GB_NSE, false); + log_set_filter_data(target, LOG_FLT_GB_NSE, NULL); } } @@ -2192,11 +2192,11 @@ struct gprs_ns2_vc *nsvc) { if (nsvc) { - target->filter_map |= (1 << LOG_FLT_GB_NSVC); - target->filter_dataLOG_FLT_GB_NSVC = nsvc; - } else if (target->filter_dataLOG_FLT_GB_NSVC) { - target->filter_map = ~(1 << LOG_FLT_GB_NSVC); - target->filter_dataLOG_FLT_GB_NSVC = NULL; + log_set_filter(target, LOG_FLT_GB_NSVC, true); + log_set_filter_data(target, LOG_FLT_GB_NSVC, nsvc); + } else if (log_get_filter(target, LOG_FLT_GB_NSVC)) { + log_set_filter(target, LOG_FLT_GB_NSVC, false); + log_set_filter_data(target, LOG_FLT_GB_NSVC, NULL); } }
View file
libosmocore_1.12.1.tar.xz/src/gb/gprs_ns_vty.c -> libosmocore_1.13.0.tar.xz/src/gb/gprs_ns_vty.c
Changed
@@ -68,11 +68,11 @@ struct gprs_nsvc *nsvc) { if (nsvc) { - target->filter_map |= (1 << LOG_FLT_GB_NSVC); - target->filter_dataLOG_FLT_GB_NSVC = nsvc; - } else if (target->filter_dataLOG_FLT_GB_NSVC) { - target->filter_map = ~(1 << LOG_FLT_GB_NSVC); - target->filter_dataLOG_FLT_GB_NSVC = NULL; + log_set_filter(target, LOG_FLT_GB_NSVC, true); + log_set_filter_data(target, LOG_FLT_GB_NSVC, nsvc); + } else if (log_get_filter(target, LOG_FLT_GB_NSVC)) { + log_set_filter(target, LOG_FLT_GB_NSVC, false); + log_set_filter_data(target, LOG_FLT_GB_NSVC, NULL); } }
View file
libosmocore_1.12.1.tar.xz/src/gsm/Makefile.am -> libosmocore_1.13.0.tar.xz/src/gsm/Makefile.am
Changed
@@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=23:0:3 +LIBVERSION=24:0:4 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include AM_CFLAGS = -Wall $(TALLOC_CFLAGS)
View file
libosmocore_1.12.1.tar.xz/src/gsm/auth_core.c -> libosmocore_1.13.0.tar.xz/src/gsm/auth_core.c
Changed
@@ -98,11 +98,11 @@ int osmo_auth_load(const char *path) { /* load all plugins available from path */ -#if !defined(EMBEDDED) +#ifdef ENABLE_PLUGIN return osmo_plugin_load_all(path); #else return -1; -#endif +#endif /* ifdef ENABLE_PLUGIN */ } /*! Determine if a given authentication algorithm is supported
View file
libosmocore_1.12.1.tar.xz/src/gsm/gprs_cipher_core.c -> libosmocore_1.13.0.tar.xz/src/gsm/gprs_cipher_core.c
Changed
@@ -66,11 +66,11 @@ /* load all available GPRS cipher plugins */ int gprs_cipher_load(const char *path) { -#if !defined(EMBEDDED) +#ifdef ENABLE_PLUGIN /* load all plugins available from path */ if (path) return osmo_plugin_load_all(path); -#endif +#endif /* ifdef ENABLE_PLUGIN */ return 0; }
View file
libosmocore_1.12.1.tar.xz/src/gsm/rsl.c -> libosmocore_1.13.0.tar.xz/src/gsm/rsl.c
Changed
@@ -121,6 +121,7 @@ RSL_IE_RTD = { TLV_TYPE_TV }, RSL_IE_TFO_STATUS = { TLV_TYPE_TV }, RSL_IE_LLP_APDU = { TLV_TYPE_TLV }, + RSL_IE_TFO_XPAR_CONT = { TLV_TYPE_TLV }, RSL_IE_SIEMENS_MRPCI = { TLV_TYPE_TV }, RSL_IE_OSMO_REP_ACCH_CAP = { TLV_TYPE_TLV }, RSL_IE_OSMO_TRAINING_SEQUENCE = { TLV_TYPE_TLV },
View file
libosmocore_1.12.1.tar.xz/src/vty/Makefile.am -> libosmocore_1.13.0.tar.xz/src/vty/Makefile.am
Changed
@@ -1,7 +1,7 @@ # This is _NOT_ the library release version, it's an API version. # Please read chapter "Library interface versions" of the libtool documentation # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html -LIBVERSION=13:4:0 +LIBVERSION=14:0:1 AM_CPPFLAGS = \ -I$(top_srcdir)/include \
View file
libosmocore_1.12.1.tar.xz/src/vty/command.c -> libosmocore_1.13.0.tar.xz/src/vty/command.c
Changed
@@ -33,7 +33,9 @@ #include <stdbool.h> #include <syslog.h> #include <errno.h> +#ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE +#endif #include <unistd.h> #include <ctype.h> #include <time.h>
View file
libosmocore_1.12.1.tar.xz/src/vty/logging_vty.c -> libosmocore_1.13.0.tar.xz/src/vty/logging_vty.c
Changed
@@ -29,7 +29,9 @@ #include <osmocom/core/strrb.h> #include <osmocom/core/loggingrb.h> #include <osmocom/core/gsmtap.h> +#include <osmocom/core/gsmtap_util.h> #include <osmocom/core/application.h> +#include <osmocom/core/socket.h> #include <osmocom/vty/command.h> #include <osmocom/vty/buffer.h> @@ -37,6 +39,9 @@ #include <osmocom/vty/telnet_interface.h> #include <osmocom/vty/logging.h> +/* From VTY core code. Used by gsmtap and syslog targets. */ +extern struct host host; + #define LOG_STR "Configure logging sub-system\n" #define LEVEL_STR "Set the log level for a specified category\n" @@ -639,7 +644,7 @@ 1 }; -#ifdef HAVE_SYSLOG_H +#ifdef ENABLE_SYSLOG_LOGGING #include <syslog.h> @@ -654,9 +659,6 @@ 7 = LOG_LOCAL7 }; -/* From VTY core code */ -extern struct host host; - static int _cfg_log_syslog(struct vty *vty, int facility) { struct log_target *tgt; @@ -749,7 +751,7 @@ RET_WITH_UNLOCK(CMD_SUCCESS); } -#endif /* HAVE_SYSLOG_H */ +#endif /* ENABLE_SYSLOG_LOGGING */ DEFUN(cfg_log_systemd_journal, cfg_log_systemd_journal_cmd, "log systemd-journal raw", @@ -810,25 +812,50 @@ } DEFUN(cfg_log_gsmtap, cfg_log_gsmtap_cmd, - "log gsmtap HOSTNAME", + "log gsmtap HOSTNAME (nonblocking-io|blocking-io|wq)", LOG_STR "Logging via GSMTAP\n" - "Host name to send the GSMTAP logging to (UDP port 4729)\n") -{ - const char *hostname = argc ? argv0 : "127.0.0.1"; + "Host name to send the GSMTAP logging to (UDP port 4729)\n" + "Use non-blocking, synchronous I/O (may lose msgs if UDP socket send buffer becomes full) (default)\n" + "Use blocking, synchronous I/O (only for debug purposes or when blocking is acceptable)\n" + "Use Tx workqueue, asynchronous I/O (may lose msgs if queue becomes full)\n") +{ + const char *hostname = argc > 0 ? argv0 : "127.0.0.1"; + bool ofd_wq_mode = argc > 1 && (strcmp(argv1, "wq") == 0); + bool blocking_io = argc > 1 && (strcmp(argv1, "blocking-io") == 0); struct log_target *tgt; log_tgt_mutex_lock(); tgt = log_target_find(LOG_TGT_TYPE_GSMTAP, hostname); if (!tgt) { tgt = log_target_create_gsmtap(hostname, GSMTAP_UDP_PORT, - host.app_info->name, false, + host.app_info->name, ofd_wq_mode, true); if (!tgt) { vty_out(vty, "%% Unable to create GSMTAP log for %s%s", hostname, VTY_NEWLINE); RET_WITH_UNLOCK(CMD_WARNING); } + if (!ofd_wq_mode && !blocking_io) { + int rc = gsmtap_source_set_nonblock(tgt->tgt_gsmtap.gsmtap_inst, 1); + if (rc != 0) + vty_out(vty, "%% Unable to configure GSMTAP log for %s as nonblocking-io%s", + hostname, VTY_NEWLINE); + } log_add_target(tgt); + } else { + if (ofd_wq_mode != gsmtap_source_using_wq(tgt->tgt_gsmtap.gsmtap_inst)) { + vty_out(vty, "%% Remove and re-add the log gsmtap target in order to " + "change between synchronous and asynchronous IO%s", VTY_NEWLINE); + RET_WITH_UNLOCK(CMD_WARNING); + } + if (!ofd_wq_mode) { + int fd = gsmtap_inst_fd2(tgt->tgt_gsmtap.gsmtap_inst); + if (fd > 0 && !osmo_sock_get_nonblock(fd) != blocking_io) { + vty_out(vty, "%% Remove and re-add the log gsmtap target in order to " + "change between blocking and non-blocking IO%s", VTY_NEWLINE); + RET_WITH_UNLOCK(CMD_WARNING); + } + } } vty->index = tgt; @@ -859,11 +886,15 @@ } DEFUN(cfg_log_stderr, cfg_log_stderr_cmd, - "log stderr blocking-io", + "log stderr (nonblocking-io|blocking-io|wq)", LOG_STR "Logging via STDERR of the process\n" - "Use blocking, synchronous I/O\n") + "Use non-blocking, synchronous I/O (may lose msgs if file write buffer becomes full) (default)\n" + "Use blocking, synchronous I/O (only for debug purposes or when blocking is acceptable)\n" + "Use Tx workqueue, asynchronous I/O (may lose msgs if queue becomes full)\n") { struct log_target *tgt; + bool wq_mode = argc > 0 && (strcmp(argv0, "wq") == 0); + bool blocking_io = argc > 0 && (strcmp(argv0, "blocking-io") == 0); log_tgt_mutex_lock(); tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL); @@ -877,10 +908,12 @@ log_add_target(tgt); } - if (argc > 0 && !strcmp(argv0, "blocking-io")) - log_target_file_switch_to_stream(tgt); - else + if (wq_mode) { log_target_file_switch_to_wqueue(tgt); + } else { + log_target_file_switch_to_stream(tgt); + log_target_file_set_nonblock(tgt, blocking_io ? 0 : 1); + } vty->index = tgt; vty->node = CFG_LOG_NODE; @@ -908,11 +941,15 @@ } DEFUN(cfg_log_file, cfg_log_file_cmd, - "log file FILENAME blocking-io", + "log file FILENAME (nonblocking-io|blocking-io|wq)", LOG_STR "Logging to text file\n" "Filename\n" - "Use blocking, synchronous I/O\n") + "Use non-blocking, synchronous I/O (may lose msgs if file write buffer becomes full) (default)\n" + "Use blocking, synchronous I/O (only for debug purposes or when blocking is acceptable)\n" + "Use Tx workqueue, asynchronous I/O (may lose msgs if queue becomes full)\n") { const char *fname = argv0; + bool wq_mode = argc > 1 && (strcmp(argv1, "wq") == 0); + bool blocking_io = argc > 1 && (strcmp(argv1, "blocking-io") == 0); struct log_target *tgt; log_tgt_mutex_lock(); @@ -927,10 +964,12 @@ log_add_target(tgt); } - if (argc > 1 && !strcmp(argv1, "blocking-io")) - log_target_file_switch_to_stream(tgt); - else + if (wq_mode) { log_target_file_switch_to_wqueue(tgt); + } else { + log_target_file_switch_to_stream(tgt); + log_target_file_set_nonblock(tgt, blocking_io ? 0 : 1); + } vty->index = tgt; vty->node = CFG_LOG_NODE; @@ -1005,10 +1044,51 @@ RET_WITH_UNLOCK(CMD_SUCCESS); } +#if defined(__EMSCRIPTEN__) +DEFUN(cfg_log_emscripten, cfg_log_emscripten_cmd, + "log emscripten", + LOG_STR "Logging via EMSCRIPTEN\n") +{ + struct log_target *tgt; + + log_tgt_mutex_lock(); + tgt = log_target_create_emscripten(); + if (!tgt) { + vty_out(vty, "%% Unable to create EMSCRIPTEN log target%s", VTY_NEWLINE); + RET_WITH_UNLOCK(CMD_WARNING); + } + log_add_target(tgt); + + vty->index = tgt; + vty->node = CFG_LOG_NODE; + + RET_WITH_UNLOCK(CMD_SUCCESS); +} + +DEFUN(cfg_no_log_emscripten, cfg_no_log_emscripten_cmd, + "no log emscripten", + NO_STR LOG_STR "Logging via EMSCRIPTEN\n")
View file
libosmocore_1.12.1.tar.xz/src/vty/telnet_interface.c -> libosmocore_1.13.0.tar.xz/src/vty/telnet_interface.c
Changed
@@ -248,10 +248,10 @@ switch (event) { case VTY_READ: - bfd->when |= OSMO_FD_READ; + osmo_fd_read_enable(bfd); break; case VTY_WRITE: - bfd->when |= OSMO_FD_WRITE; + osmo_fd_write_enable(bfd); break; case VTY_CLOSED: /* vty layer is about to free() vty */
View file
libosmocore_1.12.1.tar.xz/tests/logging/logging_test.c -> libosmocore_1.13.0.tar.xz/tests/logging/logging_test.c
Changed
@@ -16,6 +16,7 @@ */ #include <osmocom/core/logging.h> +#include <osmocom/core/select.h> #include <osmocom/core/utils.h> #include <stdlib.h> @@ -138,5 +139,8 @@ log_set_print_filename_pos(stderr_target, LOG_FILENAME_POS_LINE_END); DEBUGP(DLGLOBAL, "A message with source info printed last\n"); + for (int i = 0; i < 20; i++) + osmo_select_main(1); + return 0; }
View file
libosmocore_1.12.1.tar.xz/tests/logging/logging_test.err -> libosmocore_1.13.0.tar.xz/tests/logging/logging_test.err
Changed
@@ -7,5 +7,5 @@ DLGLOBAL You should see this on DLGLOBAL (d) DLGLOBAL You should see this on DLGLOBAL (e) DLGLOBAL You should see this (DLGLOBAL on DEBUG) -DLGLOBAL logging_test.c:137 A message with source info printed first -DLGLOBAL A message with source info printed last (logging_test.c:139) +DLGLOBAL logging_test.c:138 A message with source info printed first +DLGLOBAL A message with source info printed last (logging_test.c:140)
View file
libosmocore_1.12.1.tar.xz/tests/logging/logging_vty_test.vty -> libosmocore_1.13.0.tar.xz/tests/logging/logging_vty_test.vty
Changed
@@ -2,7 +2,7 @@ logging_vty_test# show running-config ... -log stderr +log stderr wq ... !logging level all logging level aa debug logging level bb info
View file
libosmocore_1.12.1.tar.xz/tests/osmo_io/osmo_io_test.c -> libosmocore_1.13.0.tar.xz/tests/osmo_io/osmo_io_test.c
Changed
@@ -18,6 +18,9 @@ * */ +#define _GNU_SOURCE +#include <fcntl.h> + #include <stdio.h> #include <stdint.h> #include <stdbool.h> @@ -352,6 +355,295 @@ osmo_select_main(1); } +static int segmentation_uint16_max_segmentation_cb_return_val = 4; +int segmentation_uint16_max_segmentation_cb(struct osmo_io_fd *iofd, struct msgb *msg) +{ + printf("%s: %s() returning %d\n", osmo_iofd_get_name(iofd), __func__, segmentation_uint16_max_segmentation_cb_return_val); + return segmentation_uint16_max_segmentation_cb_return_val; +} + +static int segmentation_uint16_max_read_cb_bytes_read = 0; +static void segmentation_uint16_max_read_cb(struct osmo_io_fd *iofd, int rc, struct msgb *msg) +{ + printf("%s: %s() msg with rc=%d msgb_len=%d completed=%u\n", osmo_iofd_get_name(iofd), __func__, rc, + msg ? msgb_length(msg) : -1, segmentation_uint16_max_read_cb_bytes_read); + if (rc < 0) { + printf("%s: error: %s\n", osmo_iofd_get_name(iofd), strerror(-rc)); + OSMO_ASSERT(0); + } + if (rc == 0) { + file_eof_read = true; + osmo_iofd_unregister(iofd); + } + if (msg) { + segmentation_uint16_max_read_cb_bytes_read += msgb_length(msg); + talloc_free(msg); + } +} + +static void test_segmentation_uint16_max(unsigned segment_len, unsigned msgb_alloc_info_len, unsigned msg_alloc_info_headroom) +{ + struct osmo_io_fd *iofd; + struct msgb *msg; + int fd2 = { 0, 0 }; + int rc; + struct osmo_io_ops ioops; + + const unsigned num_write_msgs = 3; + const unsigned num_write_bytes = UINT16_MAX * num_write_msgs; + + TEST_START(); + + /* Create pipe */ + rc = pipe(fd); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(fd0); + OSMO_ASSERT(fd1); + + int pipe_size = num_write_bytes; + rc = fcntl(fd0, F_SETPIPE_SZ, pipe_size); + OSMO_ASSERT(rc >= num_write_bytes); + + /* First test writing to the pipe: */ + printf("Enable write\n"); + ioops = (struct osmo_io_ops){ .write_cb = file_write_cb }; + iofd = osmo_iofd_setup(ctx, fd1, "seg_iofd", OSMO_IO_FD_MODE_READ_WRITE, &ioops, NULL); + osmo_iofd_register(iofd, fd1); + + for (unsigned int i = 0; i < num_write_msgs; i++) { + msg = msgb_alloc(UINT16_MAX, "Test data"); + memset(msgb_put(msg, UINT16_MAX), 0x2b, UINT16_MAX); + osmo_iofd_write_msgb(iofd, msg); + } + /* Allow enough cycles to handle the messages */ + file_bytes_write_compl = 0; + for (int i = 0; i < 128; i++) { + OSMO_ASSERT(file_bytes_write_compl <= num_write_bytes); + if (file_bytes_write_compl == num_write_bytes) + break; + osmo_select_main(1); + usleep(100 * 1000); + } + fflush(stdout); + OSMO_ASSERT(file_bytes_write_compl == num_write_bytes); + + osmo_iofd_close(iofd); + + /* Now, re-configure iofd to only read from the pipe. + * Reduce the read buffer size, to verify correct segmentation operation: */ + printf("Enable read\n"); + osmo_iofd_set_alloc_info(iofd, msgb_alloc_info_len, msg_alloc_info_headroom); + osmo_iofd_register(iofd, fd0); + ioops = (struct osmo_io_ops){ .read_cb = segmentation_uint16_max_read_cb, + .segmentation_cb2 = segmentation_uint16_max_segmentation_cb }; + rc = osmo_iofd_set_ioops(iofd, &ioops); + segmentation_uint16_max_read_cb_bytes_read = 0; + segmentation_uint16_max_segmentation_cb_return_val = segment_len; + OSMO_ASSERT(rc == 0); + /* Allow enough cycles to handle the messages. */ + file_bytes_read = 0; + file_eof_read = false; + for (int i = 0; i < 128; i++) { + if (file_eof_read) + break; + for (int j = 0; j < 10; j++) + osmo_select_main(1); + usleep(100 * 1000); + } + fflush(stdout); + OSMO_ASSERT(file_eof_read); + + osmo_iofd_free(iofd); + + for (int i = 0; i < 128; i++) + osmo_select_main(1); +} + +unsigned segmentation_cb_requests_segment_too_big_segmentation_cb_headroom; +int segmentation_cb_requests_segment_too_big_segmentation_cb(struct osmo_io_fd *iofd, struct msgb *msg) +{ + int req_segment_size = UINT16_MAX + 1 - segmentation_cb_requests_segment_too_big_segmentation_cb_headroom; + printf("%s: %s() returning %d\n", osmo_iofd_get_name(iofd), __func__, req_segment_size); + return req_segment_size; +} + +static void segmentation_cb_requests_segment_too_big_read_cb(struct osmo_io_fd *iofd, int rc, struct msgb *msg) +{ + printf("%s: %s() msg with rc=%d msgb_len=%d error: %s\n", osmo_iofd_get_name(iofd), __func__, rc, + msg ? msgb_length(msg) : -1, strerror(-rc)); + OSMO_ASSERT(rc == -EPROTO); + if (msg) + talloc_free(msg); + + file_eof_read = true; + osmo_iofd_close(iofd); +} + +/* Test that a user's segment_cb requesting segments bigger than what we allow +* per struct msgb are translated to read_cb(rc=-EPROTO): */ +static void test_segmentation_cb_requests_segment_too_big(unsigned msgb_alloc_info_headroom) +{ + struct osmo_io_fd *iofd; + struct msgb *msg; + int fd2 = { 0, 0 }; + int rc; + struct osmo_io_ops ioops; + + const unsigned num_write_msgs = 3; + const unsigned num_write_bytes = UINT16_MAX * num_write_msgs; + + TEST_START(); + + /* Create pipe */ + rc = pipe(fd); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(fd0); + OSMO_ASSERT(fd1); + + int pipe_size = num_write_bytes; + rc = fcntl(fd0, F_SETPIPE_SZ, pipe_size); + OSMO_ASSERT(rc >= num_write_bytes); + + /* First test writing to the pipe: */ + printf("Enable write\n"); + ioops = (struct osmo_io_ops){ .write_cb = file_write_cb }; + iofd = osmo_iofd_setup(ctx, fd1, "seg_iofd", OSMO_IO_FD_MODE_READ_WRITE, &ioops, NULL); + osmo_iofd_register(iofd, fd1); + + for (unsigned int i = 0; i < num_write_msgs; i++) { + msg = msgb_alloc(UINT16_MAX, "Test data"); + memset(msgb_put(msg, UINT16_MAX), 0x2b, UINT16_MAX); + osmo_iofd_write_msgb(iofd, msg); + } + /* Allow enough cycles to handle the messages */ + file_bytes_write_compl = 0; + for (int i = 0; i < 128; i++) { + OSMO_ASSERT(file_bytes_write_compl <= num_write_bytes); + if (file_bytes_write_compl == num_write_bytes) + break; + osmo_select_main(1); + usleep(100 * 1000); + } + fflush(stdout); + OSMO_ASSERT(file_bytes_write_compl == num_write_bytes); + + osmo_iofd_close(iofd); + + /* Now, re-configure iofd to only read from the pipe. + * Reduce the read buffer size, to verify correct segmentation operation: */ + printf("Enable read\n"); + osmo_iofd_set_alloc_info(iofd, 16000, msgb_alloc_info_headroom); + segmentation_cb_requests_segment_too_big_segmentation_cb_headroom = msgb_alloc_info_headroom; + osmo_iofd_register(iofd, fd0); + ioops = (struct osmo_io_ops){ .read_cb = segmentation_cb_requests_segment_too_big_read_cb, + .segmentation_cb2 = segmentation_cb_requests_segment_too_big_segmentation_cb }; + rc = osmo_iofd_set_ioops(iofd, &ioops); + OSMO_ASSERT(rc == 0); + /* Allow enough cycles to handle the messages. */ + file_bytes_read = 0;
View file
libosmocore_1.13.0.tar.xz/tests/osmo_io/osmo_io_test.err
Added
@@ -0,0 +1,3 @@ +ERROR iofd(seg_iofd) Rx segment msgb of > 65535 bytes (headroom 0 bytes) is unsupported, check your segment_cb! +ERROR iofd(seg_iofd) Rx segment msgb of > 65215 bytes (headroom 320 bytes) is unsupported, check your segment_cb! +ERROR iofd(seg_iofd) segmentation_cb returned error (-105), skipping msg of size 6
View file
libosmocore_1.12.1.tar.xz/tests/osmo_io/osmo_io_test.ok -> libosmocore_1.13.0.tar.xz/tests/osmo_io/osmo_io_test.ok
Changed
@@ -35,3 +35,309 @@ 09 0a 0b 0c tailroom = 2 seg_iofd: read() msg with rc=0 +Running test_segmentation_uint16_max +Enable write +seg_iofd: write() returned rc=65535 +2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +seg_iofd: write() returned rc=65535 +2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +seg_iofd: write() returned rc=65535 +2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Enable read +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=0 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=20000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=30000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=40000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=50000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=60000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=70000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=80000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=90000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=100000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=110000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=120000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=130000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=140000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=150000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=160000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=170000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65535 msgb_len=10000 completed=180000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=0 msgb_len=0 completed=190000 +Running test_segmentation_uint16_max +Enable write +seg_iofd: write() returned rc=65535 +2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +seg_iofd: write() returned rc=65535 +2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +seg_iofd: write() returned rc=65535 +2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Enable read +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=0 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=20000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=30000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=40000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=50000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=60000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=70000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=80000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=90000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=100000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=110000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=120000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=130000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=140000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=150000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=160000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=170000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=65215 msgb_len=10000 completed=180000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=0 msgb_len=0 completed=190000 +Running test_segmentation_uint16_max +Enable write +seg_iofd: write() returned rc=65535 +2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +seg_iofd: write() returned rc=65535 +2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +seg_iofd: write() returned rc=65535 +2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b +Enable read +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=3000 msgb_len=10000 completed=0 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=3000 msgb_len=10000 completed=10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=3000 msgb_len=10000 completed=20000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=3000 msgb_len=10000 completed=30000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=3000 msgb_len=10000 completed=40000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=3000 msgb_len=10000 completed=50000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=3000 msgb_len=10000 completed=60000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=3000 msgb_len=10000 completed=70000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=3000 msgb_len=10000 completed=80000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=3000 msgb_len=10000 completed=90000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000 +seg_iofd: segmentation_uint16_max_read_cb() msg with rc=3000 msgb_len=10000 completed=100000 +seg_iofd: segmentation_uint16_max_segmentation_cb() returning 10000
View file
libosmocore_1.12.1.tar.xz/tests/vty/vty_transcript_test.c -> libosmocore_1.13.0.tar.xz/tests/vty/vty_transcript_test.c
Changed
@@ -218,6 +218,17 @@ return CMD_SUCCESS; } +DEFUN(multi4, multi4_cmd, + "multi4 (foo|bar) (one|two|three)", + "multi4 test command\n" "foo\nbar\n" "1\n2\n3\n") +{ + vty_out(vty, "ok argc=%d%s%s%s%s%s", argc, + argc > 0 ? " " : "", argc > 0 ? argv0 : "", + argc > 1 ? " " : "", argc > 1 ? argv1 : "", + VTY_NEWLINE); + return CMD_SUCCESS; +} + #define X(f) (1 << f) enum { @@ -392,6 +403,7 @@ install_element_ve(&multi1_cmd); install_element_ve(&multi2_cmd); install_element_ve(&multi3_cmd); + install_element_ve(&multi4_cmd); install_element(CONFIG_NODE, &cfg_attr_test_cmd); install_node(&attr_test_node, NULL);
View file
libosmocore_1.12.1.tar.xz/tests/vty/vty_transcript_test.vty -> libosmocore_1.13.0.tar.xz/tests/vty/vty_transcript_test.vty
Changed
@@ -4,6 +4,7 @@ multi1 (one|two|three) multi2 (one|two|three) multi3 (foo|bar) (one|two|three) + multi4 (foo|bar) (one|two|three) vty_transcript_test> multi0 ? one 1 @@ -89,6 +90,27 @@ vty_transcript_test> multi3 bar three ok argc=2 bar three +vty_transcript_test> multi4 ? + foo foo + bar bar + +vty_transcript_test> multi4 foo ? + one 1 + two 2 + three 3 + +vty_transcript_test> multi4 foo +ok argc=1 foo + +vty_transcript_test> multi4 bar +ok argc=1 bar + +vty_transcript_test> multi4 foo one +ok argc=2 foo one + +vty_transcript_test> multi3 bar three +ok argc=2 bar three + vty_transcript_test> multi0 thr ok argc=1 three @@ -101,6 +123,9 @@ vty_transcript_test> multi3 foo t % Ambiguous command. +vty_transcript_test> multi4 foo t +% Ambiguous command. + vty_transcript_test> single0 one ok argc=1 one
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.