]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #32389 from keszybz/bin-sbin-merge
authorLuca Boccassi <bluca@debian.org>
Mon, 22 Apr 2024 11:07:48 +0000 (13:07 +0200)
committerGitHub <noreply@github.com>
Mon, 22 Apr 2024 11:07:48 +0000 (13:07 +0200)
Try PATH without sbin even if compiled with split-bin=true

1  2 
src/basic/path-util.c
src/basic/path-util.h
src/core/manager.c

diff --combined src/basic/path-util.c
index 16b13ed628a488a17f7e4c78c808586109052d0f,5272477c2ac8deef4b4ecf0a2d8901a6e16dbae7..ad8d6d5b30d4d636da5d55472e47e14eca994ff4
@@@ -525,18 -525,6 +525,18 @@@ int path_compare_filename(const char *a
          return strcmp(fa, fb);
  }
  
 +int path_equal_or_inode_same_full(const char *a, const char *b, int flags) {
 +        /* Returns true if paths are of the same entry, false if not, <0 on error. */
 +
 +        if (path_equal(a, b))
 +                return 1;
 +
 +        if (!a || !b)
 +                return 0;
 +
 +        return inode_same(a, b, flags);
 +}
 +
  char* path_extend_internal(char **x, ...) {
          size_t sz, old_sz;
          char *q, *nx;
@@@ -696,7 -684,7 +696,7 @@@ int find_executable_full
                   * binary. */
                  p = getenv("PATH");
          if (!p)
-                 p = DEFAULT_PATH;
+                 p = default_PATH();
  
          if (exec_search_path) {
                  STRV_FOREACH(element, exec_search_path) {
@@@ -1453,3 -1441,31 +1453,31 @@@ int path_glob_can_match(const char *pat
                  *ret = NULL;
          return false;
  }
+ const char* default_PATH(void) {
+ #if HAVE_SPLIT_BIN
+         static int split = -1;
+         int r;
+         /* Check whether /usr/sbin is not a symlink and return the appropriate $PATH.
+          * On error fall back to the safe value with both directories as configured… */
+         if (split < 0)
+                 STRV_FOREACH_PAIR(bin, sbin, STRV_MAKE("/usr/bin", "/usr/sbin",
+                                                        "/usr/local/bin", "/usr/local/sbin")) {
+                         r = inode_same(*bin, *sbin, AT_NO_AUTOMOUNT);
+                         if (r > 0 || r == -ENOENT)
+                                 continue;
+                         if (r < 0)
+                                 log_debug_errno(r, "Failed to compare \"%s\" and \"%s\", using compat $PATH: %m",
+                                                 *bin, *sbin);
+                         split = true;
+                         break;
+                 }
+         if (split < 0)
+                 split = false;
+         if (split)
+                 return DEFAULT_PATH_WITH_SBIN;
+ #endif
+         return DEFAULT_PATH_WITHOUT_SBIN;
+ }
diff --combined src/basic/path-util.h
index 368e0001217067dc903d4bf311318edf5211c083,62a012d39f02ed968a55cd7f1e522a5c388b4266..fcb3aa93999a53bc87fc2a46cd946e3dad12948d
  #include "strv.h"
  #include "time-util.h"
  
- #define PATH_SPLIT_SBIN_BIN(x) x "sbin:" x "bin"
- #define PATH_SPLIT_SBIN_BIN_NULSTR(x) x "sbin\0" x "bin\0"
+ #define PATH_SPLIT_BIN(x) x "sbin:" x "bin"
+ #define PATH_SPLIT_BIN_NULSTR(x) x "sbin\0" x "bin\0"
  
- #define PATH_NORMAL_SBIN_BIN(x) x "bin"
- #define PATH_NORMAL_SBIN_BIN_NULSTR(x) x "bin\0"
+ #define PATH_MERGED_BIN(x) x "bin"
+ #define PATH_MERGED_BIN_NULSTR(x) x "bin\0"
  
- #if HAVE_SPLIT_BIN
- #  define PATH_SBIN_BIN(x) PATH_SPLIT_SBIN_BIN(x)
- #  define PATH_SBIN_BIN_NULSTR(x) PATH_SPLIT_SBIN_BIN_NULSTR(x)
- #else
- #  define PATH_SBIN_BIN(x) PATH_NORMAL_SBIN_BIN(x)
- #  define PATH_SBIN_BIN_NULSTR(x) PATH_NORMAL_SBIN_BIN_NULSTR(x)
- #endif
+ #define DEFAULT_PATH_WITH_SBIN PATH_SPLIT_BIN("/usr/local/") ":" PATH_SPLIT_BIN("/usr/")
+ #define DEFAULT_PATH_WITHOUT_SBIN PATH_MERGED_BIN("/usr/local/") ":" PATH_MERGED_BIN("/usr/")
  
- #define DEFAULT_PATH PATH_SBIN_BIN("/usr/local/") ":" PATH_SBIN_BIN("/usr/")
- #define DEFAULT_PATH_NULSTR PATH_SBIN_BIN_NULSTR("/usr/local/") PATH_SBIN_BIN_NULSTR("/usr/")
- #define DEFAULT_PATH_COMPAT PATH_SPLIT_SBIN_BIN("/usr/local/") ":" PATH_SPLIT_SBIN_BIN("/usr/") ":" PATH_SPLIT_SBIN_BIN("/")
+ #define DEFAULT_PATH_COMPAT PATH_SPLIT_BIN("/usr/local/") ":" PATH_SPLIT_BIN("/usr/") ":" PATH_SPLIT_BIN("/")
  
- #ifndef DEFAULT_USER_PATH
- #  define DEFAULT_USER_PATH DEFAULT_PATH
+ const char* default_PATH(void);
+ static inline const char* default_user_PATH(void) {
+ #ifdef DEFAULT_USER_PATH
+         return DEFAULT_USER_PATH;
+ #else
+         return default_PATH();
  #endif
+ }
  
  static inline bool is_path(const char *p) {
          if (!p) /* A NULL pointer is definitely not a path */
@@@ -68,9 -67,8 +67,9 @@@ static inline bool path_equal_filename(
          return path_compare_filename(a, b) == 0;
  }
  
 +int path_equal_or_inode_same_full(const char *a, const char *b, int flags);
  static inline bool path_equal_or_inode_same(const char *a, const char *b, int flags) {
 -        return path_equal(a, b) || inode_same(a, b, flags) > 0;
 +        return path_equal_or_inode_same_full(a, b, flags) > 0;
  }
  
  char* path_extend_internal(char **x, ...);
diff --combined src/core/manager.c
index d113089e3e3f6e91e8d2276ab8f78191c75dbcba,b627e7abc088c7f5f36288d0fcfbf5a1cf24ee15..564aa1022484a8c55dd7bc74a2feb6cbe47ac3f0
@@@ -658,8 -658,6 +658,6 @@@ static char** sanitize_environment(cha
  }
  
  int manager_default_environment(Manager *m) {
-         int r;
          assert(m);
  
          m->transient_environment = strv_free(m->transient_environment);
                   *
                   * The initial passed environment is untouched to keep /proc/self/environ valid; it is used
                   * for tagging the init process inside containers. */
-                 m->transient_environment = strv_new("PATH=" DEFAULT_PATH);
-                 if (!m->transient_environment)
+                 char *path = strjoin("PATH=", default_PATH());
+                 if (!path)
+                         return log_oom();
+                 if (strv_consume(&m->transient_environment, path) < 0)
                          return log_oom();
  
                  /* Import locale variables LC_*= from configuration */
                  if (!m->transient_environment)
                          return log_oom();
  
-                 r = strv_env_replace_strdup(&m->transient_environment, "PATH=" DEFAULT_USER_PATH);
-                 if (r < 0)
+                 char *path = strjoin("PATH=", default_user_PATH());
+                 if (!path)
+                         return log_oom();
+                 if (strv_env_replace_consume(&m->transient_environment, path) < 0)
                          return log_oom();
  
                  /* Envvars set for our 'manager' class session are private and should not be propagated
@@@ -1974,15 -1978,6 +1978,15 @@@ int manager_startup(Manager *m, FILE *s
                                  return log_error_errno(r, "Deserialization failed: %m");
                  }
  
 +                if (m->previous_objective >= 0) {
 +                        if (IN_SET(m->previous_objective, MANAGER_REEXECUTE, MANAGER_SOFT_REBOOT, MANAGER_SWITCH_ROOT))
 +                                log_debug("Launching as effect of a '%s' operation.",
 +                                          manager_objective_to_string(m->previous_objective));
 +                        else
 +                                log_warning("Got unexpected previous objective '%s', ignoring.",
 +                                            manager_objective_to_string(m->previous_objective));
 +                }
 +
                  /* If we are in a new soft-reboot iteration bump the counter now before starting units, so
                   * that they can reliably read it. We get the previous objective from serialized state. */
                  if (m->previous_objective == MANAGER_SOFT_REBOOT)
@@@ -3707,15 -3702,13 +3711,15 @@@ static void manager_notify_finished(Man
          if (MANAGER_IS_SYSTEM(m) && m->soft_reboots_count > 0) {
                  /* The soft-reboot case, where we only report data for the last reboot */
                  firmware_usec = loader_usec = initrd_usec = kernel_usec = 0;
 -                total_usec = userspace_usec = usec_sub_unsigned(m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic, m->timestamps[MANAGER_TIMESTAMP_SHUTDOWN_START].monotonic);
 +                total_usec = userspace_usec = usec_sub_unsigned(m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic,
 +                                                                m->timestamps[MANAGER_TIMESTAMP_SHUTDOWN_START].monotonic);
  
                  log_struct(LOG_INFO,
                             "MESSAGE_ID=" SD_MESSAGE_STARTUP_FINISHED_STR,
                             "USERSPACE_USEC="USEC_FMT, userspace_usec,
 -                           LOG_MESSAGE("Soft-reboot finished in %s.",
 -                                       FORMAT_TIMESPAN(total_usec, USEC_PER_MSEC)));
 +                           LOG_MESSAGE("Soft-reboot finished in %s, counter is now at %u.",
 +                                       FORMAT_TIMESPAN(total_usec, USEC_PER_MSEC),
 +                                       m->soft_reboots_count));
          } else if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) {
                  char buf[FORMAT_TIMESPAN_MAX + STRLEN(" (firmware) + ") + FORMAT_TIMESPAN_MAX + STRLEN(" (loader) + ")]
                          = {};
@@@ -4422,7 -4415,7 +4426,7 @@@ void manager_override_show_status(Manag
          set_show_status_marker(show_status_on(mode));
  }
  
 -const char *manager_get_confirm_spawn(Manager *m) {
 +const charmanager_get_confirm_spawn(Manager *m) {
          static int last_errno = 0;
          struct stat st;
          int r;
@@@ -5045,7 -5038,7 +5049,7 @@@ LogTarget manager_get_executor_log_targ
          return LOG_TARGET_KMSG;
  }
  
 -static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
 +static const charconst manager_state_table[_MANAGER_STATE_MAX] = {
          [MANAGER_INITIALIZING] = "initializing",
          [MANAGER_STARTING]     = "starting",
          [MANAGER_RUNNING]      = "running",
  
  DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState);
  
 -static const char *const manager_timestamp_table[_MANAGER_TIMESTAMP_MAX] = {
 +static const char* const manager_objective_table[_MANAGER_OBJECTIVE_MAX] = {
 +        [MANAGER_OK]          = "ok",
 +        [MANAGER_EXIT]        = "exit",
 +        [MANAGER_RELOAD]      = "reload",
 +        [MANAGER_REEXECUTE]   = "reexecute",
 +        [MANAGER_REBOOT]      = "reboot",
 +        [MANAGER_SOFT_REBOOT] = "soft-reboot",
 +        [MANAGER_POWEROFF]    = "poweroff",
 +        [MANAGER_HALT]        = "halt",
 +        [MANAGER_KEXEC]       = "kexec",
 +        [MANAGER_SWITCH_ROOT] = "switch-root",
 +};
 +
 +DEFINE_STRING_TABLE_LOOKUP(manager_objective, ManagerObjective);
 +
 +static const char* const manager_timestamp_table[_MANAGER_TIMESTAMP_MAX] = {
          [MANAGER_TIMESTAMP_FIRMWARE]                 = "firmware",
          [MANAGER_TIMESTAMP_LOADER]                   = "loader",
          [MANAGER_TIMESTAMP_KERNEL]                   = "kernel",