diff --git a/system/nxinit/builtin.c b/system/nxinit/builtin.c index 5ed7f3a29fe..c12f8cef4cb 100644 --- a/system/nxinit/builtin.c +++ b/system/nxinit/builtin.c @@ -25,16 +25,23 @@ ****************************************************************************/ #include +#include #include #include #include #include +#include #include +#include #include #include #include +#ifdef CONFIG_RPTUN +#include +#endif + #include "builtin.h" #include "init.h" #include "property.h" @@ -91,6 +98,12 @@ static int cmd_start_cpu(FAR struct action_manager_s *am, static int cmd_netinit(FAR struct action_manager_s *am, int argc, FAR char **argv); #endif +#ifdef CONFIG_RPTUN +static int cmd_rptun(FAR struct action_manager_s *am, + int argc, FAR char **argv); +#endif +static int cmd_unlink(FAR struct action_manager_s *am, + int argc, FAR char **argv); /**************************************************************************** * Private Data @@ -120,6 +133,10 @@ static const struct cmd_map_s g_builtin[] = {"start", 2, 2, cmd_start}, {"stop", 2, 2, cmd_stop}, {"trigger", 2, 2, cmd_trigger}, +#ifdef CONFIG_RPTUN + {"rptun", 3, 3, cmd_rptun}, +#endif + {"unlink", 2, 2, cmd_unlink}, }; /**************************************************************************** @@ -269,6 +286,63 @@ static int cmd_exec(FAR struct action_manager_s *am, return -EINVAL; } +#ifdef CONFIG_RPTUN +static int cmd_rptun(FAR struct action_manager_s *am, + int argc, FAR char **argv) +{ + int fd; + int ret; + + UNUSED(am); + + fd = open(argv[2], O_WRONLY | O_CLOEXEC); + if (fd < 0) + { + init_err("rptun %s: open '%s' failed: %d", + argv[1], argv[2], errno); + return -errno; + } + + if (!strcmp(argv[1], "start")) + { + ret = ioctl(fd, RPTUNIOC_START, 0); + } + else if (!strcmp(argv[1], "stop")) + { + ret = ioctl(fd, RPTUNIOC_STOP, 0); + } + else + { + init_err("rptun: unknown command '%s'", argv[1]); + ret = -EINVAL; + } + + if (ret < 0) + { + init_err("rptun %s: failed: %d", argv[1], errno); + } + + close(fd); + return ret < 0 ? ret : 0; +} +#endif + +static int cmd_unlink(FAR struct action_manager_s *am, + int argc, FAR char **argv) +{ + int ret; + + UNUSED(am); + + ret = unlink(argv[1]); + if (ret < 0) + { + init_err("unlink '%s' failed: %d", argv[1], errno); + } + + return ret; +} + /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/system/nxinit/service.c b/system/nxinit/service.c index 8a92bb20baf..d3dbecb1aac 100644 --- a/system/nxinit/service.c +++ b/system/nxinit/service.c @@ -96,6 +96,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, @@ -114,6 +116,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}, #ifdef CONFIG_BOARDCTL_RESET @@ -131,6 +134,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 @@ -253,6 +257,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) { @@ -279,6 +293,7 @@ static int option_reboot_on_failure(FAR struct service_manager_s *sm, { FAR struct service_s *s = list_last_entry(&sm->services, struct service_s, node); + s->reset_reason = atoi(argv[1]); return 0; } @@ -649,17 +664,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 64520064886..bf93154b656 100644 --- a/system/nxinit/service.h +++ b/system/nxinit/service.h @@ -54,6 +54,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)