Linux中SysRq的使用

  • 1.简介
SysRq 键可以直接从内核输出信息。只要不是禁 止中断状态,即使死机时也可以获取信息。SysRq 键在确认内核运行、调查内核死机原
因等各种情况下都非常有效。
  • 2.需要kernel打开CONFIG_MAGIC_SYSRQ选项支持
  • 3.内核的源代码位置:
drivers/tty/sysrq.c
  • 4.kernel中的实现
static int __init sysrq_init(void)
{
     sysrq_init_procfs();        //注册proc入口
    if (sysrq_on())    //按键的话需要开关控制
        sysrq_register_handler();         //注册按键处理入口
    return 0;
}
module_init(sysrq_init);
sysrq proc的支持:
static void sysrq_init_procfs(void)
{
    if (!proc_create("sysrq-trigger", S_IWUSR, NULL,
             & proc_sysrq_trigger_operations))
        pr_err("Failed to register proc interface\n");
}
static const struct file_operations proc_sysrq_trigger_operations = {
    .write        = write_sysrq_trigger,
    .llseek        = noop_llseek,
};
static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
                   size_t count, loff_t *ppos)
{
    if (count) {
        char c;
        if (get_user(c, buf))
            return -EFAULT;
         __handle_sysrq(c, false);
    }
    return count;
}
void __handle_sysrq(int key, bool check_mask)
{
    struct sysrq_key_op *op_p;
    ...
        op_p = __sysrq_get_key_op(key);
        if (op_p) {
        /*
         * Should we check for enabled operations (/proc/sysrq-trigger
         * should not) and is the invoked operation enabled?
         */
        if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
            printk("%s\n", op_p->action_msg);
            console_loglevel = orig_log_level;
             op_p->handler(key);
        } else {
            printk("This sysrq operation is disabled.\n");
        }
    } 
 ...
}
struct sysrq_key_op * __sysrq_get_key_op(int key)
{
        struct sysrq_key_op *op_p = NULL;
        int i;
    i = sysrq_key_table_key2index(key);
    if (i != -1)
            op_p = sysrq_key_table[i];
        return op_p;
}
static struct sysrq_key_op *sysrq_key_table[36] = {
    &sysrq_loglevel_op,        /* 0 */
    &sysrq_loglevel_op,        /* 1 */
    &sysrq_loglevel_op,        /* 2 */
    &sysrq_loglevel_op,        /* 3 */
    &sysrq_loglevel_op,        /* 4 */
    &sysrq_loglevel_op,        /* 5 */
    &sysrq_loglevel_op,        /* 6 */
    &sysrq_loglevel_op,        /* 7 */
    &sysrq_loglevel_op,        /* 8 */
    &sysrq_loglevel_op,        /* 9 */
    /*
     * a: Don't use for system provided sysrqs, it is handled specially on
     * sparc and will never arrive.
     */
    NULL,                /* a */
    & sysrq_reboot_op,        /* b */
    &sysrq_crash_op,        /* c & ibm_emac driver debug */
    &sysrq_showlocks_op,        /* d */
    & sysrq_term_op,            /* e */
    &sysrq_moom_op,            /* f */
    /* g: May be registered for the kernel debugger */
    NULL,                /* g */
    NULL,                /* h - reserved for help */
    & sysrq_kill_op,            /* i */
#ifdef CONFIG_BLOCK
    &sysrq_thaw_op,            /* j */
#else
    NULL,                /* j */
#endif
    &sysrq_SAK_op,            /* k */
#ifdef CONFIG_SMP
    &sysrq_showallcpus_op,        /* l */
#else
    NULL,                /* l */
#endif
    & sysrq_showmem_op,        /* m */
    &sysrq_unrt_op,            /* n */
    /* o: This will often be registered as 'Off' at init time */
    NULL,                /* o */
    &sysrq_showregs_op,        /* p */
    &sysrq_show_timers_op,        /* q */
    &sysrq_unraw_op,        /* r */
    &sysrq_sync_op,            /* s */
    &sysrq_showstate_op,        /* t */
    &sysrq_mountro_op,        /* u */
    /* v: May be registered for frame buffer console restore */
    NULL,                /* v */
    &sysrq_showstate_blocked_op,    /* w */
    /* x: May be registered on ppc/powerpc for xmon */
    /* x: May be registered on sparc64 for global PMU dump */
    NULL,                /* x */
    /* y: May be registered on sparc64 for global register dump */
    NULL,                /* y */
    &sysrq_ftrace_dump_op,        /* z */
}
     
sysrq按键的支持:
首先需要打开开关
打开这个功能,运行:
  # echo 1 > /proc/sys/kernel/sysrq
关闭这个功能:
  # echo 0 > /proc/sys/kernel/sysrq
#ifdef CONFIG_MAGIC_SYSRQ
    {
        .procname    = "sysrq",
        .data        = &__sysrq_enabled,
        .maxlen        = sizeof (int),
        .mode        = 0644,
        .proc_handler    = sysrq_sysctl_handler,
    },
#endif
int sysrq_toggle_support(int enable_mask)
{
    bool was_enabled = sysrq_on();
    sysrq_enabled = enable_mask;
    if (was_enabled != sysrq_on()) {
        if (sysrq_on())
             sysrq_register_handler();
        else
             sysrq_unregister_handler();
    }
    return 0;
}
由实现可以看出支持动态打开和关闭
注册sysrq按键处理函数:
static inline void sysrq_register_handler(void)
{
    int error;
    error = input_register_handler(&sysrq_handler);
    if (error)
        pr_err("Failed to register input handler, error %d", error);
    else
        sysrq_handler_registered = true;
}
static struct input_handler sysrq_handler = {
    .filter        = sysrq_filter,   //哪些消息给sysrq去处理
    .connect    = sysrq_connect,
    .disconnect    = sysrq_disconnect,
    .name        = "sysrq",
    .id_table    = sysrq_ids,
};
static bool sysrq_filter(struct input_handle *handle,
             unsigned int type, unsigned int code, int value)
{
    ...
        default:
            if (sysrq->active && value && value != 2) {
                sysrq->need_reinject = false;
                 __handle_sysrq(sysrq_xlate[code], true);
            }
            break;
        }
    ....
}
可以看出sysrq按键最终和proc一样都是调用 __handle_sysrq()来处理
  • 5.使用实例
sysrq: SysRq : HELP : loglevel(0-9) reboot(b) crash(c) terminate-all-tasks(e) memory-full-oom-kill(f) kill-all-tasks(i) thaw-filesystems(j) sak(k) show-backtrace-all-active-cpus(l) show-memory-usage(m) nice-all-R
查看内存信息:
# echo 'm' > /proc/sysrq-trigger
重启:
# echo 'b' > /proc/sysrq-trigger
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值