Linux which process is writing to file

How to Find Out Who is Using a File in Linux

In this article, we will explain how to find out who is using a particular file in Linux. This will help you know the system user or process that is using an open file.

We can use the lsof command to know if someone is using a file, and if they are, who. It reads kernel memory in its search for open files and helps you list all open files. In this case, an open file may be a regular file, a directory, a block special file, a character special file, a stream, a network file and many others – because in Linux everything is a file.

Lsof is used on a file system to identify who is using any files on that file system. You can run lsof command on Linux filesystem and the output identifies the owner and process information for processes using the file as shown in the following output.

To list user specific opened files, run the following command replace tecmint with the actual user name.

Another important use of lsof is to find out the process listening on a specific port. For example identify the process listening on port 80 using the following command.

Note: Since lsof reads kernel memory in its search for open files, rapid changes in kernel memory may result into unpredictable outputs. This is one of the major downsides of using lsof command.

For more information, look at the lsof man page:

That’s all! In this article, we have explained how to know who is using a particular file in Linux. We have shown how to identify the owner and process information for processes using an open file. Use the feedback form below to reach us for any questions or comments.

If You Appreciate What We Do Here On TecMint, You Should Consider:

TecMint is the fastest growing and most trusted community site for any kind of Linux Articles, Guides and Books on the web. Millions of people visit TecMint! to search or browse the thousands of published articles available FREELY to all.

If you like what you are reading, please consider buying us a coffee ( or 2 ) as a token of appreciation.

We are thankful for your never ending support.

Источник

How to find which process a file is being written by in Linux?

Some people ask a file is being written by one process and they want to check this process, but they cannot find the process even with sof.

This question is very common and there are many solutions, here we introduce a straightforward method.

In Linux, each file will be stored on one device and of course there will be a relative inode, then we can use vfs.write to know who is writing the inode on one specified device continuously. Luckily there is inodewatch.stp in the installation package of systemtap, it locates at /usr/local/share/doc/systemtap/examples/io. It is used foe above.

Let take a look at the code:

  1. «color:rgb(85, 85, 85)» >$ cat inodewatch.stp
  2. #! /usr/bin/env stap
  3. probe vfs.write, vfs.read
  4. <
  5. # dev and ino are defined by vfs.write and vfs.read
  6. if (dev == MKDEV( $1 , $2 ) # major/minor device
  7. && ino == $3 )
  8. printf ( «%s(%d) %s 0x%x/%u\n» ,
  9. execname(), pid(), probefunc(), dev, ino)
  10. >

This usage of this method is stap inodewatch.stp major minor ino. Let’s create this scenario,: dd will continuously write on one file, we find out the ino of this file and its major and minor of its device, we can find the answer by executing stap.

Let’s take a look at the scenario codes:

  1. $ pwd
  2. /home/chuba
  3. $ df
  4. Filesystem 1K-blocks Used Available Use% Mounted on
  5. .
  6. /dev/sdb1 1621245336 825209568 713681236 54% /home
  7. .
  8. $ ls -al /dev/sdb1
  9. brw-rw—- 1 root disk 8, 17 Oct 24 11:22 /dev/sdb1
  10. $ rm -f test.dat && dd if =/dev/zero of=test.dat
  11. ^C9912890+0 records in
  12. 9912890+0 records out
  13. 5075399680 bytes (5.1 GB) copied, 26.8189 s, 189 MB/s

This terminal will simulate the file write, at the same time another terminal will check which process is doing this. Here we can find the major/minor of the device is 8/17.

  1. $ stat -c ‘%i’ test.dat
  2. 25337884
  3. $ sudo stap /usr/local/share/doc/systemtap/examples/io/inodewatch.stp 8 17 25337884
  4. dd(740) vfs_write 0x800011/25337884
  5. dd(740) vfs_write 0x800011/25337884
  6. dd(740) vfs_write 0x800011/25337884
  7. dd(740) vfs_write 0x800011/25337884
  8. dd(740) vfs_write 0x800011/25337884
  9. dd(740) vfs_write 0x800011/25337884
  10. .
Читайте также:  Устанавливаемый драйвер для установки windows

Have you noticed that dd is the process, PID is 740. It’s done. Mission completed.

Источник

Find Which Linux Process is Using Your Files or Ports

Find Which Linux Process is Using Your Files or Ports

If you have ever tried to unmount a filesystem, USB stick, cdrom, etc… but found that it was busy and therefore could not be unmounted, you will like the fuser command. Fuser’s man page tells us that fuser will “Show which processes use the named files, sockets, or filesystems.” But you can do more than that! You can also use fuser to send signals to your processes telling them to shutdown, terminate, pause, etc…

