Extending SysRq

Basics about SysRq

During the kernel debugging, you can use SysRq to get some details about the system status at some point or to execute some commands without typing the command.

We can use one of the below method to trigger the operation.

Method 1.

  1. $ echo 1 > /proc/sys/kernel/sysrq
  2. Press ‘Alt-SysRq-[key]’ combination to trigger the operation. If you are in GUI mode, press ‘Ctrl-Alt-SysRq-[key]’
  3. You can get details in /var/log/messages.

Method 2.

  1. $ echo ‘key’ > /proc/sysrq-trigger
  2. Check /var/log/messages for the result

If you are not familiar what commands are provided in the kernel, you can check it by running the below command.

$ echo h > /proc/sysrq-trigger

Extending SysRq

You can extend SysRq with your own key with some basic steps. You need a handler and need to fill the fileds in sysrq_key_op structure which exists in include/linux/sysrq.h

struct sysrq_key_op {
        void (*handler)(int, struct tty_struct *);
        char *help_msg;
        char *action_msg;
        int enable_mask;
};

After then, you can register and unregister it with the following functions.

int register_sysrq_key(int key, struct sysrq_key_op *op);
int unregister_sysrq_key(int key, struct sysrq_key_op *op);

Here is the sample SysRq example module (mysysrq.c)

#include <linux/module.h>
#include <linux/init.h>
#include <linux/sysrq.h>
#include <linux/sched.h>
#include <linux/version.h>
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
static void hack_sysrq_task_list(int key, struct pt_regs *ptregs,
                                 struct tty_struct *ttystruct)
#else
static void hack_sysrq_task_list(int key, struct tty_struct *ttystruct)
#endif
{
    struct task_struct *p;
 
    printk("Start to dump task list ----n");
 
    for_each_process(p) {
        printk("%s(%d) is %s Runnablen",
            p->comm, p->pid,
            p->state == TASK_RUNNING ? "" : "Not");
    }
    printk("End of task dump ----n");
}
 
static struct sysrq_key_op hack_sysrq_op = {
    .handler = hack_sysrq_task_list,
    .help_msg = "dump-All-tasks",
    .action_msg = "Show All Task List",
};
 
static int __init my_init (void)
{
    int ret = register_sysrq_key('a', &hack_sysrq_op);
 
    printk("Ret = %dn", ret);
    return ret;
}
 
static void __exit my_exit (void)
{
    unregister_sysrq_key('a', &hack_sysrq_op);
}
 
module_init(my_init);
module_exit(my_exit);
 
MODULE_LICENSE ("GPL v2");

You also need Makefile to build this.

obj-m += mysysrq.o
 
export KROOT=/lib/modules/`uname -r`/build
 
allofit:   modules
modules:
        @$(MAKE) -C $(KROOT) M=$(PWD) modules
modules_install:
        @$(MAKE) -C $(KROOT) M=$(PWD) modules_install
clean:
        rm -rf   *.o *.ko .*cmd *.mod.c .tmp_versions .*.d .*.tmp Module.symvers

For this, your system needs to have kernel-devel package installed for the current kernel version.

Now, it’s time to compile and load it.

$ make
make[1]: Entering directory `/usr/src/kernels/2.6.32-358.6.1.el6.x86_64'
  CC [M]  /root/Study/mysysrq.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /root/Study/mysysrq.mod.o
  LD [M]  /root/Study/mysysrq.ko.unsigned
  NO SIGN [M] /root/Study/mysysrq.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.32-358.6.1.el6.x86_64'
 
$ insmod ./mysysrq.ko
$ echo h > /proc/sysrq-trigger
$ tail -1 /var/log/messages
May  5 18:50:18 localhost kernel: SysRq : HELP : loglevel(0-9) dump-All-tasks reBoot Crash terminate-all-tasks(E)
memory-full-oom-kill(F) kill-all-tasks(I) thaw-filesystems(J) saK show-backtrace-all-active-cpus(L) show-memory-usage(M)
nice-all-RT-tasks(N) powerOff show-registers(P) show-all-timers(Q) unRaw Sync show-task-states(T)
Unmount show-blocked-tasks(W) dump-ftrace-buffer(Z)
 
$ echo a > /proc/sysrq-trigger
 
$ tail -3 /var/log/messages
May  5 18:48:12 localhost kernel: bash(7942) is  Runnable
May  5 18:48:12 localhost kernel: pickup(8001) is Not Runnable
May  5 18:48:12 localhost kernel: End of task dump ----
 
$ rmmod mysysrq

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.