how to see which files are accessed during an application command? - linux

If I run some command-line application in Linux, how to tell which files were accessed (read and/or written) by that process? I imagine I would need to place some hooks in the file-system driver and recompile the kernel, or something like that? Is there an easier way?

strace is a command will display each system call the application makes.
From the man page:
In the simplest case strace runs the specified command until it exits. It intercepts and records the system calls which are called by a process and the signals which are received by a process. The name of each system call, its arguments and its return value are printed on standard error or to the file specified with the -o option.
For instance, each open(), read() and write() operation will show the arguments and the return code.

You can get list of file access by your application by lsof command in linux Here is list of example

In addition of other answers mentionning lsof, strace (maybe ltrace could be useful too!), fs_usage you could use for process 1234 the directory /proc/1234/, in particular the opened file descriptors are available from /proc/1234/fd/; from inside your program you could use /proc/self/fd/. See proc(5)
Perhaps inotify(7) or ptrace(2) is relevant too.

Related

ulimit Linux connection limit

I have a question about ulimit:
ulimit -u unlimited
ulimit -n 60000
If I execute these in a screen, will they forever be kept as a setting on the screen until I kill the screen or do I have to run it every time I run the program?
What I want to do is irrelevant, I just want to know if they will be kept as a setting within the screen.
ulimit is a bash builtin. It invokes the setrlimit(2) system call.
That syscall modifies some limit in its -shell- process (likewise the cd builtin calls chdir(2) and modifies the working directory of your shell process).
In a bash shell, $$ expands to the pid of that shell process. So you can use ps $$ (and even compose it, e.g. like in touch /tmp/foo$$ or cat /proc/$$/status)
So the ulimit applies to your shell and stay the same until you do another ulimit command (or until your shell terminates).
The limits of your shell process (and also its working directory) are inherited by every process started by fork(2) from your shell. These processes include those running your commands in that same shell. Notice that changing the limit (or the working directory) of some process don't affect those of the parent process. Notice that execve(2) don't change limits or working directories.
Limits (and working directory) are properties of processes (not of terminals, screens, windows, etc...). Each process has its own : limits and working directory, virtual address space, file descriptor table, etc... You could use proc(5) to query them (try in some shell to run cat /proc/self/limits and cat /proc/$$/maps and ls -l /proc/self/cwd /proc/self/fd/). See also this. Limits (and working directory) are inherited by child process started with fork(2) which has its own copy of them (so limits are not shared, but copied ... by fork).
But if you start another terminal window, it is running another shell process (which has its own limits and working directory).
See also credentials(7). Be sure to understand how fork(2) and execve(2) work, and how your shell uses them (for every command starting a new process, practically most of them).
You mention kill(1) in some comments. Be sure to read its man page (and every man page mentioned here!). Read also kill(2) and signal(7).
A program can call by itself setrlimit(2) (or chdir(2)) but that won't affect the limits (or working directory) of its parent process (often your shell). Of course it would affect future fork-ed child processes of the process running that program.
I recommend reading ALP (a freely downloadable book about Linux programming) which has several chapters explaining all that. You need several books to explain the details.
After ALP, read intro(2), be aware of existing syscalls(2), play with strace(1) and your own programs (writing a small shell is very instructive; or study the code of some existing one), and read perhaps Operating Systems: Three Easy pieces.
NB. The screen(1) utility manages several terminals, each having typically its shell process. I don't know if you refer to that utility. Read also about terminal emulators, and the tty demystified page.
The only way to really kill some screen is with a hammer, like this:
(image of a real hammer hitting a laptop found with Google, then cut with gimp, and put temporarily on my web server; the original URL is probably https://www.istockphoto.com/fr/photo/femme-daffaires-stress%C3%A9-%C3%A0-lordinateur-crash-arrive-et-d%C3%A9truisent-le-moniteur-gm172788693-5836585 and I understand the license permits me to do that.)
Don't do that, you'll be sorry.
Apparently, you are talking of sending a signal (with kill(1) or killall(1) or pkill(1) to some process running the screen(1) program, or to its process group. It is not the same.

How to kill programs in the same directory in linux?

I want to kill all programs running in the same directory as I do.
I need to find which programs are running right now and kill them (and to be careful to not kill myself).
I am running my program in Ubuntu(Linux).
I need to use this command:
int kill(pid_t pid, int sig);
How I can do it?
*The programs live in the same directory .
Stricto sensu, your question does not make sense. By the time you are getting the directory of a process, it could have called chdir(2) before you kill it (and then you should not have killed it).
On Linux, to get information about processes, use proc(5). So use readdir(3) after opendir(3) on /proc/ (filter only the numerical directories, like /proc/1234/ which corresponds to process of pid 1234). For each process there, use readlink(2) on  /proc/1234/cwd to get its directory (and on /proc/1234/exe to get its executable, if it matters). Use getcwd(2) and getpid(2) to get current directory and current process.
BTW, your kill(2) is a syscall (listed in syscalls(2)), not a command. The command is kill(1) to be usually run from a shell.
You should read Advanced Linux Programming.
At last, your desired behavior to kill every process running in your directory is extremely user unfriendly. So at least document it, and perhaps give some way to disable that behavior. A more gentle way would be to make some temporary directory (using mkdtemp(3)) then chdir(2) into it (then perhaps unlink(2) or rmdir(2) it).
See also pkill(1) and pgrep

Retrieving a list of all file descriptors (files) that a process ever opened in linux

I would like to be able to get a list of all of the file descriptors (now considering this question to pertain to actual files) that a process ever opened during the runtime of the process. The problem with polling /proc/(PID)/fd/ is that you only get a snapshot in time of what is currently open. Is there a way to force linux to keep this information around long enough to log it for the entire run of the process?
First, notice that a file descriptor which is open-ed then close-d by the application is recycled by the kernel (a future open could give the same file descriptor). See open(2) and close(2) and read Advanced Linux Programming.
Then, consider using strace(1); you'll be able to log all the syscalls (or perhaps just open, socket, close, accept, ... that is the syscalls changing the file descriptor table). Of course strace is using the ptrace(2) syscall (which you probably don't want to bother using directly).
The simplest way would be to run strace -o /tmp/mytrace.tr yourprog argments... and to look, e.g. with some pager like less, into the quite big /tmp/mytrace.tr file.
As Gearoid Murphy commented you could restrict the output of strace using e.g. -e trace=file.
BTW, to debug Makefile-s this is the wrong approach. Learn more about remake.

trigger alert when a specified command executes in linux

I have 3 samba shares mounted in my system, but suddenly, one of them gets umounted without my permision. Maybe one of houndreds of scripts which run in my crontab, but i dont know which one.
I've reviewed all /var/log directory looking for umount word without success, then i want to log when command umount is executed and which process is running it.
Maybe with syslog, maybe with another log, maybe a mail to my box....
Thanks a lot.
I have this software:
mount: mount-2.12q
mount.cifs version: 1.14-3.5.4
Unmounting does not only happen by calling the umount binary, many programs might do it. See the manual page (man syscalls) and search for umount. This said, you would have to hook the corresponding syscall and see who invokes it. I'm not sure, but most probably it's possible to disconnect inside the kernel by calling the corresponding method directly, so functionality might bypass the syscall interface which is mainly required for userspace interaction. In this case you would have to use some debugging technique on the kernel itself, which maybe is a little much for finding your problem!
You may have success using strace on an already running process (man strace), for example smbd, and see if this process invokes umount, which is quite possible.
Anyways, if you can recompile your kernel from source, you might add some printk message inside the function that is used to unmount a device to see which process did it (this would be my approach for cases where nothing else, including strace, helps).
Since the mount is a change in the filesystem, maybe the inode-observer incron is a solution for you. Another option might be the auditd.

Figuring out a program communication

I have an embedded gnu/linux on an arm device running a program and I can telnet it. I want to know how the program sends commands to the device so I can make my own program to send those commands but when I want it to. I'm pretty sure it writes to something in /dev.
How do I know which file in /dev (I know its not really files) a program is writing to and what?
For reference its on armv5tejl chip with 2.6.27.47 kernel. I also have its tool-chain so I can compile programs to it.
Using lsof (list open files), you can see which files each process has open. You should find the device node your process uses there. Alternatively, you can find out the PID (process ID) of your program using ps aux, then look at the open file descriptors of the process at /proc/$pid/fd, where $pid is the PID of your program.
To find out what the program is writing, probably the easiest thing is to use strace to trace all system calls the program does. (With strace, you can also find out which file the program opens.) You could also replace the file the program writes to with an empty file, if possible, or, if necessary, with a dummy kernel driver, which records everything it receives.

Resources