From 923f655811846d8a9664e668b2dff5d6dd2aa495 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Sun, 1 Jul 2018 16:10:29 +0100 Subject: [PATCH] anonymous inode: move doc to readme --- README.adoc | 33 +++++++++++++++++++++++++++- kernel_module/README.adoc | 1 - kernel_module/anonymous_inode.c | 21 +++++------------- kernel_module/user/anonymous_inode.c | 16 +++++++++----- rootfs_overlay/anonymous_inode.sh | 2 +- rootfs_overlay/test_all.sh | 1 + 6 files changed, 50 insertions(+), 24 deletions(-) diff --git a/README.adoc b/README.adoc index 65aab95..da67e6f 100644 --- a/README.adoc +++ b/README.adoc @@ -3101,6 +3101,37 @@ Sources: Bibliography: https://stackoverflow.com/questions/5970595/how-to-create-a-device-node-from-the-init-module-code-of-a-linux-kernel-module/45531867#45531867 +==== Anonymous inode + +In guest: + +.... +/anonymous_inode.sh +echo $? +.... + +Outcome: the test passes: + +.... +0 +.... + +Sources: + +* link:kernel_module/anonymous_inode.c[] +* link:kernel_module/anonymous_inode.h[] +* link:kernel_module/user/anonymous_inode.c[] +* link:rootfs_overlay/anonymous_inode.sh[] + +This example: + +* gets an anonymous inode via `ioctl` from a debugfs entry `anon_inode_getfd` from a debugfs file +* read jiffies from that inode + +Anonymous inodes allow getting multiple file descriptors from a single filesystem entry, which reduces namespace pollution compared to creating multiple device files. + +Bibliography: https://stackoverflow.com/questions/4508998/what-is-an-anonymous-inode-in-linux + === Kernel panic and oops To test out kernel panics and oops in controlled circumstances, try out the modules: @@ -7734,7 +7765,7 @@ We are slowly automating testable guest tests with: ./run -F '/test_all.sh;/poweroff.out' | grep lkmc_test .... -which outputs to stdout `lkmc_test_pass` or `lkmc_test_fail` to stdout, which we can grep from host to automate testing. +which outputs `lkmc_test_pass` or `lkmc_test_fail`. Source: link:rootfs_overlay/test_all.sh[]. diff --git a/kernel_module/README.adoc b/kernel_module/README.adoc index 780e215..d4e08b5 100644 --- a/kernel_module/README.adoc +++ b/kernel_module/README.adoc @@ -19,7 +19,6 @@ ... link:dep.c[] ... link:dep2.c[] . Pseudo filesystems -.. link:anonymous_inode.c[] .. link:ioctl.c[] .. link:mmap.c[] .. link:poll.c[] diff --git a/kernel_module/anonymous_inode.c b/kernel_module/anonymous_inode.c index 54d9f56..40fa6e6 100644 --- a/kernel_module/anonymous_inode.c +++ b/kernel_module/anonymous_inode.c @@ -1,20 +1,9 @@ -/* -https://stackoverflow.com/questions/4508998/what-is-anonymous-inode - -anon_inode_getfd example: - -- get an anonymous inode via ioctl from a debugfs entry -- read jiffies from that inode - -This method allows getting multiple file descriptors from a single filesystem, -which reduces namespace pollution. -*/ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#anonymous-inode */ #include #include #include /* EFAULT */ #include -#include #include /* min */ #include #include /* printk */ @@ -23,16 +12,18 @@ which reduces namespace pollution. #include "anonymous_inode.h" static struct dentry *debugfs_file; +static u32 myval = 1; static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off) { - char kbuf[1024]; + char kbuf[8]; size_t ret; - ret = snprintf(kbuf, sizeof(kbuf), "%llu", (unsigned long long)jiffies); + ret = snprintf(kbuf, sizeof(kbuf), "%x", myval); if (copy_to_user(buf, kbuf, ret)) { ret = -EFAULT; } + myval <<= 4; return ret; } @@ -47,7 +38,7 @@ static long unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long ar switch (cmd) { case LKMC_ANONYMOUS_INODE_GET_FD: fd = anon_inode_getfd( - "random", + "todo_what_is_this_for", &fops_anon, NULL, O_RDONLY | O_CLOEXEC diff --git a/kernel_module/user/anonymous_inode.c b/kernel_module/user/anonymous_inode.c index 760fa0e..4f10d8f 100644 --- a/kernel_module/user/anonymous_inode.c +++ b/kernel_module/user/anonymous_inode.c @@ -14,10 +14,15 @@ int main(int argc, char **argv) { char buf[1024]; int fd_ioctl, fd_ioctl_anon, ret; + size_t i, nreads; if (argc < 2) { - puts("Usage: ./prog "); + puts("Usage: ./prog []"); return EXIT_FAILURE; + } else if (argc > 2) { + nreads = strtol(argv[2], NULL, 10); + } else { + nreads = 3; } fd_ioctl = open(argv[1], O_RDONLY); if (fd_ioctl == -1) { @@ -29,11 +34,10 @@ int main(int argc, char **argv) perror("ioctl"); return EXIT_FAILURE; } - ret = read(fd_ioctl_anon, buf, sizeof(buf)); - printf("%.*s\n", ret, buf); - sleep(1); - ret = read(fd_ioctl_anon, buf, sizeof(buf)); - printf("%.*s\n", ret, buf); + for (i = 0; i < nreads; ++i) { + ret = read(fd_ioctl_anon, buf, sizeof(buf)); + printf("%.*s\n", ret, buf); + } close(fd_ioctl_anon); close(fd_ioctl); return EXIT_SUCCESS; diff --git a/rootfs_overlay/anonymous_inode.sh b/rootfs_overlay/anonymous_inode.sh index d8d988b..d9c2aa7 100755 --- a/rootfs_overlay/anonymous_inode.sh +++ b/rootfs_overlay/anonymous_inode.sh @@ -1,5 +1,5 @@ #!/bin/sh set -e insmod /anonymous_inode.ko -/anonymous_inode.out /sys/kernel/debug/lkmc_anonymous_inode +[ "$(/anonymous_inode.out /sys/kernel/debug/lkmc_anonymous_inode 3)" = "$(printf '1\n10\n100')" ] rmmod anonymous_inode diff --git a/rootfs_overlay/test_all.sh b/rootfs_overlay/test_all.sh index 22e2a17..3402198 100755 --- a/rootfs_overlay/test_all.sh +++ b/rootfs_overlay/test_all.sh @@ -1,5 +1,6 @@ #!/bin/sh for test in \ + /anonymous_inode.sh \ /character_device.sh \ /character_device_create.sh \ /debugfs.sh \