What is anonymous inode on Linux?

I did a google search for "anonymous inode" and it seems to be related to epoll ... but what really is?

+20
linux epoll inode
Dec 22 '10 at
source share
2 answers

In at least some contexts, an anonymous index is an inode without an attached directory entry. The easiest way to create an index like this:

int fd = open( "/tmp/file", O_CREAT | O_RDWR, 0666 ); unlink( "/tmp/file" ); // Note that the descriptor fd now points to an inode that has no filesystem entry; you // can still write to it, fstat() it, etc. but you can't find it in the filesystem. 
+19
Dec 22 '10 at 12:09
source share

open with O_TMPFILE

That would be a good definition of an anonymous inode: it creates an inode inside the given directory without any name that doesn't display at all with ls .

Then, when you close the handle, the file is deleted.

It was added in Linux 3.11.

 #define _GNU_SOURCE #include <assert.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> int main(void) { char buf[] = { 'a', 'b', 'c', 'd' }; char buf2[] = { 'e', 'f', 'g', 'h' }; int f, ret; size_t off; /* write */ f = open(".", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); ret = write(f, buf, sizeof(buf)); /* Interactivelly check if anything changed on directory. It hasn't. */ /*puts("hit enter to continue");*/ /*getchar();*/ /* read */ lseek(f, 0, SEEK_SET); off = 0; while ((ret = read(f, buf2 + off, sizeof(buf) - off))) { off += ret; } close(f); assert(!memcmp(buf, buf2, sizeof(buf))); return EXIT_SUCCESS; } 

Tested on Ubuntu 17.04, Linux 4.10, glibc 2.24, run with

 gcc -o a.out -std=c99 -Wall -Wextra ac ./a.out 

anon_inode_getfd Linux kernel function

If you are dealing with kernel modules, this is a likely definition.

You call it:

 fd = anon_inode_getfd("random", &fops_anon, NULL, O_RDONLY | O_CLOEXEC); 

and return fd user, for example. from ioctl .

Now the user has fd with the corresponding arbitrary file_operations and inode , and when this fd closed, everything is freed.

This method is useful, for example, if you want to have several read system calls, but do not want to create multiple device files, which further pollutes /dev : instead, you simply create an additional ioctl .

Minimal runnable example with QEMU Buildroot:

 #include <asm/uaccess.h> /* copy_from_user, copy_to_user */ #include <linux/anon_inodes.h> #include <linux/debugfs.h> #include <linux/errno.h> /* EFAULT */ #include <linux/fs.h> #include <linux/jiffies.h> #include <linux/kernel.h> /* min */ #include <linux/module.h> #include <linux/printk.h> /* printk */ #include "anonymous_inode.h" MODULE_LICENSE("GPL"); static struct dentry *dir; static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off) { char kbuf[1024]; size_t ret; ret = snprintf(kbuf, sizeof(kbuf), "%llu", (unsigned long long)jiffies); if (copy_to_user(buf, kbuf, ret)) { ret = -EFAULT; } return ret; } static const struct file_operations fops_anon = { .read = read, }; static long unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long argp) { int fd; switch (cmd) { case LKMC_ANONYMOUS_INODE_GET_FD: fd = anon_inode_getfd( "random", &fops_anon, NULL, O_RDONLY | O_CLOEXEC ); if (copy_to_user((void __user *)argp, &fd, sizeof(fd))) { return -EFAULT; } break; default: return -EINVAL; break; } return 0; } static const struct file_operations fops_ioctl = { .owner = THIS_MODULE, .unlocked_ioctl = unlocked_ioctl }; static int myinit(void) { dir = debugfs_create_dir("lkmc_anonymous_inode", 0); debugfs_create_file("f", 0, dir, NULL, &fops_ioctl); return 0; } static void myexit(void) { debugfs_remove_recursive(dir); } module_init(myinit) module_exit(myexit) 
+6
Jun 06 '17 at 10:52
source share



All Articles