Android Service 命名過長導致服務不可用分析
來自專欄 Android開發隨筆
前段時間在處理Android網路問題的時候,遇到了一個很匪夷所思的問題:在init.xxx.rc中增加了一個service,內容是運行一個腳本,編譯燒錄內核以後,發現這個service 就是不會執行,無論怎麼調換位置和格式,就是不能執行,當時的內容如下:
service flush_dns_nameserver /system/bin/flush_dns_name.sh ... ...
網上查了一些資料,也沒有發現相關的現象。在進行了很多嘗試都沒有奏效後,我將service name的長度縮短了一點,縮短成下面這樣
service flush_service /system/bin/flush_dns_name.sh ... ...
竟然奇蹟的可以了!!! 看樣子linux在這裡做了手腳,我們來看看源碼:
static void *parse_service(struct parse_state *state, int nargs, char **args){ struct service *svc; if (nargs < 3) { parse_error(state, "services must have a name and a program
"); return 0; } if (!valid_name(args[1])) { parse_error(state, "invalid service name %s
", args[1]); return 0; } svc = service_find_by_name(args[1]); if (svc) { parse_error(state, "ignored duplicate definition of service %s
", args[1]); return 0; } nargs -= 2; svc = calloc(1, sizeof(*svc) + sizeof(char*) * nargs); if (!svc) { parse_error(state, "out of memory
"); return 0; } svc->name = args[1]; svc->classname = "default"; memcpy(svc->args, args + 2, sizeof(char*) * nargs); svc->args[nargs] = 0; svc->nargs = nargs; svc->onrestart.name = "onrestart"; list_init(&svc->onrestart.commands); list_add_tail(&service_list, &svc->slist); return svc;}
上面的內容是init_parser.c的函數,作用是解析開機啟動腳本(init.xxx.rc)的service section內容。在解析之前,函數進行了一個參數檢測
if (!valid_name(args[1])) { parse_error(state, "invalid service name %s
", args[1]); return 0;}
args[1] 也就是service name 這裡對service name 進行了一個valid判斷
static int valid_name(const char *name){ if (strlen(name) > 16) { return 0; } while (*name) { if (!isalnum(*name) && (*name != _) && (*name != -)) { return 0; } name++; } return 1;}
通過原生的代碼,我們可以得出一下結論:
- service name 長度不能超出16個字元
- service name 命名時可以使用的字元只能是字母數字(0-9a-zA-Z),_和 -
因為連續兩天有人踩了這個坑,決定追一下源碼,填了這個坑
推薦閱讀:
※情懷不能支撐諾基亞——第三季度凈虧損1.90億歐元,股價暴跌18%
※中國為何不像NASA那樣發射遠距離深空探測器?
※冰箱突然爆炸,如何安全使用冰箱防意外?
※對人類歷史影響最大的10個發明是什麼?為什麼?
※因數據濫用調查,Facebook暫停了200款應用