Use Fuser to Find Which Processes are Using a Filesystem

One of the things that used to annoy me the most was when I would try to unmount a filesystem and I would find that a process was using it and I would get the “device is busy” message.

Now, when I get that message, I simply use fuser to find which processes are using files in that filesystem.

Example: Show linux processes using /myfilesystem

As we look at the output from the fuser command above, we see that both the root user and the mary user have processes in the filesystem. We can review the columns and get lots of information. The USER, PID, and COMMAND columns are similar to the columns from the ps command and are self-explanatory. The USER column tells us the user id for the process. The PID column tells us the process id of that process. The COMMAND column tells us the command the process is running as well as the userid again in parenthesis. The ACCESS column tells us how the process is using the file. The ACCESS column may include he following letters referencing these access types:

ACCESS Column Code Code’s Definition
F file is open for writing.
f,o The process has an open file.
r The process’ root or home directory is on this filesystem (chroot).
c The process’ current directory is on this filesystem.
e,t The process is executing a file.
m,s The process has a mapped file or is using a shared library.

Using LSOF (List Open Files)

We can also use the “lsof” (list open files) command to show a similar report.

Example: Using lsof to find processes using a specified filesystem.

Find and Killing Processes Using Fuser

For the more confident system administrators, fuser has a kill option (-k) that can be used to kill whatever processes are found using a file or filesystem.

Example: Find whatever processes are using the /myfilesystem and shut them down!

Interestingly, in the above example, we found that our very process was using the /myfilesystem filesystem. We ran the fuser command with the kill option (-k) telling it to kill the processes. As ours was amongst them, it killed our process.

Use Fuser to Find Which Processes / Daemons are Listening on a Port

Fuser has additional uses. Sometimes, we want to find out what process and userid are utilizing a port on our system. We can specify the IP version with -v4 for IPv4 or -v6 for IPv6.

Example: Find out what process is handling our http traffic on port 80

We were able to find out that varnishd is handling our http traffic on port 80/tcp.

Kill Whatever Process is Listening on a Port

Let’s imagine that you need to shutdown whatever is running on port 8001/tcp for some reason. Perhaps, you have a process that normally runs on that port, but something else has taken it while you have been performing some maintenance. We can use fuser to find and kill the process in one command by using the fuser command with the -k option.

Example: Find and kill whatever process is listening on port 8001/tcp

Specifying the Signal Fuser Will Use as it Kills a Process

You can change the signal used when killing a process using fuser by simply listing it as an option to your fuser command. You can list the available signals using “fuser -l”.

and then use withever signal you want it to use:

Other Resources

Fuser is a powerful tool that can help you find which linux process is using your files or ports. Here are a few other resources that can give you additional information on fuser.

Источник

Linux / UNIX List Open Files for Process

H ow do I list all open files for a Linux or UNIX process using command line options? How can I show open files per process under Linux?

Both Linux and Unix-like operating systems come with various utilities to find out open files associated with the process.

Tutorial details
Difficulty level Easy
Root privileges Yes
Requirements None
Est. reading time 3 minutes

UNIX List Open Files For Process

First use the ps command command to get PID of process, enter:
$ ps -aef | grep $ ps -aef | grep httpd
Next pass this PID to pfiles command under Solaris Unix:
$ pfiles
$ pfiles 3533
See pfiles command documentation> for more information or type the following man command:
% man pfiles

FreeBSD list open files per process

On FreeBSD use the fstat command along with the ps command:
# ps aux | grep -i openvpn # filter outputs using the grep command #
# fstat -p
# fstat -p 1219
We can count open files count for openvpn process as follows using the wc command:
# fstat -p 1219 | grep -v ^USER | wc -l
The -p option passed to the fstat to report all files open by the specified process.

FreeBSD pstat command in action

Linux List Open Files For Process

First you need to find out PID of process. Simply use any one of the following command to obtain process id:
# ps aux | grep OR
$ ps -C -o pid=
For example, find out PID of firefox web-browser, enter:
$ ps -C firefox -o pid=
Output:

To list opne files for firefox process, enter:
$ ls -l /proc/7857/fd
Sample output:

  • No ads and tracking
  • In-depth guides for developers and sysadmins at Opensourceflare✨
  • Join my Patreon to support independent content creators and start reading latest guides:
    • How to set up Redis sentinel cluster on Ubuntu or Debian Linux
    • How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
    • How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
    • A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
    • How to protect Linux against rogue USB devices using USBGuard

Join Patreon

