Frage

Ich habe eine Google-Suche über „anonymous inode“ und es scheint es epoll verwandt ist ... aber was ist es eigentlich?

War es hilfreich?

Lösung

Zumindest in manchen Kontexten ein anonymer Inode ist eine Inode ohne angeschlossenen Verzeichniseintrag. Der einfachste Weg, eine solche Inode zu schaffen, ist als solche:

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.

Andere Tipps

open mit O_TMPFILE

Dies wäre eine gute Definition von anonymen Inode sein. Es schafft eine Inode in einem bestimmten Verzeichnis ohne Namen, die überhaupt nicht mit ls erscheinen

Wenn Sie dann den Deskriptor schließen die Datei gelöscht wird.

Es wurde in Linux 3.11 hinzugefügt.

#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;
}

Getestet in Ubuntu 17.04, Linux 4.10, glibc 2.24, führen Sie mit:

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

anon_inode_getfd Linux-Kernel-Funktion

Wenn Sie mit Kernel-Module handelt, ist dies eine wahrscheinliche Definition.

Sie nennen es wie:

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

und Rückkehr fd an Benutzer, beispielsweise von einem ioctl.

Jetzt hat der Benutzer eine fd mit zugehörigen beliebigen file_operations und inode, und wenn das fd geschlossen ist, wird alles befreit.

Dieses Verfahren ist nützlich, zum Beispiel wenn Sie mehrere read syscalls haben wollen, aber nicht wollen, mehrere Gerätedateien zu erzeugen, die weiter verunreinigt /dev: Sie nur zusätzliche ioctls erstellen, anstatt

.

Minimal runnable Beispiel mit 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)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top