This experiment traces and documents which Linux system calls are invoked when executing simple file operations:
- Creating a hard link (
ln file1.txt file1_hardlink.txt) - Deleting a hard link (
rm file1_hardlink.txt) - Reading a file (
cat file1.txt)
The goal is to understand how shell commands map to low-level kernel system calls.
All system behavior was traced using strace with -f -e trace=file options.
Command:
ln file1.txt file1_hardlink.txtSystem Calls Observed:
| Syscall | Meaning |
|---|---|
execve("/usr/bin/ln", [...]) |
Starts the ln executable |
faccessat |
Checks access permissions for preload libraries (normal) |
openat("/etc/ld.so.cache", O_RDONLY) |
Loads library cache |
newfstatat |
Reads metadata of library files |
openat("/lib/.../libc.so.6", O_RDONLY) |
Loads libc dynamically |
newfstatat |
Reads metadata of libc |
linkat("file1.txt", "file1_hardlink.txt", 0) |
Creates a hard link (key operation) |
exit |
ln exits successfully |
Main filesystem effect:
linkat()creates a new directory entryfile1_hardlink.txtpointing to the same inode asfile1.txt.- No data copying occurs.
Command:
rm file1_hardlink.txtSystem Calls Observed:
| Syscall | Meaning |
|---|---|
execve("/usr/bin/rm", [...]) |
Starts the rm executable |
faccessat |
Checks preload libraries |
openat("/etc/ld.so.cache", O_RDONLY) |
Loads library cache |
newfstatat |
Reads library metadata |
openat("/lib/.../libc.so.6", O_RDONLY) |
Loads libc dynamically |
newfstatat |
Reads metadata of libc |
newfstatat("file1_hardlink.txt", ...) |
Checks metadata of target file |
unlinkat("file1_hardlink.txt", 0) |
Removes the directory entry (key operation) |
exit |
rm exits successfully |
Main filesystem effect:
unlinkat()removes thefile1_hardlink.txtdirectory entry.- If no other links point to the inode, the inode and data would be deleted.
- However, in this case, the original
file1.txtstill exists.
Command:
cat file1.txtSystem Calls Observed:
| Syscall | Meaning |
|---|---|
execve("/usr/bin/cat", [...]) |
Starts the cat executable |
faccessat |
Checks access permissions |
openat("/etc/ld.so.cache", O_RDONLY) |
Loads library cache |
newfstatat |
Reads metadata of library |
openat("/lib/.../libc.so.6", O_RDONLY) |
Loads libc |
newfstatat |
Reads libc metadata |
openat("file1.txt", O_RDONLY) |
Opens the file for reading (key operation) |
newfstatat |
Reads metadata of the opened file |
exit |
cat exits successfully |
Main filesystem effect:
openat()opens the file descriptor forfile1.txt.catreads and outputs the file content to stdout.
| Command | Critical Syscall | Action |
|---|---|---|
ln file1.txt file1_hardlink.txt |
linkat |
Create hard link |
rm file1_hardlink.txt |
unlinkat |
Remove hard link (directory entry) |
cat file1.txt |
openat |
Open file for reading |
All other syscalls (execve, openat, newfstatat, etc.) during setup are dynamic linking overhead.
Only linkat, unlinkat, and openat are actual filesystem operations in these experiments.