GNU/Linux >> Linux の 問題 >  >> Linux

Linux の匿名 i ノードとは何ですか?

open O_TMPFILE

これは匿名 i ノードの適切な定義です。指定されたディレクトリ内に名前なしで i ノードを作成します。これは ls ではまったく表示されません。 .

その後、記述子を閉じると、ファイルは削除されます。

Linux 3.11 で追加されました。

main.c

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

GitHub アップストリーム。

コンパイルして実行:

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

したがって、これは本質的に一時ファイルを実装する最適な方法です:C++ で一時テキスト ファイルを作成する方法は?可能な限り:

  • ファイル名をループしなくても、自由な名前をすぐに見つけることができます (名前は必要ありません!)
  • 自動削除機能あり

C++ で一時ディレクトリを作成する方法は?

Ubuntu 17.04、Linux 4.10、glibc 2.24 でテスト済み。

どのように O_TMPFILE /proc/PID/fd のように見えます

次の方法ですばやく調べることができます:

#define _GNU_SOURCE
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main(void) {
    int f = open(".", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
    struct stat s;
    fstat(f, &s);
    printf("pid %jd\n", (intmax_t)getpid());
    printf("inode %jd\n", (intmax_t)s.st_ino);
    getchar();
}

出力例:

pid 15952     
inode 44698689

ls -l /proc/15952/fd

3 -> '/home/ciro/test/#44698689 (deleted)'

これは、特定のプロセスの一時ファイルを見つけて inode を確認する方法を示しています および i ノードの親ディレクトリ。

anon_inode_getfd Linux カーネル機能

カーネル モジュールを扱っている場合、これはおそらく定義です。

次のように呼びます:

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

fd を返します ユーザーへ。 ioctl から .

今、ユーザーは fd を持っています 関連する任意の file_operations を使用 と inode 、そしてその fd 閉じられ、すべてが解放されます。

この方法は便利です。複数の read が必要な場合 /dev をさらに汚染する複数のデバイス ファイルを作成したくない :追加の ioctl を作成するだけです

QEMU Buildroot で実行可能な最小限の例:

  • https://github.com/cirosantilli/linux-kernel-module-cheat/blob/de6c179fc0cf122789f0fe85cc69b847a1f4fe9c/kernel_module/anonymous_inode.c
  • https://github.com/cirosantilli/linux-kernel-module-cheat/blob/de6c179fc0cf122789f0fe85cc69b847a1f4fe9c/rootfs_overlay/anonymous_inode.sh
#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)

anon_inode /proc/PID/fd 内

これらはパイプとソケットです。https://unix.stackexchange.com/questions/463548/what-is-anon-inode-in-the-output-of-ls-l を参照してください。


少なくとも一部のコンテキストでは、匿名 i ノードは、ディレクトリ エントリが添付されていない i ノードです。このような 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.

Linux
  1. LinuxのUmaskとは

  2. UnixからLinuxへの移行

  3. Linuxのiノード番号とは何ですか?

  1. LinuxとUnix:違いは何ですか?

  2. rdiff-backupの新機能

  3. linux/if.h と net/if.h の何が問題になっていますか?

  1. Linuxユーザーとは何ですか?

  2. Linux –フォルダのアクセス許可を変更しますか?

  3. Red Hat Linux とは?