For privileged process use the sudo command and to count open files use the wc command on Linux as follows:
# Get process pid
sudo ps -C Xorg -o pid
sudo ls -l /proc/$/fd
# Say pid is 9497 for Xorg, then
sudo ls -l /proc/9497/fd | wc -l
We can use bash for loop as follows too:

Listing Open Files on Linux

Using lsof to display the processes using the most file handles

The lsof command list open files under all Linux distributions or UNIX-like operating system. Type the following command to list open file for process ID 351:
$ lsof -p 351
In this example display and count all open files for top 10 processes on Linux operating systems or server:
# lsof | awk ‘‘ | sort | uniq -c | sort -r | head
## force numeric sort by passing the ‘-n’ option to the sort ##
# lsof | awk ‘‘ | sort | uniq -c | sort -r -n | head

  • lsof – Run the lsof to display all open files and send output to the awk
  • awk ‘ – Display first field i.e. process name only
  • uniq -c – Omit duplicate lines while prefix lines by the number of occurrences
  • sort -r – Reverse sort
  • head – Display top 10 process along with open files count

Conclusion

Now you know how to find open files per process on Linux, FreeBSD, and Unix-like systems using various command-line options. See how to increase the system-wide/user-wide number of available (open) file handles on Linux for more information.

🐧 Get the latest tutorials on Linux, Open Source & DevOps via

Источник

Изучаем процессы в Linux


В этой статье я хотел бы рассказать о том, какой жизненный путь проходят процессы в семействе ОС Linux. В теории и на примерах я рассмотрю как процессы рождаются и умирают, немного расскажу о механике системных вызовов и сигналов.

Данная статья в большей мере рассчитана на новичков в системном программировании и тех, кто просто хочет узнать немного больше о том, как работают процессы в Linux.

Всё написанное ниже справедливо к Debian Linux с ядром 4.15.0.

Содержание

Введение

Системное программное обеспечение взаимодействует с ядром системы посредством специальных функций — системных вызовов. В редких случаях существует альтернативный API, например, procfs или sysfs, выполненные в виде виртуальных файловых систем.

Атрибуты процесса

Процесс в ядре представляется просто как структура с множеством полей (определение структуры можно прочитать здесь).
Но так как статья посвящена системному программированию, а не разработке ядра, то несколько абстрагируемся и просто акцентируем внимание на важных для нас полях процесса:

  • Идентификатор процесса (pid)
  • Открытые файловые дескрипторы (fd)
  • Обработчики сигналов (signal handler)
  • Текущий рабочий каталог (cwd)
  • Переменные окружения (environ)
  • Код возврата

Жизненный цикл процесса

Рождение процесса

Только один процесс в системе рождается особенным способом — init — он порождается непосредственно ядром. Все остальные процессы появляются путём дублирования текущего процесса с помощью системного вызова fork(2) . После выполнения fork(2) получаем два практически идентичных процесса за исключением следующих пунктов:

  1. fork(2) возвращает родителю PID ребёнка, ребёнку возвращается 0;
  2. У ребёнка меняется PPID (Parent Process Id) на PID родителя.

После выполнения fork(2) все ресурсы дочернего процесса — это копия ресурсов родителя. Копировать процесс со всеми выделенными страницами памяти — дело дорогое, поэтому в ядре Linux используется технология Copy-On-Write.
Все страницы памяти родителя помечаются как read-only и становятся доступны и родителю, и ребёнку. Как только один из процессов изменяет данные на определённой странице, эта страница не изменяется, а копируется и изменяется уже копия. Оригинал при этом «отвязывается» от данного процесса. Как только read-only оригинал остаётся «привязанным» к одному процессу, странице вновь назначается статус read-write.

Состояние «готов»

Сразу после выполнения fork(2) переходит в состояние «готов».
Фактически, процесс стоит в очереди и ждёт, когда планировщик (scheduler) в ядре даст процессу выполняться на процессоре.

Состояние «выполняется»

Как только планировщик поставил процесс на выполнение, началось состояние «выполняется». Процесс может выполняться весь предложенный промежуток (квант) времени, а может уступить место другим процессам, воспользовавшись системным вывозом sched_yield .

Перерождение в другую программу

В некоторых программах реализована логика, в которой родительский процесс создает дочерний для решения какой-либо задачи. Ребёнок в данном случае решает какую-то конкретную проблему, а родитель лишь делегирует своим детям задачи. Например, веб-сервер при входящем подключении создаёт ребёнка и передаёт обработку подключения ему.
Однако, если нужно запустить другую программу, то необходимо прибегнуть к системному вызову execve(2) :

или библиотечным вызовам execl(3), execlp(3), execle(3), execv(3), execvp(3), execvpe(3) :

