M2.54: 字体归MeowOS/fonts+SDK跟随+多字体+全屏?(等)+boot板载+状态栏28+亮度/音量修复+mDNS固化(meow_svcd双源+meow_mdns)+hostname=meowos+文档
This commit is contained in:
1 parent
064635b3c4
commit
9b8a1e5c8b
13 files changed
+807
-35
No files matched your search
@@ -129,6 +129,9 @@ static const meow_setting_def g_defs[] = {
|
||||
* 用户关=0 则 ensure_wifi 不再自动拉起 / 蓝牙默认关=少耗电) */
|
||||
{ "network.wifi_enabled", SET_BOOL, "1", 0, 0, NULL, NULL },
|
||||
{ "network.bluetooth_enabled", SET_BOOL, "0", 0, 0, NULL, NULL },
|
||||
/* 系统(M2.54:主机名,bootmenu S89meow_svcd 开机读 system.hostname sethostname;
|
||||
* 缺省 meowos;RFC1035 首标签,供 meow_mdns 公布 <host>.local) */
|
||||
{ "system.hostname", SET_STR, "meowos", 0, 0, NULL, NULL },
|
||||
};
|
||||
|
||||
/* ---- 日志(自包含,不依赖 launcher 的 logmsg;前缀 "settings:")---- */
|
||||
|
||||
Executable
+84
@@ -0,0 +1,84 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# S89meow_svcd - MeowOS 服务管理器开机自启 + 主机名应用 + 板载服务预置
|
||||
#
|
||||
# 位置:S84ssh 之后、S90meow_bootmenu 之前(S80 < S84 < S89 < S90)。
|
||||
# * rcS 顺序执行 /etc/init.d/S??*,而 S90meow_bootmenu 里 `exec /usr/bin/meow_bootmenu
|
||||
# --fork` 会阻塞 rcS(选单后 exec meow_launcherd 或 fork 播放器监督),故任何 S90
|
||||
# 之后的 init.d(如 S91/S92)**都不会执行**——svcd 必须排在 S90 之前。
|
||||
# * 本脚本只装「稳定框架/KB级设置」:meow_svcd(固件 /usr/bin/)+ 板载服务配置
|
||||
# (/usr/data/meow/services.d/,Data 区,首启预置 mdnsd.conf)+ 应用主机名。
|
||||
#
|
||||
# 红线:不 killall、不碰播放器信号、不刷机。svcd 以 -f 前台被本脚本重挂循环拉起
|
||||
#(失败降级不死——若 svcd 死,其所托管服务已是独立子进程、被 init 收养继续运行);
|
||||
# 服务本身(mdnsd)由 svcd 按 restart=on-fail 托管。
|
||||
#
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Starting meow_svcd (S89): "
|
||||
|
||||
# 1) 应用主机名:读板载设置 system.hostname(settings.conf),缺省 meowos。
|
||||
# 须早于 meow_mdns 启动(mdnsd 默认用 gethostname() 公布 <host>.local)。
|
||||
host="meowos"
|
||||
if [ -f /usr/data/meow/settings.conf ]; then
|
||||
v=$(awk -F= '$1 ~ /^[[:space:]]*system\.hostname[[:space:]]*$/ {gsub(/[[:space:]]/,"",$2); print $2; exit}' /usr/data/meow/settings.conf)
|
||||
[ -n "$v" ] && host="$v"
|
||||
fi
|
||||
# 仅允许 RFC1035 首标签字符(A-Za-z0-9 和 '-'/'.'/'_'),否则回退 meowos
|
||||
case "$host" in
|
||||
''|*[!A-Za-z0-9_.-]*) host="meowos" ;;
|
||||
esac
|
||||
sethostname "$host" 2>/dev/null || hostname "$host" 2>/dev/null
|
||||
echo -n "host=$host "
|
||||
|
||||
# 2) 首启预置板载 mdnsd.conf(Data 区可写才建;已存在不覆盖)
|
||||
if [ -d /usr/data/meow ] && [ -w /usr/data/meow ]; then
|
||||
mkdir -p /usr/data/meow/services.d
|
||||
if [ -f /usr/data/meow/services.d/mdnsd.conf ]; then
|
||||
echo -n "mdnsd.conf exists "
|
||||
else
|
||||
cat > /usr/data/meow/services.d/mdnsd.conf <<'EOF'
|
||||
exec=/usr/bin/meow_mdns
|
||||
args=
|
||||
enabled=1
|
||||
restart=on-fail
|
||||
backoff_ms=2000
|
||||
max_restart=5
|
||||
trigger=boot
|
||||
cap=
|
||||
EOF
|
||||
chmod 644 /usr/data/meow/services.d/mdnsd.conf
|
||||
echo -n "provisioned mdnsd.conf "
|
||||
fi
|
||||
else
|
||||
echo -n "skip mdnsd.conf (/usr/data/meow not writable) "
|
||||
fi
|
||||
|
||||
# 3) 拉起 meow_svcd(-f 前台,重挂循环防死;/tmp/meow_svcd.stop 标记防停循环)
|
||||
rm -f /tmp/meow_svcd.stop
|
||||
if [ -x /usr/bin/meow_svcd ]; then
|
||||
if [ -f /tmp/meow_svcd.pid ] && kill -0 "$(cat /tmp/meow_svcd.pid 2>/dev/null)" 2>/dev/null; then
|
||||
echo "already running"
|
||||
else
|
||||
( while [ ! -f /tmp/meow_svcd.stop ]; do /usr/bin/meow_svcd -f; sleep 1; done ) &
|
||||
echo "started (supervisor pid $!)"
|
||||
fi
|
||||
else
|
||||
echo "MISSING /usr/bin/meow_svcd"
|
||||
fi
|
||||
;;
|
||||
stop)
|
||||
echo -n "Stopping meow_svcd: "
|
||||
touch /tmp/meow_svcd.stop
|
||||
for p in $(ps | grep "[m]eow_svcd" | awk '{print $1}'); do kill "$p" 2>/dev/null; done
|
||||
echo "OK"
|
||||
;;
|
||||
restart|reload)
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
Binary file not shown.
@@ -8,9 +8,13 @@
|
||||
* - svcd 本身极简:无 dlopen、无外部依赖,仅依赖 POSIX + Linux 基础接口,
|
||||
* 交叉编译为 mipsel 静态(zig-mipsel-cc),打进固件(不入卡)。
|
||||
*
|
||||
* 配置来源(TF 卡,目录式):
|
||||
* `$CARD/MeowOS/services.d/<name>.conf`(默认 `CARD=/usr/data/mnt/sd_0`)。
|
||||
* 卡拔出 → svcd 优雅停止所托管服务并保留运行状态;插卡 → 自动重建服务。
|
||||
* 配置来源(双源,目录式;板载优先):
|
||||
* - 板载 `/usr/data/meow/services.d/<name>.conf`(Data 区,恒定存在,权威源);
|
||||
* - TF 卡 `$CARD/MeowOS/services.d/<name>.conf`(默认 `CARD=/usr/data/mnt/sd_0`)。
|
||||
* 扫描**两处都读**;同名服务**板载优先**(扫 TF 时若 name 已在板载 → 跳过 + WARN
|
||||
* 「<name> 板载与 TF 都存在,采用板载」)。无双源冲突时行为不变。
|
||||
* 卡拔出 → svcd 优雅停止所托管**卡上**服务并保留运行状态(板载服务视 trigger 保留);
|
||||
* 插卡 → 自动重建。
|
||||
*
|
||||
* .conf 字段(极简 key = value,'#'/';' 注释,见 meow_svcd.md 文档):
|
||||
* name / exec / args / env / enabled / restart / backoff_ms / max_restart /
|
||||
@@ -60,7 +64,9 @@
|
||||
|
||||
/* ---- 默认路径 / 常量 ---- */
|
||||
#define SVCD_CARD_DEFAULT "/usr/data/mnt/sd_0" /* TF 卡挂载点(SPEC §1.2) */
|
||||
#define SVCD_SERVICES_REL "MeowOS/services.d" /* 配置目录(用户定案目录式) */
|
||||
#define SVCD_SERVICES_REL "MeowOS/services.d" /* TF 配置目录(用户定案目录式) */
|
||||
#define SVCD_SERVICES_BOARD "/usr/data/meow/services.d" /* 板载配置目录(首启预置/Data 区) */
|
||||
#define SVCD_PATH_MAX 256 /* 服务源目录路径缓冲上限 */
|
||||
#define SVCD_SOCK_DEFAULT "/tmp/meow_svcd.sock"
|
||||
#define SVCD_STATUS_DEFAULT "/tmp/meow_svcd.status"
|
||||
#define SVCD_PIDFILE_DEFAULT "/tmp/meow_svcd.pid"
|
||||
@@ -111,6 +117,7 @@ typedef struct {
|
||||
int max_restart; /* <0=无限 */
|
||||
char cap[SVCD_CAP_MAX]; /* 解析保留;实装为后续任务 */
|
||||
char trigger[SVCD_TRIG_STR_MAX]; /* boot|card-mount|wifi-up */
|
||||
int src; /* 0=TF 卡, 1=板载(同名优先源) */
|
||||
|
||||
/* 运行状态 */
|
||||
pid_t pid;
|
||||
@@ -131,12 +138,14 @@ static int g_nsvc = 0;
|
||||
|
||||
/* 全局环境(可被 --card/--sock/--status 覆盖,亦读 env) */
|
||||
static char g_card[256] = SVCD_CARD_DEFAULT;
|
||||
static char g_board_dir[256] = SVCD_SERVICES_BOARD; /* 板载服务目录(--board/MEOW_SVCD_BOARD 可覆写) */
|
||||
static char g_sock[SVCD_SOCK_PATH_MAX] = SVCD_SOCK_DEFAULT;
|
||||
static char g_status[256] = SVCD_STATUS_DEFAULT;
|
||||
static char g_pidfile[256] = SVCD_PIDFILE_DEFAULT;
|
||||
static char g_log[256] = ""; /* 可选日志文件 */
|
||||
|
||||
static int g_card_present = 0;
|
||||
static int g_board_online = 0; /* 板载服务目录本帧可读 */
|
||||
static int g_wifi_up = 0;
|
||||
static int g_shutdown = 0;
|
||||
static int g_fg = 0; /* -f:前台(supervisor 托管) */
|
||||
@@ -513,9 +522,9 @@ static int trigger_satisfied(const svc_t *s)
|
||||
return g_card_present;
|
||||
case 'w': /* wifi-up */
|
||||
return g_card_present && g_wifi_up;
|
||||
case 'b': /* boot:配置在卡 → 随卡存在 */
|
||||
case 'b': /* boot:板载服务恒定存在,触发不依赖卡;TF 服务仍需卡 */
|
||||
default:
|
||||
return g_card_present;
|
||||
return (s->src == 1) ? 1 : g_card_present;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,11 +579,23 @@ static int card_present(void)
|
||||
return 0; /* 同文件系统空目录 = 未挂载/未用 */
|
||||
}
|
||||
|
||||
static int scan_directory(char out[][SVCD_NAME_MAX], int max)
|
||||
static int board_services_exist(void)
|
||||
{
|
||||
struct stat st;
|
||||
if (stat(g_board_dir, &st) != 0 || !S_ISDIR(st.st_mode)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int name_in_list(const char *name, char list[][SVCD_NAME_MAX], int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
if (strcmp(list[i], name) == 0) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 枚举某目录下的 *.conf,去除 .conf 得服务名。返回个数。 */
|
||||
static int scan_conf_names(const char *dir, char out[][SVCD_NAME_MAX], int max)
|
||||
{
|
||||
char dir[512];
|
||||
if (snprintf(dir, sizeof dir, "%s/%s", g_card, SVCD_SERVICES_REL)
|
||||
>= (int)sizeof dir) return 0;
|
||||
DIR *d = opendir(dir);
|
||||
if (!d) return 0;
|
||||
int n = 0;
|
||||
@@ -593,18 +614,48 @@ static int scan_directory(char out[][SVCD_NAME_MAX], int max)
|
||||
return n;
|
||||
}
|
||||
|
||||
/* 卡存在时(初始/插入/reload)重新读配置并调和服务表。 */
|
||||
/* 双源目录调和:板载(恒定存在、权威优先)先扫,卡上有则叠加扫 TF,
|
||||
* 同名服务 TF 被板载屏蔽(WARN 记录)。无双源冲突时行为不变。 */
|
||||
static void scan_and_reconcile(void)
|
||||
{
|
||||
char names[SVCD_MAX_SERVICES][SVCD_NAME_MAX];
|
||||
int n = scan_directory(names, SVCD_MAX_SERVICES);
|
||||
char srcdir[SVCD_MAX_SERVICES][SVCD_PATH_MAX]; /* 每服务实际 .conf 所在目录 */
|
||||
int n = 0;
|
||||
|
||||
if (board_services_exist()) {
|
||||
int nb = scan_conf_names(g_board_dir, names, SVCD_MAX_SERVICES);
|
||||
for (int i = 0; i < nb; i++)
|
||||
safe_strcpy(srcdir[i], sizeof srcdir[0], g_board_dir);
|
||||
n = nb;
|
||||
}
|
||||
|
||||
if (g_card_present) {
|
||||
char tfdir[SVCD_PATH_MAX];
|
||||
if (snprintf(tfdir, sizeof tfdir, "%s/%s", g_card, SVCD_SERVICES_REL)
|
||||
< (int)sizeof tfdir) {
|
||||
char tfnames[SVCD_MAX_SERVICES][SVCD_NAME_MAX];
|
||||
int nt = scan_conf_names(tfdir, tfnames, SVCD_MAX_SERVICES);
|
||||
for (int t = 0; t < nt; t++) {
|
||||
if (name_in_list(tfnames[t], names, n) >= 0) {
|
||||
svcd_log("%s 板载与 TF 都存在,采用板载", tfnames[t]);
|
||||
continue;
|
||||
}
|
||||
if (n >= SVCD_MAX_SERVICES) {
|
||||
svcd_log("service table full, drop %s", tfnames[t]); continue;
|
||||
}
|
||||
safe_strcpy(names[n], sizeof names[0], tfnames[t]);
|
||||
safe_strcpy(srcdir[n], sizeof srcdir[0], tfdir);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < g_nsvc; i++) g_svcs[i].in_config = 0;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
char path[512];
|
||||
if (snprintf(path, sizeof path, "%s/%s/%s.conf", g_card, SVCD_SERVICES_REL,
|
||||
names[i]) >= (int)sizeof path) continue;
|
||||
if (snprintf(path, sizeof path, "%s/%s.conf", srcdir[i], names[i])
|
||||
>= (int)sizeof path) continue;
|
||||
int idx = find_svc(names[i]);
|
||||
if (idx < 0) {
|
||||
if (g_nsvc >= SVCD_MAX_SERVICES) { svcd_log("service table full, drop %s", names[i]); continue; }
|
||||
@@ -612,6 +663,7 @@ static void scan_and_reconcile(void)
|
||||
}
|
||||
svc_t tmp;
|
||||
if (load_conf(path, names[i], &tmp) != 0) { continue; }
|
||||
tmp.src = (strcmp(srcdir[i], g_board_dir) == 0) ? 1 : 0;
|
||||
svc_t *s = &g_svcs[idx];
|
||||
|
||||
/* 判定是否需重启(结构字段变化) */
|
||||
@@ -692,6 +744,8 @@ static void on_card_out(void)
|
||||
for (int i = 0; i < g_nsvc; i++) {
|
||||
svc_t *s = &g_svcs[i];
|
||||
s->restart_at_ms = 0;
|
||||
/* 拔卡后 trigger 仍满足的服务(板载-boot)不随卡停止(板载服务保留,MDNS 等常驻) */
|
||||
if (s->pid > 0 && trigger_satisfied(s)) continue;
|
||||
if (s->pid > 0) { stop_service(s, 0, 0); }
|
||||
else if (s->state == SV_RUNNING || s->state == SV_STOPPING) s->state = SV_STOPPED;
|
||||
}
|
||||
@@ -822,7 +876,7 @@ static void handle_connection(int fd)
|
||||
} else if (strcmp(line, "status") == 0) {
|
||||
cmd_status(fd);
|
||||
} else if (strcmp(line, "reload") == 0) {
|
||||
if (g_card_present) scan_and_reconcile();
|
||||
scan_and_reconcile();
|
||||
send_resp(fd, "OK\n");
|
||||
} else if (sp && strcmp(line, "start") == 0) {
|
||||
send_resp(fd, cmd_start(sp) == 0 ? "OK\n" : "ERR no-such-service\n");
|
||||
@@ -942,12 +996,13 @@ static int start_daemon(void)
|
||||
if (g_status_fd < 0) svcd_log("status file open fail: %s", strerror(errno));
|
||||
else set_cloexec(g_status_fd);
|
||||
|
||||
/* 初始卡探测 */
|
||||
/* 初始卡探测 + 板载服务目录状态 */
|
||||
g_card_present = card_present();
|
||||
if (g_card_present) scan_and_reconcile();
|
||||
g_board_online = board_services_exist();
|
||||
scan_and_reconcile(); /* 板载服务恒在,无卡也扫;卡上有则叠加扫 TF */
|
||||
|
||||
svcd_log("meow_svcd up: card=%s present=%d sock=%s pid=%d",
|
||||
g_card, g_card_present, g_sock, (int)getpid());
|
||||
svcd_log("meow_svcd up: card=%s present=%d board=%s sock=%s pid=%d",
|
||||
g_card, g_card_present, g_board_dir, g_sock, (int)getpid());
|
||||
|
||||
struct pollfd pfds[2];
|
||||
nfds_t nfds = 2;
|
||||
@@ -997,6 +1052,12 @@ static int start_daemon(void)
|
||||
if (present) { g_card_present = 1; svcd_log("card mounted, rebuild"); scan_and_reconcile(); }
|
||||
else { g_card_present = 0; on_card_out(); }
|
||||
}
|
||||
int bonline = board_services_exist();
|
||||
if (bonline != g_board_online) {
|
||||
g_board_online = bonline;
|
||||
svcd_log("board services dir %s %s, rebuild", g_board_dir, bonline ? "online" : "offline");
|
||||
scan_and_reconcile();
|
||||
}
|
||||
}
|
||||
tick_evaluate();
|
||||
build_status_file();
|
||||
@@ -1048,6 +1109,7 @@ static void usage(const char *argv0)
|
||||
" options:\n"
|
||||
" -f, --foreground stay in foreground (supervisor fork/exec 托管)\n"
|
||||
" --card <path> TF card mount point (default /usr/data/mnt/sd_0)\n"
|
||||
" --board <path> board services dir (default /usr/data/meow/services.d)\n"
|
||||
" --sock <path> control socket (default /tmp/meow_svcd.sock)\n"
|
||||
" --status <path> status file (default /tmp/meow_svcd.status)\n"
|
||||
" --pidfile <path> pid file (default /tmp/meow_svcd.pid)\n"
|
||||
@@ -1065,6 +1127,7 @@ int main(int argc, char **argv)
|
||||
const char *a = argv[i];
|
||||
if (strcmp(a, "-f") == 0 || strcmp(a, "--foreground") == 0) g_fg = 1;
|
||||
else if (strcmp(a, "--card") == 0 && i + 1 < argc) safe_strcpy(g_card, sizeof g_card, argv[++i]);
|
||||
else if (strcmp(a, "--board") == 0 && i + 1 < argc) safe_strcpy(g_board_dir, sizeof g_board_dir, argv[++i]);
|
||||
else if (strcmp(a, "--sock") == 0 && i + 1 < argc) safe_strcpy(g_sock, sizeof g_sock, argv[++i]);
|
||||
else if (strcmp(a, "--status") == 0 && i + 1 < argc) safe_strcpy(g_status, sizeof g_status, argv[++i]);
|
||||
else if (strcmp(a, "--pidfile") == 0 && i + 1 < argc) safe_strcpy(g_pidfile, sizeof g_pidfile, argv[++i]);
|
||||
@@ -1076,6 +1139,7 @@ int main(int argc, char **argv)
|
||||
/* env 覆盖 */
|
||||
const char *e;
|
||||
if ((e = getenv("MEOW_SVCD_CARD")) && e[0]) safe_strcpy(g_card, sizeof g_card, e);
|
||||
if ((e = getenv("MEOW_SVCD_BOARD")) && e[0]) safe_strcpy(g_board_dir, sizeof g_board_dir, e);
|
||||
if ((e = getenv("MEOW_SVCD_SOCK")) && e[0]) safe_strcpy(g_sock, sizeof g_sock, e);
|
||||
if ((e = getenv("MEOW_SVCD_STATUS")) && e[0]) safe_strcpy(g_status, sizeof g_status, e);
|
||||
if ((e = getenv("MEOW_SVCD_LOG")) && e[0]) safe_strcpy(g_log, sizeof g_log, e);
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
二进制入口:`patch_v2/meow_svcd/meow_svcd`(mipsel 静态,~98KB,<200KB 固件阈值)。
|
||||
宿主编译:`patch_v2/meow_svcd/meow_svcd_host`。
|
||||
|
||||
> 本阶段范围:守护 + 宿主测试。**接入 supervisor 启动链**
|
||||
> (bootmenu/launcher fork+exec 拉起、waitpid)为后续任务——启动改固件有风险,
|
||||
> 需另行确认。接入时用 `meow_svcd -f`(前台)保证 supervisor 可 `waitpid`。
|
||||
> 本阶段(M2.54)范围:守护 + 双源 services.d + 宿主测试。**接入系统启动链**已定:
|
||||
> 固件预置 `etc/init.d/S89meow_svcd`(开机自启,`myow_svcd -f` 前台 + shell 重挂在 rcS 早期,
|
||||
> 先于 S90meow_bootmenu——因 S90 exec 引导选单后阻塞 rcS,故须排在 S90 之前)。
|
||||
> 直接由 bootmenu/launcher `fork+exec` + `waitpid` 托管的方案仍成立(改固件有风险),
|
||||
> 作为备选——用 `-f` 前台即可被 waitpid。
|
||||
|
||||
---
|
||||
|
||||
@@ -19,7 +21,8 @@
|
||||
| 用途 | 默认值 | 覆盖方式 |
|
||||
|---|---|---|
|
||||
| TF 卡挂载点 | `/usr/data/mnt/sd_0`(SPEC §1.2) | `--card` / `MEOW_SVCD_CARD` |
|
||||
| 服务配置目录 | `<card>/MeowOS/services.d/` | 随 `--card` |
|
||||
| 板载服务目录 | `/usr/data/meow/services.d`(首启预置/Data 区) | `--board` / `MEOW_SVCD_BOARD` |
|
||||
| TF 服务目录 | `<card>/MeowOS/services.d/` | 随 `--card` |
|
||||
| 控制 socket | `/tmp/meow_svcd.sock` | `--sock` / `MEOW_SVCD_SOCK` |
|
||||
| 状态文件 | `/tmp/meow_svcd.status` | `--status` / `MEOW_SVCD_STATUS` |
|
||||
| pid 文件 | `/tmp/meow_svcd.pid` | `--pidfile` |
|
||||
@@ -28,10 +31,18 @@
|
||||
> 状态文件写板载 `/tmp`(tmpfs,存活期)或可配置;svcd 日志走 stderr 便于
|
||||
> supervisor 捕获(`-f` 前台时子进程 stdout/stderr 也落到同一 sink)。
|
||||
|
||||
## 2. services.d 目录式配置
|
||||
## 2. services.d 目录式配置(**双源**:板载 + TF,板载优先)
|
||||
|
||||
卡片上 `MeowOS/services.d/<name>.conf`,一个服务一个 `.conf`。极简 `key = value`,
|
||||
`#`/`;` 注释,空行忽略;**未知键忽略**(前向兼容)。行内注释可用 `\#` 转义。
|
||||
服务配置**两处都读**,一个服务一个 `<name>.conf`:
|
||||
|
||||
- **板载** `/usr/data/meow/services.d/<name>.conf`:Data 区,恒定存在、权威优先;
|
||||
首启由固件 `S89meow_svcd` 预置(如 `mdnsd.conf`)。拔卡不丢。
|
||||
- **TF** `<card>/MeowOS/services.d/<name>.conf`:随卡存在/消失。
|
||||
|
||||
**同名遮蔽规则**:先扫板载(权威),再扫 TF;若 TF 出现与板载同名服务 → **跳过 +
|
||||
WARN**「<name> 板载与 TF 都存在,采用板载」。无双源冲突时行为不变。
|
||||
|
||||
极简 `key = value`,`#`/`;` 注释,空行忽略;**未知键忽略**(前向兼容)。行内注释可用 `\#` 转义。
|
||||
|
||||
| 字段 | 必填 | 类型 | 说明 | 默认 |
|
||||
|---|---|---|---|---|
|
||||
@@ -71,6 +82,23 @@ trigger = card-mount
|
||||
# cap = cap_net_bind_service,cap_net_raw
|
||||
```
|
||||
|
||||
**板载 mDNS 应答器示例**(固件预置 `/usr/data/meow/services.d/mdnsd.conf`,首启建):
|
||||
|
||||
```ini
|
||||
# 自研 IPv4-only mDNS 应答器(固件 /usr/bin/meow_mdns;板载服务,拔卡不丢)
|
||||
exec = /usr/bin/meow_mdns
|
||||
args =
|
||||
enabled = 1
|
||||
restart = on-fail
|
||||
backoff_ms = 2000
|
||||
max_restart = 5
|
||||
trigger = boot # 板载服务:boot 触发不依赖卡(恒定存在);cap 空=root 绑 5353/组播
|
||||
cap =
|
||||
```
|
||||
|
||||
> `trigger` 为单值枚举(`boot|card-mount|wifi-up`)。板载服务用 `boot`(恒存在即启动);
|
||||
> `wifi-up` 属扩展点(`/sys/class/net/<iface>/operstate`),当前平台无无线接口恒 0。
|
||||
|
||||
## 3. 状态机
|
||||
|
||||
```
|
||||
@@ -112,7 +140,7 @@ FAILED 崩溃且不再重启(超 max_restart / restart=never)
|
||||
优雅停所有服务**并保留 `restart_count`/`last_exit` 状态**;插卡 → `scan_and_reconcile()`
|
||||
重建并按触发拉起。
|
||||
- **`wifi-up`**:读 `/sys/class/net/<iface>/operstate`,无无线接口恒 `0`(扩展点)。
|
||||
- `boot`:配置在卡 → 随卡存在即启动(拔卡即停)。
|
||||
- `boot`:TF 配置在卡 → 随卡存在即启动(拔卡即停);**板载配置**(`src=board`)→ 恒定存在即启动(不依赖卡,拔卡保留,供 mdnsd 等常驻服务)。
|
||||
|
||||
## 6. CLI / 控制协议
|
||||
|
||||
@@ -139,7 +167,8 @@ meow_svcd pid
|
||||
|
||||
## 后续(不在本阶段)
|
||||
|
||||
- 接入 supervisor 启动链(bootmenu/launcher fork+exec、waitpid,`-f` 前台)。
|
||||
- ~~接入 supervisor 启动链~~(已改由 `etc/init.d/S89meow_svcd` 开机自启;bootmenu/launcher
|
||||
`fork+exec` + `waitpid` 托管仍为备选)。
|
||||
- `cap` 真机实装(平台是否支持 capset/pthread caps 待确认;需先探测)。
|
||||
- `wifi-up` 事件细节(是否用 `/proc/net/wireless` / 重试文件,接口判定收紧)。
|
||||
- svcd/服务日志落位到卡 `MeowOS/logs/` 的行为(当前 svcd 日志 stderr + 可选 `--log`)。
|
||||
Reference in new issue
Block a user