diff --git a/system/nxinit/service.c b/system/nxinit/service.c index 71f0b76c0..bfdd99367 100644 --- a/system/nxinit/service.c +++ b/system/nxinit/service.c @@ -98,6 +98,8 @@ static int option_gentle_kill(FAR struct service_manager_s *sm, int argc, FAR char **argv); static int option_restart_period(FAR struct service_manager_s *sm, int argc, FAR char **argv); +static int option_fallback(FAR struct service_manager_s *sm, + int argc, FAR char **argv); static int option_override(FAR struct service_manager_s *sm, int argc, FAR char **argv); static int option_oneshot(FAR struct service_manager_s *sm, @@ -118,6 +120,7 @@ static const struct cmd_map_s g_option[] = {"class", 2, NXINIT_ACTION_CMD_ARGS_MAX, option_class}, {"gentle_kill", 1, 1, option_gentle_kill}, {"restart_period", 2, 2, option_restart_period}, + {"fallback", 1, 1, option_fallback}, {"override", 1, 1, option_override}, {"oneshot", 1, 1, option_oneshot}, {"console", 1, 2, option_console}, @@ -137,6 +140,7 @@ static const struct flag_str_s g_flag_str[] = {SVC_GENTLE_KILL, "gentle_kill"}, {SVC_REMOVE, "remove"}, {SVC_SIGKILL, "sigkill"}, + {SVC_FALLBACK, "fallback"}, {SVC_OVERRIDE, "override"}, }; #endif @@ -260,6 +264,16 @@ static int option_restart_period(FAR struct service_manager_s *sm, return 0; } +static int option_fallback(FAR struct service_manager_s *sm, + int argc, FAR char **argv) +{ + FAR struct service_s *s = list_last_entry(&sm->services, struct service_s, + node); + + add_flags(s, SVC_FALLBACK); + return 0; +} + static int option_override(FAR struct service_manager_s *sm, int argc, FAR char **argv) { @@ -768,17 +782,31 @@ int init_service_check(FAR const struct parser_s *parser) { if (!strcmp(s->argv[1], tmp->argv[1])) { - if (!check_flags(tmp, SVC_OVERRIDE)) + if (check_flags(tmp, SVC_OVERRIDE)) + { + init_info("override: remove old service '%s'", + s->argv[1]); + add_flags(s, SVC_DISABLED | SVC_REMOVE); + } + else if (check_flags(tmp, SVC_FALLBACK)) + { + init_info("fallback: ignore new service '%s'", + tmp->argv[1]); + add_flags(tmp, SVC_DISABLED | SVC_REMOVE); + } + else if (check_flags(s, SVC_FALLBACK)) + { + init_info("fallback: replace old service '%s'", + s->argv[1]); + add_flags(s, SVC_DISABLED | SVC_REMOVE); + } + else { init_err("Redefined service '%s'", tmp->argv[1]); init_dump_service(s); init_dump_service(tmp); return -EEXIST; } - - init_info("Remove duplicate definition of service '%s'", - tmp->argv[1]); - add_flags(s, SVC_DISABLED | SVC_REMOVE); } } } diff --git a/system/nxinit/service.h b/system/nxinit/service.h index c6b98dd8e..a50cf2124 100644 --- a/system/nxinit/service.h +++ b/system/nxinit/service.h @@ -55,6 +55,10 @@ /* Flags below are new added. */ +/* Fallback: silently ignored if a service with the same name exists */ + +#define SVC_FALLBACK (1 << 28) + /* Override the previous definition for a service with the same name */ #define SVC_OVERRIDE (1 << 29)