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();

统,支持sysupgrade刷机、文件系统快照和回滚、重写挂载系统;初步支持musl C 标准库,等等。

OpenWrt下交叉编译Node.js(HG255D)

OpenWRT上判断客户端在线个数

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/59008cea928b752e56de7f3538315351.html