Process access file linux

How can I determine what process has a file open in Linux?

I’d like to determine what process has ownership of a lock-file. The lock-files are simply a file with a specific name that has been created. So, how can I determine what process has a particular file open in Linux? Preferably a one-liner type or a particular Linux tool solution would be optimal.

5 Answers 5

You can also use fuser for this:

~> less .vimrc # put in background ~> fuser .vimrc .vimrc: 28135 ~> ps 28135 PID TTY STAT TIME COMMAND 28135 pts/36 T 0:00 less .vimrc 

fuser has strange behavior with exit codes. it returns 1 exitcode with two states: A/ some internal error, checked file not found etc, B/ no process opened specified file. In situation A/ some error message is printed to its output. Unfortunately when file is available and opened by something, output is generated but with exit code 0. It would be better if fuser will exit with three codes, not two like currently. lsoft is a bit worse resolve because this is working more slowly.

This is essentially the same pattern that ls follows — it returns exit code 2 if there’s an error (e.g., invalid option specified) or file not found (and 0 if it successfully reports information).

On most Linux systems lsof NAME does the job:

fin@r2d2:~$ lsof /home/fin COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME bash 21310 fin cwd DIR 8,1 4096 5054467 /home/fin lsof 21320 fin cwd DIR 8,1 4096 5054467 /home/fin lsof 21321 fin cwd DIR 8,1 4096 5054467 /home/fin fin@r2d2:~$ 

@JoseLSegura: I assuming you’re resourceful enough for the answer ‘then install lsof’ to be useless for you. Can you elaborate on your problem? If you don’t have root, you likely don’t have privs to find out if another user has the file open anyhow.

@Jason: it does work for files, but cwd lines (which report use as the current working directory of a process) only report directories.

Having a file open is not a lock because, if each process has to check whether the file is open first and not proceed if it is or create/open it if it isn’t, then two processes could quite well check simultaneously, both find that it isn’t open, then both create or open it.

To use a file as a lock, the check-and-lock operation has to be a single uninterruptable operation. You can achieve this in a Unix filesystem by creating a file with read-only mode and removing it to unlock. If the file exists (and is read only) the file creation will fail, so you get check-and-lock in a single atomic operation.

Читайте также:  Серверы обновления linux ubuntu

If your locking process is a shell script that will be running as a daemon, you can get this effect by using umask , a per-process setting that sets the permissions that new files are created with:

oldumask=$(umask) umask 222 # create files unwritable to owner too if echo $$ > /var/lock/foo then : locking succeeded else : locking failed fi umask $oldumask

This also writes the owning process’ PID into the file, which solves your other problem: cat /var/lock/foo As regards the specific question «Which processes have this file open?», this can be useful when you want to unmount a filesystem but can’t because some process has a file open in it. If you don’t have those commands available, you can ask /proc as root:

ls -l /proc/*/cwd | grep ‘/var/lock/foo$’

ls -l /proc/*/cwd 2>/dev/null | grep ‘/var/lock/foo$’

Источник

Linux: check if process has read access to file in C/C++

Assuming we have some PID and absolute file path [not a symlink, just a regular file] — what is the most efficient way to determine that PID has read access to this file?

Welcome to StackOverflow. Are you really asking for the most efficient method, or will any effective method do? And, if efficiency is your goal, what measure of efficiency are you using?

2 Answers 2

I’m only aware of one way to do this. First, find the UID and GID of the process by constructing the path /proc/ + the PID. For example /proc/4261 . You then stat() that path and get its UID and GID. Then, you stat() the file you want to check for read access and check whether the UID/GID of the process has read permissions:

(It is assumed you already constructed the «/proc/[PID]» path in path_to_proc .)

struct stat buf; // Get UID and GID of the process. stat(path_to_proc, &buf); uid_t proc_uid = buf.st_uid; gid_t proc_gid = buf.st_gid; // Get UID and GID of the file. stat(path_to_file_you_want_to_check, &buf); // If the process owns the file, check if it has read access. if (proc_uid == buf.st_uid && buf.st_mode & S_IRUSR) < // Yes, the process has read access. >// Check if the group of the process's UID matches the file's group // and if so, check for read/write access. else if (proc_gid == buf.st_gid && buf.st_mode & S_IRGRP) < // Yes, the process has read access. >// The process's UID is neither the owner of the file nor does its GID // match the file's. Check whether the file is world readable. else if (buf.st_mode & S_IROTH) < // Yes, the process has read access. >

