2010-12-22 69 views
14

我做了一個有關「匿名inode」的谷歌搜索,它似乎與epoll有關......但究竟是什麼呢?什麼是Linux中的匿名inode?

+1

見接受的答案:http://stackoverflow.com/questions/1401359/understanding- linux-proc-id-maps – Anders 2010-12-22 12:10:19

回答

13

至少在某些情況下,一個匿名的inode是沒有附加目錄條目一個inode。創建這樣一個inode最簡單的方法是這樣的:

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. 
+0

簡而言之,匿名inode是一個不代表文件的inode,但是一個內存塊? – mrkschan 2010-12-24 04:27:13

3

openO_TMPFILE

這將是匿名的inode的一個很好的定義:它會創建一個給定目錄內的索引節點沒有任何名稱,它根本沒有出現ls

然後,當你關閉描述符中的文件被刪除。

它被添加到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; 
} 

在Ubuntu 17.04,Linux的4.10測試的glibc 2.24,運行帶有:

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

anon_inode_getfd Linux內核函數

如果你正在處理內核模塊,這是一個可能的定義。

你這樣稱呼它:

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

,並返回fd用戶,例如從ioctl

現在用戶有相關的任意file_operationsinode一個fd,並且當fd被關閉,一切都被釋放。

該方法是有用的,例如,如果你想有多個read系統調用,但不希望創建多個設備文件,從而進一步污染/dev:你只是徒增ioctl!而非。

最小運行的例子與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)