0

Suppose I'm writing a system call for Linux kernel version 2.6.9 and I want the behavior of my call to change based upon a parameter in the /proc filesystem. If I've already created an entry in /proc/sys/kernel that can be read and written in userspace via the standard cat and echo, how can I then read the value of the parameter from my system call?

Edit
It has been suggested that this is a duplicate question. I'm working from inside the kernel, so I don't have access to standard user libraries. Also, I'm not trying to read the output of another process, I'm trying to read the value set in /proc/sys/kernel/myfoobar

  • Possible duplicate of [How can I run an external program from C and parse its output?](https://stackoverflow.com/questions/43116/how-can-i-run-an-external-program-from-c-and-parse-its-output) – jack Sep 25 '17 at 15:16
  • I think that is your question, simplified. – jack Sep 25 '17 at 15:17
  • > I want the behavior of my call to change based upon a parameter in the /proc filesystem < This sounds like a bad API design. > I'm working from inside the kernel < I don't understand why do you need user-space accessible tunable only to be changed from within a kernel. Some code on how to you implemented it might help a bit – myaut Sep 25 '17 at 16:05
  • @myaut It's part of an assignment for an intro to kernel development course. The basic idea is that the system call just modifies an `int` that the user passes it. However, the user can modify the behavior of the call by editing `/proc/sys/kernel/myfoobar`. When the value in `/proc/sys/kernel/myfoobar` is `0`, the system call increments the argument, and when it is `1`, it doubles the argument. I found an answer to my question, which I've posted below. – Dan Shawlson Sep 25 '17 at 17:02

2 Answers2

0

From within the system call, I read /proc/sys/kernel/myfoobar as a file using a modified version of the code from Greg Kroah-Hartman's article Driving Me Nuts - Things You Never Should Do in the Kernel:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>

static void read_file(char *filename)
{
  int fd;
  char buf[1];

  mm_segment_t old_fs = get_fs();
  set_fs(KERNEL_DS);

  fd = sys_open(filename, O_RDONLY, 0);
  if (fd >= 0) {
    printk(KERN_DEBUG);
    while (sys_read(fd, buf, 1) == 1)
      printk("%c", buf[0]);
    printk("\n");
    sys_close(fd);
  }
  set_fs(old_fs);
}

static int __init init(void)
{
  read_file("/etc/shadow");
  return 0;
}

static void __exit exit(void)
{ }

MODULE_LICENSE("GPL");
module_init(init);
module_exit(exit);

I don't know if this is the correct/best way to accomplish this, but it works.

0

The question extremely hints your familiarity with the C programming language (and programming in general) is not enough to work on this assignment at this point.

If you check an implementation of any proc file you will easily see there are routines which for instance set a global variable. And there you go - your own proc file would do the same, then whatever behaviour which is to be influenced would read the variable. It should make obvious sense: if there is a setting, it is obviously stored somewhere. Why would the kernel read its own proc files to get them?

There is most definitely 0 use for reading a proc file. For instance check out how /proc/sys/fs/file-max is implemented.