前言
剛開始接觸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