歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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) http://www.linuxidc.com/Linux/2014-06/102734.htm

OpenWRT上判斷客戶端在線個數 http://www.linuxidc.com/Linux/2014-06/102733.htm

Ubuntu親自手動編譯Openwrt (DreamBox): for njit....ipk http://www.linuxidc.com/Linux/2014-02/97217.htm

基於Tiny210v2編譯OpenWrt http://www.linuxidc.com/Linux/2013-07/87621.htm

Copyright © Linux教程網 All Rights Reserved