ipfixcol2 icon indicating copy to clipboard operation
ipfixcol2 copied to clipboard

Add support for Musl libc

Open staehle opened this issue 5 years ago • 2 comments

Hello: Most new embedded OSes use Musl as their C library. Musl does not support the "pthread_rwlockattr_setkind_np()" function and "PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP" definition.

This is the relevant log in our build system that is failing:

[ 75%] Building CXX object src/plugins/output/json/CMakeFiles/json-output.dir/src/File.cpp.o
cd /mnt/ipfixcol2/ipfixcol2-2.1.0/src/plugins/output/json && /usr/bin/ccache /opt/toolchains/bin/x86_64-openwrt-linux-musl-g++  -Djson_output_EXPORTS -I/mnt/ipfixcol2/ipfixcol2-2.1.0/include -I/mnt/ipfixcol2/ipfixcol2-2.1.0/src -I/mnt/ipfixcol2/.odedeps/usr/include  -Os -pipe -fno-caller-saves -g3 -rdynamic -fhonour-copts -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -Wno-error=unused-const-variable -I/opt/toolchains/include -I/mnt/ipfixcol2/.odedeps/usr/include -I/opt/toolchains/x86_64-openwrt-linux-musl/include -fvisibility=hidden -std=gnu++11 -O2 -DNDEBUG -fPIC   -o CMakeFiles/json-output.dir/src/File.cpp.o -c /mnt/ipfixcol2/ipfixcol2-2.1.0/src/plugins/output/json/src/File.cpp
/mnt/ipfixcol2/ipfixcol2-2.1.0/src/plugins/output/json/src/File.cpp: In constructor 'File::File(const cfg_file&, ipx_ctx_t*)':
/mnt/ipfixcol2/ipfixcol2-2.1.0/src/plugins/output/json/src/File.cpp:113:46: error: 'PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP' was not declared in this scope
     if (pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) != 0) {
                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/mnt/ipfixcol2/ipfixcol2-2.1.0/src/plugins/output/json/src/File.cpp:113:9: error: 'pthread_rwlockattr_setkind_np' was not declared in this scope
     if (pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) != 0) {
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/mnt/ipfixcol2/ipfixcol2-2.1.0/src/plugins/output/json/src/File.cpp:113:9: note: suggested alternative: 'pthread_rwlockattr_setpshared'
     if (pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) != 0) {
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         pthread_rwlockattr_setpshared
/mnt/ipfixcol2/ipfixcol2-2.1.0/src/plugins/output/json/src/File.cpp: In static member function 'static int File::dir_create(ipx_ctx_t*, const string&)':
/mnt/ipfixcol2/ipfixcol2-2.1.0/src/plugins/output/json/src/File.cpp:344:45: error: invalid conversion from 'int' to 'const char*' [-fpermissive]
             const char *err_str = strerror_r(errno, buffer, 128);
                                   ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
/mnt/ipfixcol2/ipfixcol2-2.1.0/src/plugins/output/json/src/File.cpp:359:45: error: invalid conversion from 'int' to 'const char*' [-fpermissive]
             const char *err_str = strerror_r(errno, buffer, 128);
                                   ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
/mnt/ipfixcol2/ipfixcol2-2.1.0/src/plugins/output/json/src/File.cpp: In static member function 'static void* File::file_create(ipx_ctx_t*, const string&, const string&, const time_t&, calg)':
/mnt/ipfixcol2/ipfixcol2-2.1.0/src/plugins/output/json/src/File.cpp:421:41: error: invalid conversion from 'int' to 'const char*' [-fpermissive]
         const char *err_str = strerror_r(errno, buffer, 128);
                               ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
make[2]: *** [src/plugins/output/json/CMakeFiles/json-output.dir/src/File.cpp.o] Error 1
src/plugins/output/json/CMakeFiles/json-output.dir/build.make:158: recipe for target 'src/plugins/output/json/CMakeFiles/json-output.dir/src/File.cpp.o' failed
make[2]: Leaving directory '/mnt/ipfixcol2/ipfixcol2-2.1.0'
make[1]: *** [src/plugins/output/json/CMakeFiles/json-output.dir/all] Error 2
CMakeFiles/Makefile2:650: recipe for target 'src/plugins/output/json/CMakeFiles/json-output.dir/all' failed
make[1]: Leaving directory '/mnt/ipfixcol2/ipfixcol2-2.1.0'
make: *** [all] Error 2
Makefile:129: recipe for target 'all' failed

There is a similar resolved issue for CESNET's libnetconf2 repo: https://github.com/CESNET/libnetconf2/pull/160

It looks like the solution for libnetconf2 was to simply check for that support, and then just #ifdef the entire code block that uses it: https://github.com/CESNET/libnetconf2/pull/160/commits/153fe40bd60499677e825e66501e8601536e0323

Not sure if that would be an appropriate solution for ipfixcol2 or not?

Thanks!

staehle avatar Jun 10 '20 19:06 staehle

Hi, first of all, thank you for the solution suggestion. I think it could work.

However, I discovered that musl library doesn't support another feature - RTLD_DEEPBIND flag used by dlopen() in devel branch of the collector. It is missing in the particular header file. This flag is necessary due to newly added support for export to Kafka and a bug/feature of its librdkafka library. Nevertheless, I recently discovered that the flag is causing some other issues and it's probable that I will change implementation/get rid of it soon. After that musl might be supported.

If you don't need JSON output, you can temporarily fix the issue by disabling build of the JSON plugin in src/plugins/output/CMakeLists.txt.

By the way, how do you want to use IPFIXcol2? Do you want to run the collector directly on embedded devices instead of a server?

Lukas

Lukas955 avatar Jun 15 '20 12:06 Lukas955

Hey, thanks for the response!

I am not actually directly involved in the design process for the application that would use this. I just had this submitted to me as an item to add to our build system. From what I understand though, they would be looking at using IPFIXcol2 specifically for the JSON output, so I do need that :)

For this, I did use your tagged 2.1.0 release. So, if you think just #ifdef'ing out that pthread_rwlockattr_setkind_np function is OK, I can just create a patch for that. I'm doing that right now, and I'm noticing and fixing some other compile issues so I'll just submit a Pull Request when I'm done!

staehle avatar Jun 15 '20 19:06 staehle