Search code examples
linuxstracelsof

Is it possible to monitor all programs for accessing a file that does not exist?


I have a database driver that is launched by php through a PDO connection (and thus by Apache). This driver seeks for a file which it cannot find, but I do not know where it searches in order to place the file there.

But is it possible to monitor file access, especially to non-existant files, for the entire system?

When I use strace on the pid of apache's httpd, there is only output that is not relevant.

strace -e trace=open,close,read,write,connect,accept -f -s 1024 -p1234

The actual db driver process has a lifetime which is too short to attach strace to it when it is running, so I can't use it.

An other possibity would be:

lsof -r 2 | grep the_file_name

But this does not output non-existant files.

Is there an other command that can monitor "globally"?


Solution

  • Watching for non-existant file access is tricky. Kernel has inotify API to watch for file changes, but it wouldn't work for accessing non-existant files. One possible way to be to hook an open() syscall.

    Easier solution would be to start httpd with strace directly in foreground, that way no call would be missed. Example from my local debian box. Stop the service first, then:

    source /etc/apache2/envvars 
    strace -e trace=open,close,read,write,connect,accept -ff -s 1024 /usr/sbin/apache2 -DFOREGROUND -k start
    

    Make a request in another terminal and the output will show the syscalls made:

    curl localhost:80/test -v
    

    Response:

    [pid 25419] read(32, "GET /test HTTP/1.1\r\nHost: localhost\r\nUser-Agent: curl/7.47.0\r\nAccept: */*\r\n\r\n", 8000) = 77
    [pid 25419] open("/.htaccess", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    [pid 25419] open("/var/.htaccess", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    [pid 25419] open("/var/www/.htaccess", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    [pid 25419] open("/var/www/html/.htaccess", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    [pid 25419] read(32, 0x7fa39685b048, 8000) = -1 EAGAIN (Resource temporarily unavailable)
    [pid 25419] write(27, "::1 - - [23/Jul/2019:18:35:59 +0200] \"GET /test HTTP/1.1\" 404 438 \"-\" \"curl/7.47.0\"\n", 84) = 84
    [pid 25419] read(32, "", 8000)          = 0
    [pid 25419] read(32, "", 512)           = 0
    [pid 25419] close(32)                   = 0
    [pid 25419] read(5, 0x7fffc7a4a0df, 1)  = -1 EAGAIN (Resource temporarily unavailable)