zoukankan      html  css  js  c++  java
  • kernel log buf dump function kmsg_dump_get_buffer()

    kernel log buf dump function kmsg_dump_get_buffer()

    4.19/kernel/printk/printk.c

    void kmsg_dump(enum kmsg_dump_reason reason)
    {
        struct kmsg_dumper *dumper;
        unsigned long flags;
    
        if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump)
            return;
    
        rcu_read_lock();
        list_for_each_entry_rcu(dumper, &dump_list, list) {
            if (dumper->max_reason && reason > dumper->max_reason)
                continue;
    
            /* initialize iterator with data about the stored records */
            dumper->active = true;
    
            logbuf_lock_irqsave(flags);
            dumper->cur_seq = clear_seq;
            dumper->cur_idx = clear_idx;
            dumper->next_seq = log_next_seq;
            dumper->next_idx = log_next_idx;
            logbuf_unlock_irqrestore(flags);
    
            /* invoke dumper which will iterate over records */
            dumper->dump(dumper, reason);
    
            /* reset iterator */
            dumper->active = false;
        }
        rcu_read_unlock();
    }
    bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
                  char *buf, size_t size, size_t *len)
    {
        unsigned long flags;
        u64 seq;
        u32 idx;
        u64 next_seq;
        u32 next_idx;
        size_t l = 0;
        bool ret = false;
    
        if (!dumper->active)
            goto out;
    
        logbuf_lock_irqsave(flags);
        if (dumper->cur_seq < log_first_seq) {
            /* messages are gone, move to first available one */
            dumper->cur_seq = log_first_seq;
            dumper->cur_idx = log_first_idx;
        }
    
        /* last entry */
        if (dumper->cur_seq >= dumper->next_seq) {
            logbuf_unlock_irqrestore(flags);
            goto out;
        }
    
        /* calculate length of entire buffer */
        seq = dumper->cur_seq;
        idx = dumper->cur_idx;
        while (seq < dumper->next_seq) {
            struct printk_log *msg = log_from_idx(idx);
    
            l += msg_print_text(msg, true, NULL, 0);
            idx = log_next(idx);
            seq++;
        }
    
        /* move first record forward until length fits into the buffer */
        seq = dumper->cur_seq;
        idx = dumper->cur_idx;
        while (l >= size && seq < dumper->next_seq) {
            struct printk_log *msg = log_from_idx(idx);
    
            l -= msg_print_text(msg, true, NULL, 0);
            idx = log_next(idx);
            seq++;
        }
    
        /* last message in next interation */
        next_seq = seq;
        next_idx = idx;
    
        l = 0;
        while (seq < dumper->next_seq) {
            struct printk_log *msg = log_from_idx(idx);
    
            l += msg_print_text(msg, syslog, buf + l, size - l);
            idx = log_next(idx);
            seq++;
        }
    
        dumper->next_seq = next_seq;
        dumper->next_idx = next_idx;
        ret = true;
        logbuf_unlock_irqrestore(flags);
    out:
        if (len)
            *len = l;
        return ret;
    }
    EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer);
    下面两个变量表示kernel log buf最后一个clear log buffer后的位置(index)
    dumper->cur_seq
    dumper->cur_idx
    下面两个变量表示kernel log buf里指向buf开头的seq、idx:
    log_first_seq
    log_first_idx
    下面变量表示kernel log buf下一个写log的位置:
    dumper->next_seq

    kmsg_dump_get_buffer()函数会先计算kernel log buf目前总的size,如果这个len和此函数参数len要大,会将seq、idx前移,直到log buf size小于等于参数len,即会将会将log buf开头部分去掉,之后再将后面的log buf整体复制到函数参数buf所表示的buffer里,所以这会将kernel log buf里最新的log复制给调用者。

     
     



     
  • 相关阅读:
    Begin Example with Override Encoded SOAP XML Serialization
    State Machine Terminology
    How to: Specify an Alternate Element Name for an XML Stream
    How to: Publish Metadata for a WCF Service.(What is the Metadata Exchange Endpoint purpose.)
    Beginning Guide With Controlling XML Serialization Using Attributes(XmlSerializaiton of Array)
    Workflow 4.0 Hosting Extensions
    What can we do in the CacheMetaData Method of Activity
    How and Why to use the System.servicemodel.MessageParameterAttribute in WCF
    How to: Begin Sample with Serialization and Deserialization an Object
    A Test WCF Service without anything of config.
  • 原文地址:https://www.cnblogs.com/aspirs/p/15471868.html
Copyright © 2011-2022 走看看