Projects
osmocom:latest
libosmocore
Log In
Username
Password
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'; + AC_MSG_ERROR(syslog logging support needs syslog.h header)) + AC_DEFINE(ENABLE_SYSLOG_LOGGING, 1, Enable syslog logging target) +) +AM_CONDITIONAL(ENABLE_SYSLOG_LOGGING, test "x$syslog_logging" = "xyes") +AC_SUBST(ENABLE_SYSLOG_LOGGING) + AC_ARG_ENABLE(systemd_logging, AS_HELP_STRING( --enable-systemd-logging, Build with systemd-journal logging support ), - systemd_logging=$enableval, systemd_logging="no") + systemd_logging=$enableval, systemd_logging=$ENABLE_SYSTEMD_LOGGING_DEFAULT) AS_IF(test "x$systemd_logging" = "xyes", PKG_CHECK_MODULES(SYSTEMD, libsystemd) AC_DEFINE(ENABLE_SYSTEMD_LOGGING, 1, Enable systemd-journal logging target) @@ -260,7 +365,7 @@ --disable-libmnl, Build without netlink socket support via libmnl ), - mnl=$enableval, mnl="yes") + mnl=$enableval, mnl=$ENABLE_LIBMNL_DEFAULT) AS_IF(test "x$mnl" = "xyes", PKG_CHECK_MODULES(LIBMNL, libmnl, AC_SUBST(LIBMNL_PC, libmnl)) AC_DEFINE(ENABLE_LIBMNL, 1, Enable netlink socket support via libmnl) @@ -269,7 +374,7 @@ AC_SUBST(ENABLE_LIBMNL) AC_ARG_ENABLE(libsctp, AS_HELP_STRING(--disable-libsctp, Do not enable socket multiaddr APIs requiring libsctp), - ENABLE_LIBSCTP=$enableval, ENABLE_LIBSCTP="yes") + ENABLE_LIBSCTP=$enableval, ENABLE_LIBSCTP=$ENABLE_LIBSCTP_DEFAULT) AM_CONDITIONAL(ENABLE_LIBSCTP, test x"$ENABLE_LIBSCTP" = x"yes") AS_IF(test "x$ENABLE_LIBSCTP" = "xyes", AC_DEFINE(HAVE_LIBSCTP, 1, Define 1 to enable SCTP support) @@ -291,28 +396,27 @@ ) AC_ARG_ENABLE(sctp-tests, AS_HELP_STRING(--disable-sctp-tests, Do not run socket tests requiring system SCTP support), - ENABLE_SCTP_TESTS=$enableval, ENABLE_SCTP_TESTS="yes") + ENABLE_SCTP_TESTS=$enableval, ENABLE_SCTP_TESTS=$ENABLE_SCTP_TESTS_DEFAULT) AM_CONDITIONAL(ENABLE_SCTP_TESTS, test x"$ENABLE_SCTP_TESTS" = x"yes") AC_ARG_ENABLE(uring-tests, AS_HELP_STRING(--disable-uring-tests, Do not run io_uring tests), - ENABLE_URING_TESTS=$enableval, ENABLE_URING_TESTS="yes") + ENABLE_URING_TESTS=$enableval, ENABLE_URING_TESTS=$ENABLE_URING_TESTS_DEFAULT) AM_CONDITIONAL(ENABLE_URING_TESTS, test x"$ENABLE_URING_TESTS" = x"yes") AC_SUBST(ENABLE_URING_TESTS) -AC_ARG_ENABLE(plugin, - AS_HELP_STRING( - --disable-plugin, - Disable support for dlopen plugins, - ), - enable_plugin=$enableval, enable_plugin="yes") +AC_ARG_ENABLE(plugin, AS_HELP_STRING(--disable-plugin, Disable support for dlopen plugins,), + enable_plugin=$enableval, enable_plugin=$ENABLE_PLUGIN_DEFAULT) AM_CONDITIONAL(ENABLE_PLUGIN, test x"$enable_plugin" = x"yes") +AS_IF(test "x$enable_plugin" = "xyes", + AC_DEFINE(ENABLE_PLUGIN, 1, Enable support for dlopen plugins) +) AC_ARG_ENABLE(vty, AS_HELP_STRING( --disable-vty, Disable building VTY telnet interface ), - enable_vty=$enableval, enable_vty="yes") + enable_vty=$enableval, enable_vty=$ENABLE_VTY_DEFAULT) AM_CONDITIONAL(ENABLE_VTY, test x"$enable_vty" = x"yes") AC_ARG_ENABLE(panic_infloop, @@ -320,7 +424,7 @@ --enable-panic-infloop, Trigger infinite loop on panic rather than fprintf/abort ), - panic_infloop=$enableval, panic_infloop="no") + panic_infloop=$enableval, panic_infloop=$ENABLE_PANIC_INFLOOP_DEFAULT) if test x"$panic_infloop" = x"yes" then AC_DEFINE(PANIC_INFLOOP,1,Use infinite loop on panic rather than fprintf/abort) @@ -331,7 +435,7 @@ --enable-ofd-check, Instrument osmo_fd_register to check that the fd is registered ), - fd_check=$enableval, fd_check="no") + fd_check=$enableval, fd_check=$ENABLE_OSMO_FD_CHECK_DEFAULT) if test x"$fd_check" = x"yes" then AC_DEFINE(OSMO_FD_CHECK, 1, Instrument the osmo_fd_register) @@ -342,7 +446,7 @@ --enable-force-io-select, Build with old select I/O instead of poll ), - force_io_select=$enableval, force_io_select="no") + force_io_select=$enableval, force_io_select=$ENABLE_FORCE_IO_SELECT_DEFAULT) AS_IF(test "x$force_io_select" = "xyes", AC_DEFINE(FORCE_IO_SELECT, 1, Force the use of select() instead of poll()) ) @@ -352,7 +456,7 @@ --disable-msgfile, Disable support for the msgfile, ), - enable_msgfile=$enableval, enable_msgfile="yes") + enable_msgfile=$enableval, enable_msgfile=$ENABLE_MSGFILE_DEFAULT) AM_CONDITIONAL(ENABLE_MSGFILE, test x"$enable_msgfile" = x"yes") AC_ARG_ENABLE(serial, @@ -360,7 +464,7 @@ --disable-serial, Disable support for the serial helpers, ), - enable_serial=$enableval, enable_serial="yes") + enable_serial=$enableval, enable_serial=$ENABLE_SERIAL_DEFAULT) AM_CONDITIONAL(ENABLE_SERIAL, test x"$enable_serial" = x"yes") AC_ARG_ENABLE(utilities, @@ -368,7 +472,7 @@ --disable-utilities, Disable building utility programs, ), - enable_utilities=$enableval, enable_utilities="yes") + enable_utilities=$enableval, enable_utilities=$ENABLE_UTILITIES_DEFAULT) AM_CONDITIONAL(ENABLE_UTILITIES, test x"$enable_utilities" = x"yes") AC_ARG_ENABLE(gb, @@ -376,7 +480,7 @@ --disable-gb, Disable building Gb library, ), - enable_gb=$enableval, enable_gb="yes") + enable_gb=$enableval, enable_gb=$ENABLE_GB_DEFAULT) AM_CONDITIONAL(ENABLE_GB, test x"$enable_gb" = x"yes") AC_ARG_ENABLE(ctrl, @@ -384,7 +488,7 @@ --disable-ctrl, Disable building CTRL library, ), - enable_ctrl=$enableval, enable_ctrl="yes") + enable_ctrl=$enableval, enable_ctrl=$ENABLE_CTRL_DEFAULT) AM_CONDITIONAL(ENABLE_CTRL, test x"$enable_ctrl" = x"yes") AC_ARG_ENABLE(pseudotalloc, @@ -392,48 +496,18 @@ --enable-pseudotalloc, Enable building pseudotalloc library, ), - enable_pseudotalloc=$enableval, enable_pseudotalloc="no") + enable_pseudotalloc=$enableval, enable_pseudotalloc=$ENABLE_PSEUDOTALLOC_DEFAULT) AM_CONDITIONAL(ENABLE_PSEUDOTALLOC, test x"$enable_pseudotalloc" = x"yes") - -AC_ARG_ENABLE(embedded, - AS_HELP_STRING( - --enable-embedded, - Enable building for embedded use and disable unsupported features - ), - embedded=$enableval, embedded="no") - -AM_CONDITIONAL(EMBEDDED, false) -AM_CONDITIONAL(ENABLE_SERCOM_STUB, false) - -if test x"$embedded" = x"yes" -then - AC_DEFINE(EMBEDDED,1,Select building for embedded use) - AM_CONDITIONAL(ENABLE_PLUGIN, false) - AM_CONDITIONAL(ENABLE_MSGFILE, false) - AM_CONDITIONAL(ENABLE_SERIAL, false) - AM_CONDITIONAL(ENABLE_GNUTLS, false) - AM_CONDITIONAL(ENABLE_VTY, false) - AM_CONDITIONAL(ENABLE_CTRL, false) - AM_CONDITIONAL(ENABLE_UTILITIES, false) - AM_CONDITIONAL(ENABLE_GB, false) - AM_CONDITIONAL(ENABLE_LIBMNL, false) - AM_CONDITIONAL(ENABLE_LIBSCTP, false) - AM_CONDITIONAL(ENABLE_LIBUSB, false) - AM_CONDITIONAL(ENABLE_PCSC, false) - AM_CONDITIONAL(ENABLE_URING, false) - AM_CONDITIONAL(ENABLE_PSEUDOTALLOC, true) - AM_CONDITIONAL(ENABLE_SERCOM_STUB, true) - AM_CONDITIONAL(EMBEDDED, true) - AC_DEFINE(USE_GNUTLS, 0) - AC_DEFINE(PANIC_INFLOOP,1,Use infinite loop on panic rather than fprintf/abort) -fi +AS_IF(test "x$enable_pseudotalloc" = "xyes", + AC_DEFINE(ENABLE_PSEUDOTALLOC, 1, Enable building pseudotalloc library) +) AC_ARG_ENABLE(log_macros, AS_HELP_STRING( --disable-log-macros, Disable logging macros that are also used internally to print information ), - log_macros="yes", log_macros="no") + log_macros=$enableval, log_macros=$ENABLE_LIBOSMOCORE_NO_LOGGING_DEFAULT) if test x"$log_macros" == x"yes" then AC_DEFINE(LIBOSMOCORE_NO_LOGGING,1,Disable logging macros) @@ -444,7 +518,7 @@ --enable-sanitize, Compile with address sanitizer enabled, ), - sanitize=$enableval, sanitize="no") + sanitize=$enableval, sanitize=$ENABLE_SANITIZE_DEFAULT) if test x"$sanitize" = x"yes" then CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined" @@ -459,7 +533,7 @@ b) "#warning" pragmas (allow to remind ourselves of errors without breaking builds) ), - werror=$enableval, werror="no") + werror=$enableval, werror=$ENABLE_WERROR_DEFAULT) if test x"$werror" = x"yes" then WERROR_FLAGS="-Werror" @@ -473,7 +547,7 @@ AC_ARG_ENABLE(external_tests, AC_HELP_STRING(--enable-external-tests, Include the VTY/CTRL tests in make check default=no), - enable_ext_tests="$enableval",enable_ext_tests="no") + enable_ext_tests="$enableval",enable_ext_tests=$ENABLE_EXT_TESTS_DEFAULT) if test "x$enable_ext_tests" = "xyes" ; then AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmo_verify_transcript_vty.py,yes) if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then @@ -492,7 +566,7 @@ --disable-simd, Disable SIMD support ), - simd=$enableval, simd="yes") + simd=$enableval, simd=$ENABLE_SIMD_SUPPORT_DEFAULT) if test x"$simd" = x"yes" then # Find and define supported SIMD extensions @@ -508,7 +582,7 @@ --enable-neon, Enable ARM NEON instructions support default=no ), - neon=$enableval, neon="no") + neon=$enableval, neon=$ENABLE_NEON_SUPPORT_DEFAULT) AS_IF(test "x$neon" = "xyes", AC_DEFINE(HAVE_NEON,, Support ARM NEON instructions) ) @@ -523,7 +597,7 @@ AC_ARG_ENABLE(systemtap, AS_HELP_STRING(--enable-systemtap, Enable inclusion of systemtap trace support), - ENABLE_SYSTEMTAP="${enableval}", ENABLE_SYSTEMTAP='no') + ENABLE_SYSTEMTAP="${enableval}", ENABLE_SYSTEMTAP=$ENABLE_SYSTEMTAP_DEFAULT) AM_CONDITIONAL(ENABLE_SYSTEMTAP, test x$ENABLE_SYSTEMTAP = xyes) AC_MSG_RESULT(${ENABLE_SYSTEMTAP}) @@ -578,6 +652,12 @@ CHECK_BUILTIN_SUPPORT(__builtin_cpu_supports, Runtime SIMD detection will be disabled) +dnl Check header linux/if_tun.h +AC_CHECK_HEADERS(linux/if_tun.h) + +dnl Check header linux/tcp.h +AC_CHECK_HEADERS(linux/tcp.h) + dnl There are some members in struct tcp_info that might not exist on all linux versions AC_CHECK_MEMBER(struct tcp_info.tcpi_notsent_bytes, AC_DEFINE(HAVE_TCP_INFO_TCPI_NOTSENT_BYTES,
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; +} + +/*! Obtain data associated to a log filter + * \paramin target Log target to be queried + * \paramin log_filter_index the index of the log filter to query + * \returns data associated to the log filter + */ +void *log_get_filter_data(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 NULL; + + if (log_filter_index >= LOG_MAX_FILTERS) + return NULL; + + return target->filter_datalog_filter_index; +} + +/*! Set data associated to a log filter + * \paramin target Log target to be affected + * \paramin log_filter_index the index of the log filter to set associate data for + * \paramin data The user provided data pointer to associate to the log filter + * \returns 0 on success, negative on error. + */ +int log_set_filter_data(struct log_target *target, int log_filter_index, void *data) +{ + /* 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; + + target->filter_datalog_filter_index = data; + return 0; +} + /*! Enable or disable the use of colored output * \paramin target Log target to be affected * \paramin use_color Use color (1) or don't use color (0) @@ -1042,69 +1134,6 @@ #endif } -#if (!EMBEDDED) -/* write-queue tells us we should write another msgb (log line) to the output fd */ -static int _file_wq_write_cb(struct osmo_fd *ofd, struct msgb *msg) -{ - int rc; - - rc = write(ofd->fd, msgb_data(msg), msgb_length(msg)); - if (rc < 0) - return rc; - if (rc != msgb_length(msg)) { - /* pull the number of bytes we have already written */ - msgb_pull(msg, rc); - /* ask write_queue to re-insert the msgb at the head of the queue */ - return -EAGAIN; - } - return 0; -} - -/* 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) -{ - struct msgb *msg; - int rc; - - OSMO_ASSERT(target->tgt_file.wqueue); - msg = msgb_alloc_c(target->tgt_file.wqueue, MAX_LOG_SIZE, "log_file_msg"); - if (!msg) - return; - - /* we simply enqueue the log message to a write queue here, to avoid any blocking - * writes on the output file. The write queue will tell us once the file is writable - * and call _file_wq_write_cb() */ - rc = _output_buf((char *)msgb_data(msg), msgb_tailroom(msg), target, subsys, level, file, line, cont, format, ap); - msgb_put(msg, rc); - - /* attempt a synchronous, non-blocking write, if the write queue is empty */ - if (target->tgt_file.wqueue->current_length == 0) { - rc = _file_wq_write_cb(&target->tgt_file.wqueue->bfd, msg); - if (rc == 0) { - /* the write was complete, we can exit early */ - msgb_free(msg); - return; - } - } - /* if we reach here, either we already had elements in the write_queue, or the synchronous write - * failed: enqueue the message to the write_queue (backlog) */ - if (osmo_wqueue_enqueue_quiet(target->tgt_file.wqueue, msg) < 0) { - msgb_free(msg); - /* TODO: increment some counter so we can see that messages were dropped */ - } -} -#endif - /*! Create a new log target skeleton * \returns dynamically-allocated log target * This funcition allocates a \ref log_target and initializes it @@ -1160,211 +1189,6 @@ return target; } -/*! Create the STDERR log target - * \returns dynamically-allocated \ref log_target for STDERR */ -struct log_target *log_target_create_stderr(void) -{ -/* since C89/C99 says stderr is a macro, we can safely do this! */ -#if !EMBEDDED && defined(stderr) - struct log_target *target; - - target = log_target_create(); - if (!target) - return NULL; - - target->type = LOG_TGT_TYPE_STDERR; - target->tgt_file.out = stderr; - target->output = _file_output_stream; - return target; -#else - return NULL; -#endif /* stderr */ -} - -#if (!EMBEDDED) -/*! Create a new file-based log target using buffered, blocking stream output - * \paramin fname File name of the new log file - * \returns Log target in case of success, NULL otherwise - */ -struct log_target *log_target_create_file_stream(const char *fname) -{ - struct log_target *target; - - target = log_target_create(); - if (!target) - return NULL; - - target->type = LOG_TGT_TYPE_FILE; - target->tgt_file.out = fopen(fname, "a"); - if (!target->tgt_file.out) { - log_target_destroy(target); - return NULL; - } - target->output = _file_output_stream; - target->tgt_file.fname = talloc_strdup(target, fname); - - return target; -} - -/*! switch from non-blocking/write-queue to blocking + buffered stream output - * \paramin target log target which we should switch - * \return 0 on success; 1 if already switched before; negative on error - * Must be called with mutex osmo_log_tgt_mutex held, see log_tgt_mutex_lock. - */ -int log_target_file_switch_to_stream(struct log_target *target) -{ - struct osmo_wqueue *wq; - - if (!target) - return -ENODEV; - - if (target->tgt_file.out) { - /* target has already been switched over */ - return 1; - } - - wq = target->tgt_file.wqueue; - OSMO_ASSERT(wq); - - /* re-open output as stream */ - if (target->type == LOG_TGT_TYPE_STDERR) - target->tgt_file.out = stderr; - else - target->tgt_file.out = fopen(target->tgt_file.fname, "a"); - if (!target->tgt_file.out) { - return -EIO; - } - - /* synchronously write anything left in the queue */ - while (!llist_empty(&wq->msg_queue)) { - struct msgb *msg = msgb_dequeue(&wq->msg_queue); - fwrite(msgb_data(msg), msgb_length(msg), 1, target->tgt_file.out); - msgb_free(msg); - } - - /* now that everything succeeded, we can finally close the old output fd */ - if (target->type == LOG_TGT_TYPE_FILE) { - osmo_fd_unregister(&wq->bfd); - close(wq->bfd.fd); - wq->bfd.fd = -1; - } - - /* release the queue itself */ - talloc_free(wq); - target->tgt_file.wqueue = NULL; - target->output = _file_output_stream; - target->raw_output = NULL; - - return 0; -} - -/*! switch from blocking + buffered file output to non-blocking write-queue based output. - * \paramin target log target which we should switch - * \return 0 on success; 1 if already switched before; negative on error - * Must be called with mutex osmo_log_tgt_mutex held, see log_tgt_mutex_lock. - */ -int log_target_file_switch_to_wqueue(struct log_target *target) -{ - struct osmo_wqueue *wq; - int rc; - - if (!target) - return -ENODEV; - - if (!target->tgt_file.out) { - /* target has already been switched over */ - return 1; - } - - /* we create a ~640kB sized talloc pool within the write-queue to ensure individual - * log lines (stored as msgbs) will not put result in malloc() calls, and also to - * reduce the OOM probability within logging, as the pool is already allocated */ - wq = talloc_pooled_object(target, struct osmo_wqueue, LOG_WQUEUE_LEN, - LOG_WQUEUE_LEN*(sizeof(struct msgb)+MAX_LOG_SIZE)); - if (!wq) - return -ENOMEM; - osmo_wqueue_init(wq, LOG_WQUEUE_LEN); - - fflush(target->tgt_file.out); - if (target->type == LOG_TGT_TYPE_FILE) { - rc = open(target->tgt_file.fname, O_WRONLY|O_APPEND|O_CREAT|O_NONBLOCK, 0660); - if (rc < 0) { - talloc_free(wq); - return -errno; - } - } else { - rc = STDERR_FILENO; - } - wq->bfd.fd = rc; - wq->bfd.when = OSMO_FD_WRITE; - wq->write_cb = _file_wq_write_cb; - - rc = osmo_fd_register(&wq->bfd); - if (rc < 0) { - talloc_free(wq); - return -EIO; - } - target->tgt_file.wqueue = wq; - target->raw_output = _file_raw_output; - target->output = NULL; - - /* now that everything succeeded, we can finally close the old output stream */ - if (target->type == LOG_TGT_TYPE_FILE) - fclose(target->tgt_file.out); - target->tgt_file.out = NULL; - - return 0; -} - -/*! Create a new file-based log target using non-blocking write_queue - * \paramin fname File name of the new log file - * \returns Log target in case of success, NULL otherwise - */ -struct log_target *log_target_create_file(const char *fname) -{ - struct log_target *target; - struct osmo_wqueue *wq; - int rc; - - target = log_target_create(); - if (!target) - return NULL; - - target->type = LOG_TGT_TYPE_FILE; - /* we create a ~640kB sized talloc pool within the write-queue to ensure individual - * log lines (stored as msgbs) will not put result in malloc() calls, and also to - * reduce the OOM probability within logging, as the pool is already allocated */ - wq = talloc_pooled_object(target, struct osmo_wqueue, LOG_WQUEUE_LEN, - LOG_WQUEUE_LEN*(sizeof(struct msgb)+MAX_LOG_SIZE)); - if (!wq) { - log_target_destroy(target); - return NULL; - } - osmo_wqueue_init(wq, LOG_WQUEUE_LEN); - wq->bfd.fd = open(fname, O_WRONLY|O_APPEND|O_CREAT|O_NONBLOCK, 0660); - if (wq->bfd.fd < 0) { - talloc_free(wq); - log_target_destroy(target); - return NULL; - } - wq->bfd.when = OSMO_FD_WRITE; - wq->write_cb = _file_wq_write_cb; - - rc = osmo_fd_register(&wq->bfd); - if (rc < 0) { - talloc_free(wq); - log_target_destroy(target); - return NULL; - } - - target->tgt_file.wqueue = wq; - target->raw_output = _file_raw_output; - target->tgt_file.fname = talloc_strdup(target, fname); - - return target; -} -#endif - /*! Find a registered log target * \paramin type Log target type * \paramin fname File name @@ -1402,38 +1226,19 @@ log_del_target(target); #if (!EMBEDDED) - struct osmo_wqueue *wq; switch (target->type) { case LOG_TGT_TYPE_FILE: case 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; - } - wq = target->tgt_file.wqueue; - if (wq) { - if (wq->bfd.fd >= 0) { - osmo_fd_unregister(&wq->bfd); - if (target->type == LOG_TGT_TYPE_FILE) - close(wq->bfd.fd); - wq->bfd.fd = -1; - } - osmo_wqueue_clear(wq); - talloc_free(wq); - target->tgt_file.wqueue = NULL; - } - talloc_free((void *)target->tgt_file.fname); - target->tgt_file.fname = NULL; + log_target_file_destroy(target); break; case LOG_TGT_TYPE_GSMTAP: gsmtap_source_free(target->tgt_gsmtap.gsmtap_inst); break; -#ifdef HAVE_SYSLOG_H +#ifdef ENABLE_SYSLOG_LOGGING case LOG_TGT_TYPE_SYSLOG: closelog(); break; -#endif /* HAVE_SYSLOG_H */ +#endif /* ENABLE_SYSLOG_LOGGING */ default: /* make GCC happy */ break; @@ -1443,42 +1248,6 @@ talloc_free(target); } -/*! 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_wqueue *wq; - int rc; - - OSMO_ASSERT(target->type == LOG_TGT_TYPE_FILE || target->type == LOG_TGT_TYPE_STDERR); - OSMO_ASSERT(target->tgt_file.out || target->tgt_file.wqueue); - - if (target->tgt_file.out) { - fclose(target->tgt_file.out); - target->tgt_file.out = fopen(target->tgt_file.fname, "a"); - if (!target->tgt_file.out) - return -errno; - } else { - wq = target->tgt_file.wqueue; - if (wq->bfd.fd >= 0) { - osmo_fd_unregister(&wq->bfd); - close(wq->bfd.fd); - wq->bfd.fd = -1; - } - - rc = open(target->tgt_file.fname, O_WRONLY|O_APPEND|O_CREAT|O_NONBLOCK, 0660); - if (rc < 0) - return -errno; - wq->bfd.fd = rc; - rc = osmo_fd_register(&wq->bfd); - if (rc < 0) - return rc; - } - - return 0; -} - /*! close and re-open all log files (for log file rotation) * \returns 0 in case of success; negative otherwise */ int log_targets_reopen(void) @@ -1629,6 +1398,13 @@ /* TODO: The following could/should be cached (update on config) */ + 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 0; + } log_tgt_mutex_lock(); llist_for_each_entry(tar, &osmo_log_target_list, entry) {
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; + + msg = msgb_alloc_c(pool_ctx, MAX_LOG_SIZE, "log_file_msg"); + if (!msg) + return; + + /* we simply enqueue the log message to a write queue here, to avoid any blocking + * writes on the output file. The write queue will tell us once the file is writable + * and call _file_wq_write_cb() */ + rc = log_output_buf((char *)msgb_data(msg), msgb_tailroom(msg), target, subsys, level, + file, line, cont, format, ap); + msgb_put(msg, rc); + + rc = osmo_iofd_write_msgb(iofd, msg); + if (rc < 0) { + msgb_free(msg); + /* TODO: increment some counter so we can see that messages were dropped */ + } +} + +void _log_target_file_setup_talloc_pool(struct log_target *target) +{ + OSMO_ASSERT(target->tgt_file.wqueue && target->tgt_file.wqueue->except_cb); + struct osmo_io_fd *iofd = (struct osmo_io_fd *)target->tgt_file.wqueue->except_cb; + if (osmo_iofd_get_data(iofd)) + return; /* mempool already allocated */ + +#ifndef ENABLE_PSEUDOTALLOC + void *pool_ctx; + /* Allocate a talloc pool to avoid malloc() on the first 156 + * concurrently queued msgbs (~640KB per gsmtap_log target). + * Once the talloc_pool is full, new normal talloc chunks will be used. */ + pool_ctx = _talloc_pooled_object(target, 0, "file_log_msgb_pool", + LOG_WQUEUE_LEN, + (sizeof(struct msgb) + MAX_LOG_SIZE) * LOG_WQUEUE_LEN); + osmo_iofd_set_data(iofd, pool_ctx); +#else + /* talloc pools not supported by pseudotalloc, allocate on usual msgb ctx instead: */ + extern void *tall_msgb_ctx; + osmo_iofd_set_data(iofd, tall_msgb_ctx); +#endif /* ifndef ENABLE_PSEUDOTALLOC */ +} + +/*! switch from non-blocking/write-queue to blocking + buffered stream output + * \paramin target log target which we should switch + * \return 0 on success; 1 if already switched before; negative on error + * Must be called with mutex osmo_log_tgt_mutex held, see log_tgt_mutex_lock. + */ +int log_target_file_switch_to_stream(struct log_target *target) +{ + struct osmo_io_fd *iofd; + unsigned int prev_queue_len; + + if (!target) + return -ENODEV; + + if (target->tgt_file.out) { + /* target has already been switched over */ + return 1; + } + + /* re-open output as stream */ + if (target->type == LOG_TGT_TYPE_STDERR) + target->tgt_file.out = stderr; + else + target->tgt_file.out = fopen(target->tgt_file.fname, "a"); + + if (!target->tgt_file.out) + return -EIO; + + iofd = (struct osmo_io_fd *)target->tgt_file.wqueue->except_cb; + prev_queue_len = osmo_iofd_txqueue_len(iofd); + + /* now that everything succeeded, we can finally close the old iofd */ + osmo_iofd_free(iofd); + 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... */ + /* release the queue itself */ + talloc_free(target->tgt_file.wqueue); + target->tgt_file.wqueue = NULL; + target->output = _file_output_stream; + target->raw_output = NULL; + + + if (prev_queue_len > 0) + LOGP(DLGLOBAL, LOGL_NOTICE, + "Dropped %u messages switching log target file to stream\n", prev_queue_len); + + return 0; +} + +/* Owns fd on success, closes fd on error. */ +int _log_target_file_setup_iofd(struct log_target *target, int fd) +{ + struct osmo_io_fd *iofd; + int rc; + + /* XXX: This wq is only created to keep public log_target fields + * similar. It's not really used anymore internally, other than holding a + * struct osmo_io_fd in wq->except_cb...*/ + target->tgt_file.wqueue = talloc_zero(target, struct osmo_wqueue); + OSMO_ASSERT(target->tgt_file.wqueue); + osmo_wqueue_init(target->tgt_file.wqueue, LOG_WQUEUE_LEN); + + iofd = osmo_iofd_setup(target, fd, target->tgt_file.fname, + OSMO_IO_FD_MODE_READ_WRITE, + &log_target_file_io_ops, NULL); + if (!iofd) { + close(fd); + return -EIO; + } + target->tgt_file.wqueue->except_cb = (int (*)(struct osmo_fd *))iofd; + target->tgt_file.wqueue->bfd.fd = fd; /* Keep public field changes despite not used internally... */ + + _log_target_file_setup_talloc_pool(target); + osmo_iofd_set_txqueue_max_length(iofd, OSMO_MAX(osmo_iofd_get_txqueue_max_length(iofd), LOG_WQUEUE_LEN)); + + /* Request to use 8 write buffers, or less if not as many are available: */ + rc = osmo_iofd_set_io_buffers(iofd, OSMO_IO_OP_WRITE, 0); + rc = osmo_iofd_set_io_buffers(iofd, OSMO_IO_OP_WRITE, OSMO_MIN(rc, 8)); + + rc = osmo_iofd_register(iofd, -1); + if (rc < 0) { + osmo_iofd_free(iofd); + target->tgt_file.wqueue->except_cb = NULL; + target->tgt_file.wqueue->bfd.fd = -1; /* Keep public field changes despite not used internally... */ + talloc_free(target->tgt_file.wqueue); + return -EIO; + } + return 0; +} + +/*! switch from blocking + buffered file output to non-blocking write-queue based output. + * \paramin target log target which we should switch + * \return 0 on success; 1 if already switched before; negative on error + * Must be called with mutex osmo_log_tgt_mutex held, see log_tgt_mutex_lock. + */ +int log_target_file_switch_to_wqueue(struct log_target *target) +{ + int rc, fd; + + if (!target) + return -ENODEV; + + if (!target->tgt_file.out) { + /* target has already been switched over */ + return 1; + } + + fflush(target->tgt_file.out); + if (target->type == LOG_TGT_TYPE_FILE) + fd = open(target->tgt_file.fname, O_WRONLY|O_APPEND|O_CREAT|O_NONBLOCK, 0660); + else /* LOG_TGT_TYPE_STDERR: dup file so we can close it later with osmo_iofd_free() */ + fd = dup(STDERR_FILENO); + + if (fd < 0) + return -errno; + + rc = _log_target_file_setup_iofd(target, fd); + if (rc < 0) + return rc; + + target->raw_output = _file_raw_output; + target->output = NULL; + + /* now that everything succeeded, we can finally close the old output stream */ + if (target->type == LOG_TGT_TYPE_FILE) + fclose(target->tgt_file.out); + target->tgt_file.out = NULL; + + return 0; +} + +/*! Create a new file-based log target using a stream + * \paramin fname File name of the new log file + * \returns Log target in case of success, NULL otherwise + */ +struct log_target *log_target_create_file(const char *fname) +{ + struct log_target *target; + + target = log_target_create(); + if (!target) + return NULL; + + target->type = LOG_TGT_TYPE_FILE; + target->tgt_file.fname = talloc_strdup(target, fname); + OSMO_ASSERT(target->tgt_file.fname); + target->output = _file_output_stream; + + target->tgt_file.out = fopen(target->tgt_file.fname, "a"); + if (!target->tgt_file.out) + goto free_ret; + + return target; + +free_ret: + log_target_destroy(target); + return NULL; +} +#endif + +/*! Create the STDERR log target + * \returns dynamically-allocated \ref log_target for STDERR */ +struct log_target *log_target_create_stderr(void) +{ +/* since C89/C99 says stderr is a macro, we can safely do this! */ +#if !EMBEDDED && defined(stderr) + struct log_target *target; + + target = log_target_create(); + if (!target) + return NULL; + + target->type = LOG_TGT_TYPE_STDERR; + target->tgt_file.out = stderr; + target->output = _file_output_stream; + return target; +#else + return NULL; +#endif /* stderr */ +} + +/* @} */
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: + * iofd->pending is NULL. + * "msg" points to the chunk to be segmented. + * "tail_msg" may contain extra data to be appended and processed later (or NULL). */ + + res = iofd_handle_segmentation(iofd, msg, &iofd->pending); if (res != IOFD_SEG_ACT_DEFER) { /* It it expected as per API spec that we return the * return value of read here. The amount of bytes in msg is * available to the user in msg itself. */ - talloc_steal(iofd->msgb_alloc.ctx, msg); - iofd->io_ops.read_cb(iofd, rc, msg); + _call_read_cb(iofd, rc, msg); /* The user could unregister/close the iofd during read_cb() above. * Once that's done, it doesn't expect to receive any more events, * so discard it: */ - if (!IOFD_FLAG_ISSET(iofd, IOFD_FLAG_FD_REGISTERED)) { - msgb_free(pending); + if (!IOFD_FLAG_ISSET(iofd, IOFD_FLAG_FD_REGISTERED)) + return; + + } else { /* IOFD_SEG_ACT_DEFER */ + if (OSMO_UNLIKELY(errno != EAGAIN)) { + /* Pass iofd->Pending to user app for debugging purposes: */ + msg = iofd->pending; + iofd->pending = NULL; + _call_read_cb(iofd, -errno, iofd->pending); + return; + } + if (OSMO_UNLIKELY(msgb_length(iofd->pending) == iofd_msgb_length_max(iofd))) { + LOGPIO(iofd, LOGL_ERROR, + "Rx segment msgb of > %" PRIu16 " bytes (headroom %u bytes) is unsupported, check your segment_cb!\n", + msgb_length(msg), iofd->msgb_alloc.headroom); + /* Pass iofd->Pending to user app for debugging purposes: */ + msg = iofd->pending; + iofd->pending = NULL; + _call_read_cb(iofd, -EPROTO, msg); return; } } - if (res == IOFD_SEG_ACT_HANDLE_MORE) - msg = pending; - } while (res == IOFD_SEG_ACT_HANDLE_MORE); - - OSMO_ASSERT(iofd->pending == NULL); - iofd->pending = pending; + } while (res == IOFD_SEG_ACT_HANDLE_MORE || OSMO_UNLIKELY(tail_msg)); } /*! completion handler: Internal function called by osmo_io_backend after a given I/O operation has completed @@ -425,7 +493,7 @@ { switch (iofd->mode) { case OSMO_IO_FD_MODE_READ_WRITE: - iofd_handle_segmented_read(iofd, msg, rc); + iofd_handle_segmented_read(iofd, rc, msg); break; case OSMO_IO_FD_MODE_RECVFROM_SENDTO: talloc_steal(iofd->msgb_alloc.ctx, msg); @@ -771,6 +839,7 @@ const struct osmo_io_ops *ioops, void *data) { struct osmo_io_fd *iofd; + osmo_iofd_init(); /* reject unsupported/unknown modes */ switch (mode) { @@ -845,23 +914,27 @@ * * If the osmo_io_fd is in OSMO_IO_FD_MODE_READ_WRITE mode, this API function can be used to tell the * osmo_io proecess how many buffers should be read or written with a single read or write operation. - * This feature is supported with io_uring backend only. * * \paramin iofd the iofd file descriptor * \paramin op the osmo_io_op (read or write) to set the number of IO buffers for * \paramin buffers the number of IO buffer for each specified operation * \returns zero on success, a negative value on error + * + * The minimum valid buffers to set is always 1. + * The maximum valid buffers is implementation defined, and trying to set a + * value greater than the maximum will return an error. + * Passing \ref buffers with a value of 0 can be used to fetch the maximum value allowed. */ int osmo_iofd_set_io_buffers(struct osmo_io_fd *iofd, enum osmo_io_op op, uint8_t buffers) { if (iofd->mode != OSMO_IO_FD_MODE_READ_WRITE) return -EINVAL; - if (g_io_backend != OSMO_IO_BACKEND_IO_URING) + if (buffers > IOFD_MSGHDR_IO_BUFFERS) return -EINVAL; - if (buffers < 1 || buffers > IOFD_MSGHDR_IO_BUFFERS) - return -EINVAL; + if (buffers == 0) + return IOFD_MSGHDR_IO_BUFFERS; switch (op) { case OSMO_IO_OP_READ: @@ -1071,6 +1144,7 @@ */ void osmo_iofd_set_alloc_info(struct osmo_io_fd *iofd, unsigned int size, unsigned int headroom) { + OSMO_ASSERT(size + headroom <= 0xffff); iofd->msgb_alloc.headroom = headroom; iofd->msgb_alloc.size = size; } @@ -1084,6 +1158,16 @@ iofd->tx_queue.max_length = max_length; } + +/*! Get the maximum number of messages enqueued for sending. + * \paramin iofd the file descriptor + * \returns the maximum size of the transmit queue + */ +unsigned int osmo_iofd_get_txqueue_max_length(const struct osmo_io_fd *iofd) +{ + return iofd->tx_queue.max_length; +} + /*! Retrieve the associated user-data from an osmo_io_fd. * * A call to this function will return the opaque user data pointer which was specified previously @@ -1156,6 +1240,24 @@ osmo_talloc_replace_string(iofd, &iofd->name, name); } +/*! Set the human-readable name of the file descriptor using arguments like printf() + * \paramin iofd the file descriptor + * \paramin fmt the fmt to set on the file descriptor */ +void osmo_iofd_set_name_f(struct osmo_io_fd *iofd, const char *fmt, ...) +{ + char *name = NULL; + + if (fmt) { + va_list ap; + + va_start(ap, fmt); + name = talloc_vasprintf(iofd, fmt, ap); + va_end(ap); + } + talloc_free((void *)iofd->name); + iofd->name = name; +} + /*! Set the osmo_io_ops calbacks for an osmo_io_fd. * This function can be used to update/overwrite the call-back functions for the given osmo_io_fd; it * replaces the currently-set call-back function pointers from a previous call to osmo_iofd_set_ioops()
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") +{ + struct log_target *tgt; + + log_tgt_mutex_lock(); + tgt = log_target_find(LOG_TGT_TYPE_EMSCRIPTEN, NULL); + if (tgt == NULL) { + vty_out(vty, "%% Unable to find EMSCRIPTEN log target%s", VTY_NEWLINE); + RET_WITH_UNLOCK(CMD_WARNING); + } + + log_target_destroy(tgt); + + RET_WITH_UNLOCK(CMD_SUCCESS); +} +#endif /* defined(__EMSCRIPTEN__) */ + static int config_write_log_single(struct vty *vty, struct log_target *tgt) { char level_buf128; int i; + char *pars; switch (tgt->type) { case LOG_TGT_TYPE_VTY: @@ -1016,12 +1096,13 @@ break; case LOG_TGT_TYPE_STDERR: if (tgt->tgt_file.wqueue) - vty_out(vty, "log stderr%s", VTY_NEWLINE); + vty_out(vty, "log stderr wq%s", VTY_NEWLINE); else - vty_out(vty, "log stderr blocking-io%s", VTY_NEWLINE); + vty_out(vty, "log stderr%s%s", + log_target_file_get_nonblock(tgt) == 0 ? " blocking-io" : "", VTY_NEWLINE); break; case LOG_TGT_TYPE_SYSLOG: -#ifdef HAVE_SYSLOG_H +#ifdef ENABLE_SYSLOG_LOGGING vty_out(vty, "log syslog %s%s", get_value_string(sysl_level_names, tgt->tgt_syslog.facility), @@ -1030,23 +1111,36 @@ break; case LOG_TGT_TYPE_FILE: if (tgt->tgt_file.wqueue) - vty_out(vty, "log file %s%s", tgt->tgt_file.fname, VTY_NEWLINE); + vty_out(vty, "log file %s wq%s", tgt->tgt_file.fname, VTY_NEWLINE); else - vty_out(vty, "log file %s blocking-io%s", tgt->tgt_file.fname, VTY_NEWLINE); + vty_out(vty, "log file %s%s%s", tgt->tgt_file.fname, + log_target_file_get_nonblock(tgt) == 0 ? " blocking-io" : "", VTY_NEWLINE); break; case LOG_TGT_TYPE_STRRB: vty_out(vty, "log alarms %zu%s", log_target_rb_avail_size(tgt), VTY_NEWLINE); break; case LOG_TGT_TYPE_GSMTAP: - vty_out(vty, "log gsmtap %s%s", - tgt->tgt_gsmtap.hostname, VTY_NEWLINE); + if (gsmtap_source_using_wq(tgt->tgt_gsmtap.gsmtap_inst)) { + pars = " wq"; + } else { + int fd = gsmtap_inst_fd2(tgt->tgt_gsmtap.gsmtap_inst); + if (fd > 0 && !osmo_sock_get_nonblock(fd)) + pars = " blocking-io"; + else + pars = ""; + } + vty_out(vty, "log gsmtap %s%s%s", + tgt->tgt_gsmtap.hostname, pars, VTY_NEWLINE); break; case LOG_TGT_TYPE_SYSTEMD: vty_out(vty, "log systemd-journal%s%s", tgt->sd_journal.raw ? " raw" : "", VTY_NEWLINE); break; + case LOG_TGT_TYPE_EMSCRIPTEN: + vty_out(vty, "log emscripten%s", VTY_NEWLINE); + break; } vty_out(vty, " logging filter all %u%s", @@ -1265,7 +1359,7 @@ install_lib_element(CONFIG_NODE, &cfg_no_log_file_cmd); install_lib_element(CONFIG_NODE, &cfg_log_alarms_cmd); install_lib_element(CONFIG_NODE, &cfg_no_log_alarms_cmd); -#ifdef HAVE_SYSLOG_H +#ifdef ENABLE_SYSLOG_LOGGING install_lib_element(CONFIG_NODE, &cfg_log_syslog_cmd); install_lib_element(CONFIG_NODE, &cfg_log_syslog_local_cmd); install_lib_element(CONFIG_NODE, &cfg_no_log_syslog_cmd); @@ -1274,4 +1368,8 @@ install_lib_element(CONFIG_NODE, &cfg_no_log_systemd_journal_cmd); install_lib_element(CONFIG_NODE, &cfg_log_gsmtap_cmd); install_lib_element(CONFIG_NODE, &cfg_no_log_gsmtap_cmd); +#if defined(__EMSCRIPTEN__) + install_lib_element(CONFIG_NODE, &cfg_log_emscripten_cmd); + install_lib_element(CONFIG_NODE, &cfg_no_log_emscripten_cmd); +#endif /* defined(__EMSCRIPTEN__) */ }
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; + 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); +} + + +int _propagate_segmentation_cb(struct osmo_io_fd *iofd, struct msgb *msg) +{ + printf("%s: segmentation_cb() returning -ENOBUFS\n", osmo_iofd_get_name(iofd)); + return -ENOBUFS; +} + +static void propagate_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 == -ENOBUFS); + if (msg) + talloc_free(msg); + + file_eof_read = true; + osmo_iofd_close(iofd); +} + +/* Test that errors other than EAGAIN are propagated to the user through the read_cb path. */ +static void test_segmentation_cb_propagate_error_to_read_cb(void) +{ + struct osmo_io_fd *iofd; + struct msgb *msg; + uint8_t *buf; + int fd2 = { 0, 0 }; + int rc; + struct osmo_io_ops ioops; + + TEST_START(); + + /* Create pipe */ + rc = pipe(fd); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(fd0); + OSMO_ASSERT(fd1); + + /* 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); + + msg = msgb_alloc(12, "Test data"); + buf = msgb_put(msg, 12); + memcpy(buf, TESTDATA, 12); + 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 <= 12); + if (file_bytes_write_compl == 12) + break; + osmo_select_main(1); + usleep(100 * 1000); + } + fflush(stdout); + OSMO_ASSERT(file_bytes_write_compl == 12); + + 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, 6, 0); + osmo_iofd_register(iofd, fd0); + ioops = (struct osmo_io_ops){ .read_cb = propagate_read_cb, .segmentation_cb2 = _propagate_segmentation_cb }; + rc = osmo_iofd_set_ioops(iofd, &ioops); + OSMO_ASSERT(rc == 0); + /* Allow enough cycles to handle the message. We expect 3 reads, 4th read will return 0. */ + file_bytes_read = 0; + file_eof_read = false; + for (int i = 0; i < 128; i++) { + if (file_eof_read) + break; + 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); +} static const struct log_info_cat default_categories = { }; @@ -369,11 +661,20 @@ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE); log_set_print_category(osmo_stderr_target, 0); log_set_print_category_hex(osmo_stderr_target, 0); + log_set_print_level(osmo_stderr_target, 1); + /* To debug DLIO uncomment line below: */ + /* log_set_category_filter(osmo_stderr_target, DLIO, 1, LOGL_DEBUG); */ test_file(); test_connected(); test_unconnected(); test_segmentation(); + test_segmentation_uint16_max(10000, UINT16_MAX, 0); + test_segmentation_uint16_max(10000, UINT16_MAX - 320, 320); + test_segmentation_uint16_max(10000, 3000, 0); + test_segmentation_cb_requests_segment_too_big(0); + test_segmentation_cb_requests_segment_too_big(320); + test_segmentation_cb_propagate_error_to_read_cb(); return EXIT_SUCCESS; }
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 +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=110000 +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=120000 +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=130000 +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=140000 +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=150000 +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=160000 +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=170000 +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=180000 +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=0 msgb_len=0 completed=190000 +Running test_segmentation_cb_requests_segment_too_big +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_cb_requests_segment_too_big_segmentation_cb() returning 65536 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65536 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65536 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65536 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65536 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65536 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65536 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65536 +seg_iofd: segmentation_cb_requests_segment_too_big_read_cb() msg with rc=-71 msgb_len=65535 error: Protocol error +Running test_segmentation_cb_requests_segment_too_big +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_cb_requests_segment_too_big_segmentation_cb() returning 65216 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65216 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65216 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65216 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65216 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65216 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65216 +seg_iofd: segmentation_cb_requests_segment_too_big_segmentation_cb() returning 65216 +seg_iofd: segmentation_cb_requests_segment_too_big_read_cb() msg with rc=-71 msgb_len=65215 error: Protocol error +Running test_segmentation_cb_propagate_error_to_read_cb +Enable write +seg_iofd: write() returned rc=12 +01 02 03 04 05 06 07 08 09 0a 0b 0c +Enable read +seg_iofd: segmentation_cb() returning -ENOBUFS +seg_iofd: propagate_read_cb() msg with rc=-105 msgb_len=-1 error: No buffer space available
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
.