OpenWrt 系统日志之logread

前言

刚开始接触OpenWrt的时候,根本不知道如何调试各个进程,我之前从事IP Camera开发可能也局限了我的知识面,认为系统就改是那个样子。

其实不然,就像Linux发行版那样,他们都有各自都管理系统,同一个的消息通知系统,dbus和ubus这些。系统调试也是一样dmesg, 现在还接触到了logread。

初探

logread是在调试luci的时候用到的,极其方便,对于不太了解OpenWrt系统构成对人尤甚。

这个需要写进程对人对syslogd提供支持,否则说来知识惘然,我们需要做系统,需要做好对系统,就需要油完善对日志管理,精简无冗余对才是最有用的,这是我们使用其的目的。废话不多说,直接看卡logread的组成吧。


在busybox中实现了syslogd 和 logread.

syslogd用来记录log, logged则用来读取log.


logread的代码很简洁,主要实现过程是:连接共享内存->信号量加锁->读取共享内存中的信息并输出->信号量解锁。

连接共享内存

log_shmid = shmget(KEY_ID, 0, 0);  
    if (log_shmid == -1)  
        bb_perror_msg_and_die("can't %s syslogd buffer", "find");  
  
    /* Attach shared memory to our char* */  
    shbuf = shmat(log_shmid, NULL, SHM_RDONLY);  
    if (shbuf == NULL)  
        bb_perror_msg_and_die("can't %s syslogd buffer", "access");  
  
    log_semid = semget(KEY_ID, 0, 0);  
    if (log_semid == -1)  
        error_exit("can't get access to semaphores for syslogd buffer");

信号量加锁

if (semop(log_semid, SMrdn, 2) == -1)  
        error_exit("semop[SMrdn]");

读取共享内存中的信息并输出

    /* Suppose atomic memory read */
    /* Max possible value for tail is shbuf->size - 1 */
    cur = shbuf->tail;

    /* Loop for logread -f, one pass if there was no -f */
    do {
        unsigned shbuf_size;
        unsigned shbuf_tail;
        const char *shbuf_data;
#if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING
        int i;
        int len_first_part;
        int len_total = len_total; /* for gcc */
        char *copy = copy; /* for gcc */
#endif
        if (semop(log_semid, SMrdn, 2) == -1)
            error_exit("semop[SMrdn]");

        /* Copy the info, helps gcc to realize that it doesn't change */
        shbuf_size = shbuf->size;
        shbuf_tail = shbuf->tail;
        shbuf_data = shbuf->data; /* pointer! */

        if (DEBUG)
            printf("cur:%u tail:%u size:%u\n",
                    cur, shbuf_tail, shbuf_size);

        if (!follow) {
            /* advance to oldest complete message */
            /* find NUL */
            cur += strlen(shbuf_data + cur);
            if (cur >= shbuf_size) { /* last byte in buffer? */
                cur = strnlen(shbuf_data, shbuf_tail);
                if (cur == shbuf_tail)
                    goto unlock; /* no complete messages */
            }
            /* advance to first byte of the message */
            cur++;
            if (cur >= shbuf_size) /* last byte in buffer? */
                cur = 0;
        } else { /* logread -f */
            if (cur == shbuf_tail) {
                sem_up(log_semid);
                fflush_all();
                sleep(1); /* TODO: replace me with a sleep_on */
                continue;
            }
        }

        /* Read from cur to tail */
#if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING
        len_first_part = len_total = shbuf_tail - cur;
        if (len_total < 0) {
            /* message wraps: */
            /* [SECOND PART.........FIRST PART] */
            /*  ^data      ^tail    ^cur      ^size */
            len_total += shbuf_size;
        }
        copy = xmalloc(len_total + 1);
        if (len_first_part < 0) {
            /* message wraps (see above) */
            len_first_part = shbuf_size - cur;
            memcpy(copy + len_first_part, shbuf_data, shbuf_tail);
        }
        memcpy(copy, shbuf_data + cur, len_first_part);
        copy[len_total] = '\0';
        cur = shbuf_tail;
#else
        while (cur != shbuf_tail) {
            fputs(shbuf_data + cur, stdout);
            cur += strlen(shbuf_data + cur) + 1;
            if (cur >= shbuf_size)
                cur = 0;
        }
#endif

信号量解锁

 unlock:
        /* release the lock on the log chain */
        sem_up(log_semid);

#if ENABLE_FEATURE_LOGREAD_REDUCED_LOCKING
        for (i = 0; i < len_total; i += strlen(copy + i) + 1) {
            fputs(copy + i, stdout);
        }
        free(copy);
#endif
        fflush_all();
本文章由作者:佐须之男 整理编辑,原文地址: OpenWrt 系统日志之logread
本站的文章和资源来自互联网或者站长的原创,按照 CC BY -NC -SA 3.0 CN协议发布和共享,转载或引用本站文章应遵循相同协议。如果有侵犯版权的资 源请尽快联系站长,我们会在24h内删除有争议的资源。欢迎大家多多交流,期待共同学习进步。

相关推荐