Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing Fanotify APIs from the libc crate into Nix. #2552

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

carlvoller
Copy link

@carlvoller carlvoller commented Dec 1, 2024

What does this PR do

Adds support for nix to receive additional Fanotify information records (such as libc::fanotify_event_info_fid, libc::fanotify_event_info_error and libc::fanotify_event_info_pidfd)
Adds abstractions over the new fanotify structs.
Adds new InitFlags to allow receiving these new information records.

This closes #2551

Checklist:

  • I have read CONTRIBUTING.md
  • I have written necessary tests and rustdoc comments
  • A change log has been added if this PR modifies nix's API

@carlvoller
Copy link
Author

I'm not very sure whats going on with the solaris CI failure, but the test that is failing sys::test_uio::test_writev doesn't look related to the changes I've made.

Some guidance would be really appreciated 👍

@SteveLauC SteveLauC self-requested a review December 1, 2024 11:15
@SteveLauC
Copy link
Member

Hi @psumbera, could you please take a look at the Solaris CI failure? It failed in this line

let written = write_res.expect("couldn't write");

  ---- sys::test_uio::test_writev stdout ----
  thread 'sys::test_uio::test_writev' panicked at test/sys/test_uio.rs:48:29:
  couldn't write: EINVAL

@psumbera
Copy link
Contributor

psumbera commented Dec 1, 2024

Hi @psumbera, could you please take a look at the Solaris CI failure? It failed in this line

let written = write_res.expect("couldn't write");

  ---- sys::test_uio::test_writev stdout ----
  thread 'sys::test_uio::test_writev' panicked at test/sys/test_uio.rs:48:29:
  couldn't write: EINVAL

I have seen this one. Seems that this one can fail randomly.

I will create PR to disable this test for Solaris. Sorry about that!

@SteveLauC
Copy link
Member

Sorry about that!

No need to be sorry:)

I will create PR to disable this test for Solaris

Thanks, I will create an issue for this.

@SteveLauC
Copy link
Member

I'm not very sure whats going on with the solaris CI failure, but the test that is failing sys::test_uio::test_writev doesn't look related to the changes I've made.

This test has been disabled, you can rebase your branch to fix the CI:)

@carlvoller
Copy link
Author

Alright, just rebased 👍

@carlvoller
Copy link
Author

Hey any chance could this be merged soon? I would like to use these new features in another package I'm making.

/// Allows the receipt of events which contain additional information
/// about the underlying filesystem object correlated to an event.
///
/// This will make `FanotifyEvent::fd` return `FAN_NOFD`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// This will make `FanotifyEvent::fd` return `FAN_NOFD`.
/// This will make [`FanotifyEvent::fd()`] return `None`.

current_event_offset += header.len as usize;
}

// libc::fanotify_event_info_header
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An unused comment

Comment on lines 351 to 352
// Other fanotify_event_info records are not implemented as they don't exist in
// the libc crate yet.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emm, do we have any other types of information records? All the information record types mentioned in the man page are listed here, though the Linux kernel could add more in the future, which means this enum should be #[non_exhaustive]

/// Allows the receipt of events which contain additional information
/// about the underlying filesystem object correlated to an event.
///
/// This will make `FanotifyEvent::fd` return `FAN_NOFD`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here:

Suggested change
/// This will make `FanotifyEvent::fd` return `FAN_NOFD`.
/// This will make [`FanotifyEvent::fd()`] return `None`.

/// information record received via [`Fanotify::read_events_with_info_records`].
#[derive(Debug, Eq, Hash, PartialEq)]
#[repr(transparent)]
#[allow(missing_copy_implementations)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not Copy?

Comment on lines +623 to +624
// This isn't found in the fanotify(7) documentation, but the fanotify_init(2) documentation
// https://man7.org/linux/man-pages/man2/fanotify_init.2.html
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean types FAN_EVENT_INFO_TYPE_NEW_DFID_NAME and FAN_EVENT_INFO_TYPE_OLD_DFID_NAME?


Some(FanotifyInfoRecord::Fid(FanotifyFidRecord {
record: LibcFanotifyFidRecord(record),
handle_bytes: file_handle_ptr,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a dangling pointer as it comes from buffer, which belongs to the current function frame

Comment on lines 616 to 619
.get_struct::<libc::fanotify_event_info_header>(
&buffer,
current_event_offset,
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible, I hope we can inspect the header without doing any copy

/// The specific info_type for this Fid Record. Fanotify can return an Fid Record
/// with many different possible info_types. The info_type is not always necessary
/// but can be useful for connecting similar events together (like a FAN_RENAME)
pub fn info_type(&self) -> u8 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be nice to have an enum for the info type:

libc_enum! {
    #[repr(u8)]
    #[non_exhaustive]
    enum FanEventInfoType {
        FAN_EVENT_INFO_TYPE_FID,
        FAN_EVENT_INFO_TYPE_DFID,
        FAN_EVENT_INFO_TYPE_DFID_NAME,
        FAN_EVENT_INFO_TYPE_OLD_DFID_NAME,
        FAN_EVENT_INFO_TYPE_NEW_DFID_NAME,
    }
}

@SteveLauC
Copy link
Member

Hey any chance could this be merged soon? I would like to use these new features in another package I'm making.

Sorry for the late review, my non-working hours are quite limited due to my current full-time job, so I have been struggling to balance the few things I need to complete during that time.

Just did a round of review, I think tomorrow I will take a closer look

@carlvoller
Copy link
Author

Hi Steve,

I really appreciate you taking the time to review the code. I've just made a number of changes that should fix all of your concerns and comments above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add libc fanotify information record structs and enums into nix.
3 participants