Энциклопедия разработчика модулей ядра Linux | страница 30



>asmlinkage int our_sys_open(const char *filename, int flags, int mode) {

> int i = 0;

> char ch;

> /* Check if this is the user we're spying on */

> if (uid == getuid_call()) {

>  /* getuid_call is the getuid system call,

>  * which gives the uid of the user who

>  * ran the process which called the system

>  * call we got */

>  /* Report the file, if relevant */

>  printk("Opened file by %d: ", uid);

>  do {

>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

>   get_user(ch, filename+i);

>#else

>   ch = get_user(filename+i);

>#endif

>   i++;

>   printk("%c", ch);

>  } while (ch != 0);

>  printk("\n");

> }

> /* Call the original sys_open - otherwise, we lose

> * the ability to open files */

> return original_call(filename, flags, mode);

>}


>/* Initialize the module - replace the system call */

>int init_module() {

> /* Warning - too late for it now, but maybe for next time... */

> printk("I'm dangerous. I hope you did a ");

> printk("sync before you insmod'ed me.\n");

> printk("My counterpart, cleanup_module(), is even");

> printk("more dangerous. If\n");

> printk("you value your file system, it will ");

> printk("be \"sync; rmmod\" \n");

> printk("when you remove this module.\n");

> /* Keep a pointer to the original function in

> * original_call, and then replace the system call

> * in the system call table with our_sys_open */

> original_call = sys_call_table[__NR_open];

> sys_call_table[__NR_open] = our_sys_open;

> /* To get the address of the function for system

> * call foo, go to sys_call_table[__NR_foo]. */

> printk("Spying on UID:%d\n", uid);

> /* Get the system call for getuid */

> getuid_call = sys_call_table[__NR_getuid];

> return 0;

>}


>/* Cleanup - unregister the appropriate file from /proc */

>void cleanup_module() {

> /* Return the system call back to normal */

> if (sys_call_table[__NR_open] != our_sys_open) {

>  printk("Somebody else also played with the ");

>  printk("open system call\n");

>  printk("The system may be left in ");

>  printk("an unstable state.\n");

> }

> sys_call_table[__NR_open] = original_call;

>}

Отложенные процессы

Что Вы делаете, когда кто-то просит Вас о чем-то, что Вы не можете сделать сразу же? Если вы человек, и вы обеспокоены, единственное, что Вы можете сказать: «Не сейчас, я занят.». Но если вы модуль, Вы имеете другую возможность. Вы можете поместить процесс в спячку, чтобы он бездействовал, пока Вы не сможете обслужить его. В конце концов, процессы помещаются в спячку и пробуждаются ядром постоянно.

Этот модуль является примером этого подхода. Файл (названный /proc/sleep) может быть открыт только одним процессом сразу. Если файл уже открыт, модуль называет module_interruptible_sleep_on