mikesart / inotify-info

Linux inotify info reporting app
MIT License
298 stars 31 forks source link

Compile fails on Centos7 #10

Closed daniejstriata closed 1 year ago

daniejstriata commented 1 year ago

Hi,

When running make I get failures. I've also tried compiling the code against the Developer Toolset 7..10.

When using g++ (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)

# make
Using gold linker...
Building _release/inotify-info...
---- inotify-info.cpp ----
g++: error: unrecognized command line option ‘-Wimplicit-fallthrough=2’
make: *** [_release/inotify-info.o] Error 1

When using Developer Toolset 9 - g++ (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2)

Using gold linker...
Building _release/inotify-info...
---- inotify-info.cpp ----
inotify-info.cpp:342:67: error: return type ‘struct statx’ is incomplete
  342 | struct statx mystatx( const char *filename, unsigned int mask = 0 )
      |                                                                   ^
inotify-info.cpp: In function ‘void mystatx(const char*, unsigned int)’:
inotify-info.cpp:344:18: error: aggregate ‘statx statxbuf’ has incomplete type and cannot be defined
  344 |     struct statx statxbuf;
      |                  ^~~~~~~~
inotify-info.cpp:345:57: error: ‘AT_STATX_DONT_SYNC’ was not declared in this scope
  345 |     int flags = AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW | AT_STATX_DONT_SYNC;
      |                                                         ^~~~~~~~~~~~~~~~~~
inotify-info.cpp:347:53: error: invalid use of incomplete type ‘struct statx’
  347 |     if ( statx( 0, filename, flags, mask, &statxbuf ) == -1 )
      |                                                     ^
inotify-info.cpp:342:8: note: forward declaration of ‘struct statx’
  342 | struct statx mystatx( const char *filename, unsigned int mask = 0 )
      |        ^~~~~
inotify-info.cpp: In member function ‘void thread_info_t::add_filename(ino64_t, const char*, const char*, bool)’:
inotify-info.cpp:365:22: error: variable ‘statx statxbuf’ has initializer but incomplete type
  365 |         struct statx statxbuf = mystatx( filename.c_str() );
      |                      ^~~~~~~~
inotify-info.cpp: In function ‘uint32_t find_files_in_inode_set(const std::vector<procinfo_t>&, std::vector<filename_info_t>&)’:
inotify-info.cpp:672:53: error: ‘STATX_INO’ was not declared in this scope; did you mean ‘STA_INS’?
  672 |             thread_info.add_filename( mystatx( "/", STATX_INO ).stx_ino, "/", "", false );
      |                                                     ^~~~~~~~~
      |                                                     STA_INS
make: *** [Makefile:107: _release/inotify-info.o] Error 1

It compiled successfully on Rocky 8.

mikesart commented 1 year ago

Do you know what version of the kernel and glibc you're running with? I'm guessing it's old enough that statx just isn't supported? Which I guess we could look at adding a slower non-statx path if really needed. Thanks.

statx() was added to Linux in kernel 4.11; library support was added in glibc 2.28.

daniejstriata commented 1 year ago

@mikesart Thanks for looking, the Centos 7 kernel is still 3.10 and glibc on 2.17. I'm starting to phasing out my Centos 7 hosts this year as it is getting EOLed next year. Closing this off.

drok commented 10 months ago

Would it be possible for the utility to detect when the kernel doesn't support the statx or whatever it requires, and print out an appropriate error?

I tried running it on 2.6.32-042stab120.18 . I had to remove -Wimplicit-fallthrough=2 from the Makefile and compile with make CXX=g++-9 on Ubuntu 16. The build was successful, but when running it, it reports zero inotify handles. I am certain I do have inotify handles open, because lsof -p lists them. strace shows events are handled when the watched files change, and the applications using inotify watches react correctly to file changes.

The problem is that inotify-info output is wrong (shows zero handles):

$ _release/inotify-info -vv
0 ignore_dirs:
------------------------------------------------------------------------------
INotify Limits:
  max_queued_events    16,384
  max_user_instances   128
  max_user_watches     524,288
------------------------------------------------------------------------------
       Pid Uid        App         Watches  Instances
------------------------------------------------------------------------------
Total inotify Watches:   0
Total inotify Instances: 0
------------------------------------------------------------------------------

I appreciate that statx is required, but I, and other users in the future will waste time attempting to use this utility on old systems.

Legacy systems are not going away, and it's good form for new-fangled software like this to fail correctly with 'unsupported kernel' or such message. "Total inotify Watches: 0" is a lie.

Thank you.

mikesart commented 10 months ago

There is this bit of code in inotify-info.cpp:

// statx() was added to Linux in kernel 4.11; library support was added in glibc 2.28.
#if defined( __linux__ ) && ( ( __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 28 ) || ( __GLIBC__ > 2 ) )

Can you change this to be this:

// statx() was added to Linux in kernel 4.11; library support was added in glibc 2.28.
#if 0

And rebuild the app and see if it works?

drok commented 10 months ago

@mikesart, I tried the change you suggested and does not work. The behaviour is unchanged. My system used libc6 2.23-0ubuntu11.3, so the conditional evaluates as false with or without this change.

I looked a bit into the situation, and submitted #19, which implements backwards compatibility to kernel 2.6.32. I have not tested earlier kernels. The stat functions are not called at all on old kernels, because individual watches cannot be resolved; the fdinfo files in /proc do not include the necessary device info (the inotify wd:... line)