Note that the code is not perfect. It does not handle the possibility that the user of the process actually belongs to the file’s group without it being the user’s primary group. To deal with that, you will need to make use of getgrouplist() (which means you will need to convert the process UID to a string containing the actual username first, and then compare all returned groups to the file’s group and if one matches, check for group read access (S_IRGRP).)

Читайте также:  Linux quota all users

Источник

Linux — How to track all files accessed by a process?

Is there a way to track all file I/O for a given process? All I really need is the locations of files being read from/written to from a given process (and ideally if it was a read or write operation although that’s not as important). I can run the process and track it rather than needing to attach to an existing process which I would assume is significantly simpler. Is there any kind of wrapper utility I can run a process though that will monitor file access?

4 Answers 4

lsof :

Try doing this as a starter :

this command will list all currently open files, fd, sockets for the process with the passed process ID.

For your special needs, see what I can offer as a solution to monitor a php script :

php foo.php & _pid=$! lsof -r1 -p $_pid kill %1 # if you want to kill php script 

strace :

I recommend the use of strace . Unlike lsof , it stays running for as long as the process is running. It will print out which syscalls are being called when they are called. -e trace=file filters only for syscalls that access the filesystem:

sudo strace -f -t -e trace=file php foo.php 

or for an already running process :

sudo strace -f -t -e trace=file -p

Thanks that’s a good starting point! It works for processes already running at the moment it’s run. I’m trying to do this for a PHP script for its entire execution, tracking the files from the start of the process until it exists. Looking at the help, There’s a -r repeat option but this seems to periodically scan the files that are open by the process rather than have been opened. Essentially I want to do this: lsof -p $$ && exec php foo.php This doesn’t seem to list files that are opened by foo.php

thanks, that’s certainly providing more relevant information and showing all the php extensions being loaded, the script contains unfortunately, file.txt is not listed in the output. I can verify the file is being opened by amending the script to print the contents of file.txt but I still don’t see file.txt in the output of lsof.

Читайте также:  Redmine all in one linux

To properly trace an AppImage, I needed to run strace as root but the command using my own user. This got the job done: sudo strace -fte trace=%file -u $(id -un)

Mixing your two solutions together becomes perfect: php foo.php & sudo strace -f -t -e trace=file -p $! especially for short running tasks.

Besides strace there is another option which does not substantially slow down the monitored process. Using the Liunx kernel’s fanotify (not to be confused with the more popular inotify) it is possible to monitor whole mount-points for IO-activity. With unshared mountnamespaces the mounts of a given process can be isolated fromt the rest of the system (a key technology behind docker).

An implementation of this concept can be found in shournal, which I am the author of.

$ shournal -e sh -c 'cat foo > bar' $ shournal --query --history 1 . 1 written file(s): /home/user/bar 1 read file(s): /home/user/foo 

External links are always highly appreciated as sources, but imagine this one was to become invalid — your solution would be unsalvageable for future SO users. Please consider posting code here and explaining your solution so we all can learn.

@harmonica141: That’s always the problem: what to write and what to omit. A complete, minimal example would be not much shorter than the example at the bottom at man7.org/linux/man-pages/man7/fanotify.7.html . In fact, it could be almost the same with a leading unshare( CLONE_NEWNS); . Do you think it would be helpful to include the full source here?

strace is an amazing tool but its output is a bit verbose.
If you want you can use a tool I’ve written which processes strace output and provide a CSV report of all files accessed (TCP sockets too) with the following data:
1. Filename
2. Read/Written bytes
3. Number of read/write operations
4. Number of time the file was opened

It can be run on new processes or processes already running (using /proc/fd data).
I found it useful for debugging scenarios and performance analysis.
You can find it here: iotrace

Filename, Read bytes, Written bytes, Opened, Read op, Write op /dev/pts/1,1,526512,0,1,8904 socket_127.0.0.1:47948->127.0.0.1:22,1781764,396,0,8905,11 myfile.txt,65,0,9,10,0 pipe:[3339],0,0,0,1,0 

Afterward, you can process the CSV data in Excel or other tools for sorting or other analysis required.
The downside is you need to download & compile and it isn’t always 100% accurate.

Источник

Оцените статью
Adblock
detector