Все из перечисленных вызовов выполняют программу, путь до которой указан в первом аргументе. В случае успеха управление передаётся загруженной программе и в исходную уже не возвращается. При этом у загруженной программы остаются все поля структуры процесса, кроме файловых дескрипторов, помеченных как O_CLOEXEC , они закроются.

Как не путаться во всех этих вызовах и выбирать нужный? Достаточно постичь логику именования:

  • Все вызовы начинаются с exec
  • Пятая буква определяет вид передачи аргументов:
    • l обозначает list, все параметры передаются как arg1, arg2, . NULL
    • v обозначает vector, все параметры передаются в нуль-терминированном массиве;
  • Далее может следовать буква p, которая обозначает path. Если аргумент file начинается с символа, отличного от «/», то указанный file ищется в каталогах, перечисленных в переменной окружения PATH
  • Последней может быть буква e, обозначающая environ. В таких вызовах последним аргументом идёт нуль-терминированный массив нуль-терминированных строк вида key=value — переменные окружения, которые будут переданы новой программе.

Семейство вызовов exec* позволяет запускать скрипты с правами на исполнение и начинающиеся с последовательности шебанг (#!).

Есть соглашение, которое подразумевает, что argv[0] совпадает с нулевым аргументов для функций семейства exec*. Однако, это можно нарушить.

Любопытный читатель может заметить, что в сигнатуре функции int main(int argc, char* argv[]) есть число — количество аргументов, но в семействе функций exec* ничего такого не передаётся. Почему? Потому что при запуске программы управление передаётся не сразу в main. Перед этим выполняются некоторые действия, определённые glibc, в том числе подсчёт argc.

Состояние «ожидает»

Некоторые системные вызовы могут выполняться долго, например, ввод-вывод. В таких случаях процесс переходит в состояние «ожидает». Как только системный вызов будет выполнен, ядро переведёт процесс в состояние «готов».
В Linux так же существует состояние «ожидает», в котором процесс не реагирует на сигналы прерывания. В этом состоянии процесс становится «неубиваемым», а все пришедшие сигналы встают в очередь до тех пор, пока процесс не выйдет из этого состояния.
Ядро само выбирает, в какое из состояний перевести процесс. Чаще всего в состояние «ожидает (без прерываний)» попадают процессы, которые запрашивают ввод-вывод. Особенно заметно это при использовании удалённого диска (NFS) с не очень быстрым интернетом.

Состояние «остановлен»

В любой момент можно приостановить выполнение процесса, отправив ему сигнал SIGSTOP. Процесс перейдёт в состояние «остановлен» и будет находиться там до тех пор, пока ему не придёт сигнал продолжать работу (SIGCONT) или умереть (SIGKILL). Остальные сигналы будут поставлены в очередь.

Завершение процесса

Ни одна программа не умеет завершаться сама. Они могут лишь попросить систему об этом с помощью системного вызова _exit или быть завершенными системой из-за ошибки. Даже когда возвращаешь число из main() , всё равно неявно вызывается _exit .
Хотя аргумент системного вызова принимает значение типа int, в качестве кода возврата берется лишь младший байт числа.

Состояние «зомби»

Сразу после того, как процесс завершился (неважно, корректно или нет), ядро записывает информацию о том, как завершился процесс и переводит его в состояние «зомби». Иными словами, зомби — это завершившийся процесс, но память о нём всё ещё хранится в ядре.
Более того, это второе состояние, в котором процесс может смело игнорировать сигнал SIGKILL, ведь что мертво не может умереть ещё раз.

Забытье

Код возврата и причина завершения процесса всё ещё хранится в ядре и её нужно оттуда забрать. Для этого можно воспользоваться соответствующими системными вызовами:

Вся информация о завершении процесса влезает в тип данных int. Для получения кода возврата и причины завершения программы используются макросы, описанные в man-странице waitpid(2) .

Передача argv[0] как NULL приводит к падению.

Бывают случаи, при которых родитель завершается раньше, чем ребёнок. В таких случаях родителем ребёнка станет init и он применит вызов wait(2) , когда придёт время.

После того, как родитель забрал информацию о смерти ребёнка, ядро стирает всю информацию о ребёнке, чтобы на его место вскоре пришёл другой процесс.

Благодарности

Спасибо Саше «Al» за редактуру и помощь в оформлении;

Спасибо Саше «Reisse» за понятные ответы на сложные вопросы.

Они стойко перенесли напавшее на меня вдохновение и напавший на них шквал моих вопросов.

Источник

Читайте также:  Сетевой интерфейс linux команды
Оцените статью