Skip to content

API for deleted files / raw FD #317

@tatref

Description

@tatref

Hi,

If a file is deleted while still opened by a process, the fd under /proc/$pid/fd/$fd will show up as

[tatref@srv dev]$ ls -ld /proc/12779/fd/*
lr-x------ 1 tatref tatref 64 Oct 16 01:00 /proc/12779/fd/4 -> '/home/tatref/dev/tes (deleted)'

We can get that info with

use std::fs::File;
use std::fs::Metadata;
use std::os::unix::fs::MetadataExt;

let f = File::open(&format!("/proc/{}/fd/{}", p.pid, fd.fd)).unwrap();
let metadata = f.metadata().unwrap();

if metadata.nlink() == 0 {}

So this means format a String, open a file, and do a syscall to get metadata.

Currently it seems there is no easier API in procfs to access this information (please correct me if I'm wrong).
FDTarget has a Path variant, but there is no guarantee that another file with the same name hasn't be created.

Maybe we could store a File in the FDInfo, and add it where it is created:

fn from_process_at<P: AsRef<Path>, Q: AsRef<Path>>(
base: P,
dirfd: BorrowedFd,
path: Q,
fd: i32,
) -> ProcResult<Self> {
let p = path.as_ref();
let root = base.as_ref().join(p);
// for 2.6.39 <= kernel < 3.6 fstat doesn't support O_PATH see https://github.com/eminence/procfs/issues/265
let flags = match Version::cached() {
Ok(v) if v < KernelVersion::new(3, 6, 0) => OFlags::NOFOLLOW | OFlags::CLOEXEC,
Ok(_) => OFlags::NOFOLLOW | OFlags::PATH | OFlags::CLOEXEC,
Err(_) => OFlags::NOFOLLOW | OFlags::PATH | OFlags::CLOEXEC,
};
let file = wrap_io_error!(root, rustix::fs::openat(dirfd, p, flags, Mode::empty()))?;
let link = rustix::fs::readlinkat(&file, "", Vec::new()).map_err(io::Error::from)?;
let md =
rustix::fs::statat(&file, "", AtFlags::SYMLINK_NOFOLLOW | AtFlags::EMPTY_PATH).map_err(io::Error::from)?;
let link_os = link.to_string_lossy();
let target = FDTarget::from_str(link_os.as_ref())?;
Ok(FDInfo {
fd,
mode: (md.st_mode & Mode::RWXU.bits()) as u16,
target,
})
}

What do you think?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions