CESNET / ipfixcol2

High-performance NetFlow v5/v9 and IPFIX collector (RFC7011)
Other
123 stars 36 forks source link

Add support for Musl libc #34

Open staehle opened 4 years ago

staehle commented 4 years ago

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!

Lukas955 commented 4 years ago

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

staehle commented 4 years ago

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!