This is an automated email from the ASF dual-hosted git repository.

GUIDINGLI pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit 2085e1ca962457b57cb85d4ec4fa214413472c1b
Author: wangjianyu3 <[email protected]>
AuthorDate: Fri Aug 28 21:14:06 2026 +0800

    system/nxinit: add fallback option to resolve preset service conflict
    
    The preset kvdb service defined in parser.c conflicts with user-defined
    kvdb service in board-level init.rc, causing:
    
      Error redefined service 'kvdb'
    
    Add SVC_FALLBACK flag and fallback service option. When a service
    is marked as fallback, it will be silently ignored if another
    service with the same name already exists. This is the semantic
    opposite of override:
    
    - override: new definition replaces old
    - fallback: new definition yields to old
    - old has fallback + new arrives: old yields to new
    
    If neither flag is set, duplicate service names still produce
    EEXIST error as before.
    
    Mark the preset kvdb service as fallback so that board-specific
    init.rc can freely define its own kvdb service without conflict.
    
    Signed-off-by: wangjianyu3 <[email protected]>
---
 system/nxinit/service.c | 38 +++++++++++++++++++++++++++++++++-----
 system/nxinit/service.h |  4 ++++
 2 files changed, 37 insertions(+), 5 deletions(-)

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)

Reply via email to