import systemd-239-58.el8_6.8
This commit is contained in:
		
							parent
							
								
									3494a638bc
								
							
						
					
					
						commit
						c7097e3e7c
					
				| @ -0,0 +1,181 @@ | |||||||
|  | From d4caf8718db1d2dddf7f87cbc192cff401ebcf59 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Lennart Poettering <lennart@poettering.net> | ||||||
|  | Date: Mon, 25 May 2020 00:34:58 +0200 | ||||||
|  | Subject: [PATCH] unit-name: tighten checks for building valid unit names | ||||||
|  | 
 | ||||||
|  | Let's be more thorough that whenever we build a unit name based on | ||||||
|  | parameters, that the result is actually a valid user name. If it isn't | ||||||
|  | fail early. | ||||||
|  | 
 | ||||||
|  | This should allows us to catch various issues earlier, in particular | ||||||
|  | when we synthesize mount units from /proc/self/mountinfo: instead of | ||||||
|  | actually attempting to allocate a mount unit we will fail much earlier | ||||||
|  | when we build the name to synthesize the unit under. Failing early is a | ||||||
|  | good thing generally. | ||||||
|  | 
 | ||||||
|  | (cherry picked from commit ab19db01ae1826efb3cbdf6dcb6a14412f8844d4) | ||||||
|  | 
 | ||||||
|  | Related: #2094712 | ||||||
|  | ---
 | ||||||
|  |  src/basic/unit-name.c | 61 ++++++++++++++++++++++++++++++------------- | ||||||
|  |  1 file changed, 43 insertions(+), 18 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c
 | ||||||
|  | index 614eb8649b..f9b3fafd4d 100644
 | ||||||
|  | --- a/src/basic/unit-name.c
 | ||||||
|  | +++ b/src/basic/unit-name.c
 | ||||||
|  | @@ -207,8 +207,9 @@ UnitType unit_name_to_type(const char *n) {
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int unit_name_change_suffix(const char *n, const char *suffix, char **ret) { | ||||||
|  | -        char *e, *s;
 | ||||||
|  | +        _cleanup_free_ char *s = NULL;
 | ||||||
|  |          size_t a, b; | ||||||
|  | +        char *e;
 | ||||||
|  |   | ||||||
|  |          assert(n); | ||||||
|  |          assert(suffix); | ||||||
|  | @@ -230,8 +231,12 @@ int unit_name_change_suffix(const char *n, const char *suffix, char **ret) {
 | ||||||
|  |                  return -ENOMEM; | ||||||
|  |   | ||||||
|  |          strcpy(mempcpy(s, n, a), suffix); | ||||||
|  | -        *ret = s;
 | ||||||
|  |   | ||||||
|  | +        /* Make sure the name is still valid (i.e. didn't grow too large due to longer suffix) */
 | ||||||
|  | +        if (!unit_name_is_valid(s, UNIT_NAME_ANY))
 | ||||||
|  | +                return -EINVAL;
 | ||||||
|  | +
 | ||||||
|  | +        *ret = TAKE_PTR(s);
 | ||||||
|  |          return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -253,8 +258,8 @@ int unit_name_build(const char *prefix, const char *instance, const char *suffix
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int unit_name_build_from_type(const char *prefix, const char *instance, UnitType type, char **ret) { | ||||||
|  | +        _cleanup_free_ char *s = NULL;
 | ||||||
|  |          const char *ut; | ||||||
|  | -        char *s;
 | ||||||
|  |   | ||||||
|  |          assert(prefix); | ||||||
|  |          assert(type >= 0); | ||||||
|  | @@ -264,19 +269,23 @@ int unit_name_build_from_type(const char *prefix, const char *instance, UnitType
 | ||||||
|  |          if (!unit_prefix_is_valid(prefix)) | ||||||
|  |                  return -EINVAL; | ||||||
|  |   | ||||||
|  | -        if (instance && !unit_instance_is_valid(instance))
 | ||||||
|  | -                return -EINVAL;
 | ||||||
|  | -
 | ||||||
|  |          ut = unit_type_to_string(type); | ||||||
|  |   | ||||||
|  | -        if (!instance)
 | ||||||
|  | -                s = strjoin(prefix, ".", ut);
 | ||||||
|  | -        else
 | ||||||
|  | +        if (instance) {
 | ||||||
|  | +                if (!unit_instance_is_valid(instance))
 | ||||||
|  | +                        return -EINVAL;
 | ||||||
|  | +
 | ||||||
|  |                  s = strjoin(prefix, "@", instance, ".", ut); | ||||||
|  | +        } else
 | ||||||
|  | +                s = strjoin(prefix, ".", ut);
 | ||||||
|  |          if (!s) | ||||||
|  |                  return -ENOMEM; | ||||||
|  |   | ||||||
|  | -        *ret = s;
 | ||||||
|  | +        /* Verify that this didn't grow too large (or otherwise is invalid) */
 | ||||||
|  | +        if (!unit_name_is_valid(s, instance ? UNIT_NAME_INSTANCE : UNIT_NAME_PLAIN))
 | ||||||
|  | +                return -EINVAL;
 | ||||||
|  | +
 | ||||||
|  | +        *ret = TAKE_PTR(s);
 | ||||||
|  |          return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -445,8 +454,8 @@ int unit_name_path_unescape(const char *f, char **ret) {
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int unit_name_replace_instance(const char *f, const char *i, char **ret) { | ||||||
|  | +        _cleanup_free_ char *s = NULL;
 | ||||||
|  |          const char *p, *e; | ||||||
|  | -        char *s;
 | ||||||
|  |          size_t a, b; | ||||||
|  |   | ||||||
|  |          assert(f); | ||||||
|  | @@ -470,7 +479,11 @@ int unit_name_replace_instance(const char *f, const char *i, char **ret) {
 | ||||||
|  |   | ||||||
|  |          strcpy(mempcpy(mempcpy(s, f, a + 1), i, b), e); | ||||||
|  |   | ||||||
|  | -        *ret = s;
 | ||||||
|  | +        /* Make sure the resulting name still is valid, i.e. didn't grow too large */
 | ||||||
|  | +        if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE))
 | ||||||
|  | +                return -EINVAL;
 | ||||||
|  | +
 | ||||||
|  | +        *ret = TAKE_PTR(s);
 | ||||||
|  |          return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -501,8 +514,7 @@ int unit_name_template(const char *f, char **ret) {
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int unit_name_from_path(const char *path, const char *suffix, char **ret) { | ||||||
|  | -        _cleanup_free_ char *p = NULL;
 | ||||||
|  | -        char *s = NULL;
 | ||||||
|  | +        _cleanup_free_ char *p = NULL, *s = NULL;
 | ||||||
|  |          int r; | ||||||
|  |   | ||||||
|  |          assert(path); | ||||||
|  | @@ -520,7 +532,11 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret) {
 | ||||||
|  |          if (!s) | ||||||
|  |                  return -ENOMEM; | ||||||
|  |   | ||||||
|  | -        *ret = s;
 | ||||||
|  | +        /* Refuse this if this got too long or for some other reason didn't result in a valid name */
 | ||||||
|  | +        if (!unit_name_is_valid(s, UNIT_NAME_PLAIN))
 | ||||||
|  | +                return -EINVAL;
 | ||||||
|  | +
 | ||||||
|  | +        *ret = TAKE_PTR(s);
 | ||||||
|  |          return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -548,6 +564,10 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha
 | ||||||
|  |          if (!s) | ||||||
|  |                  return -ENOMEM; | ||||||
|  |   | ||||||
|  | +        /* Refuse this if this got too long or for some other reason didn't result in a valid name */
 | ||||||
|  | +        if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE))
 | ||||||
|  | +                return -EINVAL;
 | ||||||
|  | +
 | ||||||
|  |          *ret = s; | ||||||
|  |          return 0; | ||||||
|  |  } | ||||||
|  | @@ -601,7 +621,7 @@ static bool do_escape_mangle(const char *f, bool allow_globs, char *t) {
 | ||||||
|  |   *  If @allow_globs, globs characters are preserved. Otherwise, they are escaped. | ||||||
|  |   */ | ||||||
|  |  int unit_name_mangle_with_suffix(const char *name, UnitNameMangle flags, const char *suffix, char **ret) { | ||||||
|  | -        char *s;
 | ||||||
|  | +        _cleanup_free_ char *s = NULL;
 | ||||||
|  |          int r; | ||||||
|  |          bool mangled; | ||||||
|  |   | ||||||
|  | @@ -656,7 +676,12 @@ int unit_name_mangle_with_suffix(const char *name, UnitNameMangle flags, const c
 | ||||||
|  |          if ((!(flags & UNIT_NAME_MANGLE_GLOB) || !string_is_glob(s)) && unit_name_to_type(s) < 0) | ||||||
|  |                  strcat(s, suffix); | ||||||
|  |   | ||||||
|  | -        *ret = s;
 | ||||||
|  | +        /* Make sure mangling didn't grow this too large (but don't do this check if globbing is allowed,
 | ||||||
|  | +         * since globs generally do not qualify as valid unit names) */
 | ||||||
|  | +        if (!FLAGS_SET(flags, UNIT_NAME_MANGLE_GLOB) && !unit_name_is_valid(s, UNIT_NAME_ANY))
 | ||||||
|  | +                return -EINVAL;
 | ||||||
|  | +
 | ||||||
|  | +        *ret = TAKE_PTR(s);
 | ||||||
|  |          return 1; | ||||||
|  |   | ||||||
|  |  good: | ||||||
|  | @@ -664,7 +689,7 @@ good:
 | ||||||
|  |          if (!s) | ||||||
|  |                  return -ENOMEM; | ||||||
|  |   | ||||||
|  | -        *ret = s;
 | ||||||
|  | +        *ret = TAKE_PTR(s);
 | ||||||
|  |          return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
| @ -0,0 +1,275 @@ | |||||||
|  | From b2cfcb1f3801ae007698fce9139b39cefdfd66e1 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Michal Sekletar <msekleta@redhat.com> | ||||||
|  | Date: Tue, 15 Mar 2022 19:02:05 +0100 | ||||||
|  | Subject: [PATCH] core: shorten long unit names that are based on paths and | ||||||
|  |  append path hash at the end | ||||||
|  | 
 | ||||||
|  | Fixes #18077 | ||||||
|  | 
 | ||||||
|  | (cherry picked from commit 1d0727e76fd5e9a07cc9991ec9a10ea1d78a99c7) | ||||||
|  | 
 | ||||||
|  | Resolves: #2094712 | ||||||
|  | ---
 | ||||||
|  |  src/basic/string-util.h   | 23 +++++----- | ||||||
|  |  src/basic/unit-name.c     | 88 ++++++++++++++++++++++++++++++++++++++- | ||||||
|  |  src/basic/unit-name.h     |  3 ++ | ||||||
|  |  src/core/mount.c          |  3 ++ | ||||||
|  |  src/test/test-unit-name.c | 25 ++++++++++- | ||||||
|  |  5 files changed, 129 insertions(+), 13 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/src/basic/string-util.h b/src/basic/string-util.h
 | ||||||
|  | index 742b566932..0d406ff64a 100644
 | ||||||
|  | --- a/src/basic/string-util.h
 | ||||||
|  | +++ b/src/basic/string-util.h
 | ||||||
|  | @@ -9,17 +9,18 @@
 | ||||||
|  |  #include "macro.h" | ||||||
|  |   | ||||||
|  |  /* What is interpreted as whitespace? */ | ||||||
|  | -#define WHITESPACE        " \t\n\r"
 | ||||||
|  | -#define NEWLINE           "\n\r"
 | ||||||
|  | -#define QUOTES            "\"\'"
 | ||||||
|  | -#define COMMENTS          "#;"
 | ||||||
|  | -#define GLOB_CHARS        "*?["
 | ||||||
|  | -#define DIGITS            "0123456789"
 | ||||||
|  | -#define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz"
 | ||||||
|  | -#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 | ||||||
|  | -#define LETTERS           LOWERCASE_LETTERS UPPERCASE_LETTERS
 | ||||||
|  | -#define ALPHANUMERICAL    LETTERS DIGITS
 | ||||||
|  | -#define HEXDIGITS         DIGITS "abcdefABCDEF"
 | ||||||
|  | +#define WHITESPACE          " \t\n\r"
 | ||||||
|  | +#define NEWLINE             "\n\r"
 | ||||||
|  | +#define QUOTES              "\"\'"
 | ||||||
|  | +#define COMMENTS            "#;"
 | ||||||
|  | +#define GLOB_CHARS          "*?["
 | ||||||
|  | +#define DIGITS              "0123456789"
 | ||||||
|  | +#define LOWERCASE_LETTERS   "abcdefghijklmnopqrstuvwxyz"
 | ||||||
|  | +#define UPPERCASE_LETTERS   "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 | ||||||
|  | +#define LETTERS             LOWERCASE_LETTERS UPPERCASE_LETTERS
 | ||||||
|  | +#define ALPHANUMERICAL      LETTERS DIGITS
 | ||||||
|  | +#define HEXDIGITS           DIGITS "abcdefABCDEF"
 | ||||||
|  | +#define LOWERCASE_HEXDIGITS DIGITS "abcdef"
 | ||||||
|  |   | ||||||
|  |  #define streq(a,b) (strcmp((a),(b)) == 0) | ||||||
|  |  #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) | ||||||
|  | diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c
 | ||||||
|  | index f9b3fafd4d..65ed979e39 100644
 | ||||||
|  | --- a/src/basic/unit-name.c
 | ||||||
|  | +++ b/src/basic/unit-name.c
 | ||||||
|  | @@ -6,11 +6,17 @@
 | ||||||
|  |  #include <stdlib.h> | ||||||
|  |  #include <string.h> | ||||||
|  |   | ||||||
|  | +#include "sd-id128.h"
 | ||||||
|  | +
 | ||||||
|  |  #include "alloc-util.h" | ||||||
|  |  #include "glob-util.h" | ||||||
|  |  #include "hexdecoct.h" | ||||||
|  |  #include "path-util.h" | ||||||
|  | +#include "random-util.h"
 | ||||||
|  | +#include "siphash24.h"
 | ||||||
|  | +#include "sparse-endian.h"
 | ||||||
|  |  #include "special.h" | ||||||
|  | +#include "stdio-util.h"
 | ||||||
|  |  #include "string-util.h" | ||||||
|  |  #include "strv.h" | ||||||
|  |  #include "unit-name.h" | ||||||
|  | @@ -31,6 +37,9 @@
 | ||||||
|  |          VALID_CHARS_WITH_AT                     \ | ||||||
|  |          "[]!-*?" | ||||||
|  |   | ||||||
|  | +#define LONG_UNIT_NAME_HASH_KEY SD_ID128_MAKE(ec,f2,37,fb,58,32,4a,32,84,9f,06,9b,0d,21,eb,9a)
 | ||||||
|  | +#define UNIT_NAME_HASH_LENGTH_CHARS 16
 | ||||||
|  | +
 | ||||||
|  |  bool unit_name_is_valid(const char *n, UnitNameFlags flags) { | ||||||
|  |          const char *e, *i, *at; | ||||||
|  |   | ||||||
|  | @@ -513,6 +522,68 @@ int unit_name_template(const char *f, char **ret) {
 | ||||||
|  |          return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +bool unit_name_is_hashed(const char *name) {
 | ||||||
|  | +        char *s;
 | ||||||
|  | +
 | ||||||
|  | +        if (!unit_name_is_valid(name, UNIT_NAME_PLAIN))
 | ||||||
|  | +                return false;
 | ||||||
|  | +
 | ||||||
|  | +        assert_se(s = strrchr(name, '.'));
 | ||||||
|  | +
 | ||||||
|  | +        if (s - name < UNIT_NAME_HASH_LENGTH_CHARS + 1)
 | ||||||
|  | +                return false;
 | ||||||
|  | +
 | ||||||
|  | +        s -= UNIT_NAME_HASH_LENGTH_CHARS;
 | ||||||
|  | +        if (s[-1] != '_')
 | ||||||
|  | +                return false;
 | ||||||
|  | +
 | ||||||
|  | +        for (size_t i = 0; i < UNIT_NAME_HASH_LENGTH_CHARS; i++)
 | ||||||
|  | +                if (!strchr(LOWERCASE_HEXDIGITS, s[i]))
 | ||||||
|  | +                        return false;
 | ||||||
|  | +
 | ||||||
|  | +        return true;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +int unit_name_hash_long(const char *name, char **ret) {
 | ||||||
|  | +        _cleanup_free_ char *n = NULL, *hash = NULL;
 | ||||||
|  | +        char *suffix;
 | ||||||
|  | +        le64_t h;
 | ||||||
|  | +        size_t len;
 | ||||||
|  | +
 | ||||||
|  | +        if (strlen(name) < UNIT_NAME_MAX)
 | ||||||
|  | +                return -EMSGSIZE;
 | ||||||
|  | +
 | ||||||
|  | +        suffix = strrchr(name, '.');
 | ||||||
|  | +        if (!suffix)
 | ||||||
|  | +                return -EINVAL;
 | ||||||
|  | +
 | ||||||
|  | +        if (unit_type_from_string(suffix+1) < 0)
 | ||||||
|  | +                return -EINVAL;
 | ||||||
|  | +
 | ||||||
|  | +        h = htole64(siphash24(name, strlen(name) + 1, LONG_UNIT_NAME_HASH_KEY.bytes));
 | ||||||
|  | +
 | ||||||
|  | +        hash = hexmem(&h, sizeof(h));
 | ||||||
|  | +        if (!hash)
 | ||||||
|  | +                return -ENOMEM;
 | ||||||
|  | +
 | ||||||
|  | +        assert_se(strlen(hash) == UNIT_NAME_HASH_LENGTH_CHARS);
 | ||||||
|  | +
 | ||||||
|  | +        len = UNIT_NAME_MAX - 1 - strlen(suffix+1) - UNIT_NAME_HASH_LENGTH_CHARS - 2;
 | ||||||
|  | +        assert(len > 0 && len < UNIT_NAME_MAX);
 | ||||||
|  | +
 | ||||||
|  | +        n = strndup(name, len);
 | ||||||
|  | +        if (!n)
 | ||||||
|  | +                return -ENOMEM;
 | ||||||
|  | +
 | ||||||
|  | +        if (!strextend(&n, "_", hash, suffix, NULL))
 | ||||||
|  | +                return -ENOMEM;
 | ||||||
|  | +        assert_se(unit_name_is_valid(n, UNIT_NAME_PLAIN));
 | ||||||
|  | +
 | ||||||
|  | +        *ret = TAKE_PTR(n);
 | ||||||
|  | +
 | ||||||
|  | +        return 0;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  int unit_name_from_path(const char *path, const char *suffix, char **ret) { | ||||||
|  |          _cleanup_free_ char *p = NULL, *s = NULL; | ||||||
|  |          int r; | ||||||
|  | @@ -532,7 +603,19 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret) {
 | ||||||
|  |          if (!s) | ||||||
|  |                  return -ENOMEM; | ||||||
|  |   | ||||||
|  | -        /* Refuse this if this got too long or for some other reason didn't result in a valid name */
 | ||||||
|  | +        if (strlen(s) >= UNIT_NAME_MAX) {
 | ||||||
|  | +                _cleanup_free_ char *n = NULL;
 | ||||||
|  | +
 | ||||||
|  | +                log_debug("Unit name \"%s\" too long, falling back to hashed unit name.", s);
 | ||||||
|  | +
 | ||||||
|  | +                r = unit_name_hash_long(s, &n);
 | ||||||
|  | +                if (r < 0)
 | ||||||
|  | +                        return r;
 | ||||||
|  | +
 | ||||||
|  | +                free_and_replace(s, n);
 | ||||||
|  | +        }
 | ||||||
|  | +
 | ||||||
|  | +        /* Refuse if this for some other reason didn't result in a valid name */
 | ||||||
|  |          if (!unit_name_is_valid(s, UNIT_NAME_PLAIN)) | ||||||
|  |                  return -EINVAL; | ||||||
|  |   | ||||||
|  | @@ -582,6 +665,9 @@ int unit_name_to_path(const char *name, char **ret) {
 | ||||||
|  |          if (r < 0) | ||||||
|  |                  return r; | ||||||
|  |   | ||||||
|  | +        if (unit_name_is_hashed(name))
 | ||||||
|  | +                return -ENAMETOOLONG;
 | ||||||
|  | +
 | ||||||
|  |          return unit_name_path_unescape(prefix, ret); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h
 | ||||||
|  | index 61abcd585b..602295af8f 100644
 | ||||||
|  | --- a/src/basic/unit-name.h
 | ||||||
|  | +++ b/src/basic/unit-name.h
 | ||||||
|  | @@ -45,6 +45,9 @@ int unit_name_replace_instance(const char *f, const char *i, char **ret);
 | ||||||
|  |   | ||||||
|  |  int unit_name_template(const char *f, char **ret); | ||||||
|  |   | ||||||
|  | +int unit_name_hash_long(const char *name, char **ret);
 | ||||||
|  | +bool unit_name_is_hashed(const char *name);
 | ||||||
|  | +
 | ||||||
|  |  int unit_name_from_path(const char *path, const char *suffix, char **ret); | ||||||
|  |  int unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix, char **ret); | ||||||
|  |  int unit_name_to_path(const char *name, char **ret); | ||||||
|  | diff --git a/src/core/mount.c b/src/core/mount.c
 | ||||||
|  | index d37b5731f8..e69ecb7ce3 100644
 | ||||||
|  | --- a/src/core/mount.c
 | ||||||
|  | +++ b/src/core/mount.c
 | ||||||
|  | @@ -572,6 +572,9 @@ static int mount_add_extras(Mount *m) {
 | ||||||
|  |   | ||||||
|  |          if (!m->where) { | ||||||
|  |                  r = unit_name_to_path(u->id, &m->where); | ||||||
|  | +                if (r == -ENAMETOOLONG)
 | ||||||
|  | +                        log_unit_error_errno(u, r, "Failed to derive mount point path from unit name, because unit name is hashed. "
 | ||||||
|  | +                                                   "Set \"Where=\" in the unit file explicitly.");
 | ||||||
|  |                  if (r < 0) | ||||||
|  |                          return r; | ||||||
|  |          } | ||||||
|  | diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
 | ||||||
|  | index 2b00ef8cb7..35cfaafd30 100644
 | ||||||
|  | --- a/src/test/test-unit-name.c
 | ||||||
|  | +++ b/src/test/test-unit-name.c
 | ||||||
|  | @@ -82,6 +82,7 @@ static void test_unit_name_replace_instance(void) {
 | ||||||
|  |   | ||||||
|  |  static void test_unit_name_from_path_one(const char *path, const char *suffix, const char *expected, int ret) { | ||||||
|  |          _cleanup_free_ char *t = NULL; | ||||||
|  | +        int r;
 | ||||||
|  |   | ||||||
|  |          assert_se(unit_name_from_path(path, suffix, &t) == ret); | ||||||
|  |          puts(strna(t)); | ||||||
|  | @@ -89,12 +90,31 @@ static void test_unit_name_from_path_one(const char *path, const char *suffix, c
 | ||||||
|  |   | ||||||
|  |          if (t) { | ||||||
|  |                  _cleanup_free_ char *k = NULL; | ||||||
|  | -                assert_se(unit_name_to_path(t, &k) == 0);
 | ||||||
|  | +
 | ||||||
|  | +                /* We don't support converting hashed unit names back to paths */
 | ||||||
|  | +                r = unit_name_to_path(t, &k);
 | ||||||
|  | +                if (r == -ENAMETOOLONG)
 | ||||||
|  | +                        return;
 | ||||||
|  | +                assert(r == 0);
 | ||||||
|  | +
 | ||||||
|  |                  puts(strna(k)); | ||||||
|  |                  assert_se(path_equal(k, empty_to_root(path))); | ||||||
|  |          } | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static void test_unit_name_is_hashed(void) {
 | ||||||
|  | +        assert_se(!unit_name_is_hashed(""));
 | ||||||
|  | +        assert_se(!unit_name_is_hashed("foo@bar.service"));
 | ||||||
|  | +        assert_se(!unit_name_is_hashed("foo@.service"));
 | ||||||
|  | +        assert_se(unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_7736d9ed33c2ec55.mount"));
 | ||||||
|  | +        assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_7736D9ED33C2EC55.mount"));
 | ||||||
|  | +        assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!7736d9ed33c2ec55.mount"));
 | ||||||
|  | +        assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_7736d9gd33c2ec55.mount"));
 | ||||||
|  | +        assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_.mount"));
 | ||||||
|  | +        assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_2103e1466b87f7f7@waldo.mount"));
 | ||||||
|  | +        assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_2103e1466b87f7f7@.mount"));
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static void test_unit_name_from_path(void) { | ||||||
|  |          puts("-------------------------------------------------"); | ||||||
|  |          test_unit_name_from_path_one("/waldo", ".mount", "waldo.mount", 0); | ||||||
|  | @@ -105,6 +125,8 @@ static void test_unit_name_from_path(void) {
 | ||||||
|  |          test_unit_name_from_path_one("///", ".mount", "-.mount", 0); | ||||||
|  |          test_unit_name_from_path_one("/foo/../bar", ".mount", NULL, -EINVAL); | ||||||
|  |          test_unit_name_from_path_one("/foo/./bar", ".mount", NULL, -EINVAL); | ||||||
|  | +        test_unit_name_from_path_one("/waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ".mount",
 | ||||||
|  | +                                     "waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_7736d9ed33c2ec55.mount", 0);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void test_unit_name_from_path_instance_one(const char *pattern, const char *path, const char *suffix, const char *expected, int ret) { | ||||||
|  | @@ -824,6 +846,7 @@ int main(int argc, char* argv[]) {
 | ||||||
|  |   | ||||||
|  |          test_unit_name_is_valid(); | ||||||
|  |          test_unit_name_replace_instance(); | ||||||
|  | +        test_unit_name_is_hashed();
 | ||||||
|  |          test_unit_name_from_path(); | ||||||
|  |          test_unit_name_from_path_instance(); | ||||||
|  |          test_unit_name_mangle(); | ||||||
| @ -0,0 +1,162 @@ | |||||||
|  | From 294efa52d47be083704da51b148c685d347be4ac Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Anita Zhang <the.anitazha@gmail.com> | ||||||
|  | Date: Tue, 8 Jun 2021 00:04:35 -0700 | ||||||
|  | Subject: [PATCH] test: add extended test for triggering mount rate limit | ||||||
|  | 
 | ||||||
|  | It's hard to trigger the failure to exit the rate limit state in | ||||||
|  | isolation as it needs multiple event sources in order to show that it | ||||||
|  | gets stuck in the queue. Hence why this is an extended test. | ||||||
|  | 
 | ||||||
|  | (cherry picked from commit 0c81900965a72b29eb76e0737ed899b925ee75b6) | ||||||
|  | 
 | ||||||
|  | Related: #2094712 | ||||||
|  | ---
 | ||||||
|  |  test/TEST-60-MOUNT-RATELIMIT/Makefile     |  1 + | ||||||
|  |  test/TEST-60-MOUNT-RATELIMIT/test.sh      | 48 +++++++++++++++ | ||||||
|  |  test/TEST-60-MOUNT-RATELIMIT/testsuite.sh | 73 +++++++++++++++++++++++ | ||||||
|  |  3 files changed, 122 insertions(+) | ||||||
|  |  create mode 120000 test/TEST-60-MOUNT-RATELIMIT/Makefile | ||||||
|  |  create mode 100755 test/TEST-60-MOUNT-RATELIMIT/test.sh | ||||||
|  |  create mode 100755 test/TEST-60-MOUNT-RATELIMIT/testsuite.sh | ||||||
|  | 
 | ||||||
|  | diff --git a/test/TEST-60-MOUNT-RATELIMIT/Makefile b/test/TEST-60-MOUNT-RATELIMIT/Makefile
 | ||||||
|  | new file mode 120000 | ||||||
|  | index 0000000000..e9f93b1104
 | ||||||
|  | --- /dev/null
 | ||||||
|  | +++ b/test/TEST-60-MOUNT-RATELIMIT/Makefile
 | ||||||
|  | @@ -0,0 +1 @@
 | ||||||
|  | +../TEST-01-BASIC/Makefile
 | ||||||
|  | \ No newline at end of file | ||||||
|  | diff --git a/test/TEST-60-MOUNT-RATELIMIT/test.sh b/test/TEST-60-MOUNT-RATELIMIT/test.sh
 | ||||||
|  | new file mode 100755 | ||||||
|  | index 0000000000..e3c9288546
 | ||||||
|  | --- /dev/null
 | ||||||
|  | +++ b/test/TEST-60-MOUNT-RATELIMIT/test.sh
 | ||||||
|  | @@ -0,0 +1,48 @@
 | ||||||
|  | +#!/usr/bin/env bash
 | ||||||
|  | +set -e
 | ||||||
|  | +TEST_DESCRIPTION="Test that mount/unmount storms can enter/exit rate limit state and will not leak units"
 | ||||||
|  | +
 | ||||||
|  | +. $TEST_BASE_DIR/test-functions
 | ||||||
|  | +
 | ||||||
|  | +test_setup() {
 | ||||||
|  | +    create_empty_image
 | ||||||
|  | +    mkdir -p $TESTDIR/root
 | ||||||
|  | +    mount ${LOOPDEV}p1 $TESTDIR/root
 | ||||||
|  | +
 | ||||||
|  | +    (
 | ||||||
|  | +        LOG_LEVEL=5
 | ||||||
|  | +        eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
 | ||||||
|  | +
 | ||||||
|  | +        setup_basic_environment
 | ||||||
|  | +
 | ||||||
|  | +        # mask some services that we do not want to run in these tests
 | ||||||
|  | +        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
 | ||||||
|  | +        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
 | ||||||
|  | +        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
 | ||||||
|  | +        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
 | ||||||
|  | +        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
 | ||||||
|  | +        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
 | ||||||
|  | +
 | ||||||
|  | +        # setup the testsuite service
 | ||||||
|  | +        cat >$initdir/etc/systemd/system/testsuite.service <<EOF
 | ||||||
|  | +[Unit]
 | ||||||
|  | +Description=Testsuite service
 | ||||||
|  | +
 | ||||||
|  | +[Service]
 | ||||||
|  | +ExecStart=/bin/bash -x /testsuite.sh
 | ||||||
|  | +Type=oneshot
 | ||||||
|  | +StandardOutput=tty
 | ||||||
|  | +StandardError=tty
 | ||||||
|  | +NotifyAccess=all
 | ||||||
|  | +EOF
 | ||||||
|  | +        cp testsuite.sh $initdir/
 | ||||||
|  | +
 | ||||||
|  | +        setup_testsuite
 | ||||||
|  | +    ) || return 1
 | ||||||
|  | +    setup_nspawn_root
 | ||||||
|  | +
 | ||||||
|  | +    ddebug "umount $TESTDIR/root"
 | ||||||
|  | +    umount $TESTDIR/root
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +do_test "$@"
 | ||||||
|  | diff --git a/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh b/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh
 | ||||||
|  | new file mode 100755 | ||||||
|  | index 0000000000..8158754667
 | ||||||
|  | --- /dev/null
 | ||||||
|  | +++ b/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh
 | ||||||
|  | @@ -0,0 +1,73 @@
 | ||||||
|  | +#!/usr/bin/env bash
 | ||||||
|  | +set -eux
 | ||||||
|  | +set -o pipefail
 | ||||||
|  | +
 | ||||||
|  | +systemd-analyze log-level debug
 | ||||||
|  | +systemd-analyze log-target journal
 | ||||||
|  | +
 | ||||||
|  | +NUM_DIRS=20
 | ||||||
|  | +
 | ||||||
|  | +# mount/unmount enough times to trigger the /proc/self/mountinfo parsing rate limiting
 | ||||||
|  | +
 | ||||||
|  | +for ((i = 0; i < NUM_DIRS; i++)); do
 | ||||||
|  | +    mkdir "/tmp/meow${i}"
 | ||||||
|  | +done
 | ||||||
|  | +
 | ||||||
|  | +for ((i = 0; i < NUM_DIRS; i++)); do
 | ||||||
|  | +    mount -t tmpfs tmpfs "/tmp/meow${i}"
 | ||||||
|  | +done
 | ||||||
|  | +
 | ||||||
|  | +systemctl daemon-reload
 | ||||||
|  | +systemctl list-units -t mount tmp-meow* | grep -q tmp-meow
 | ||||||
|  | +
 | ||||||
|  | +for ((i = 0; i < NUM_DIRS; i++)); do
 | ||||||
|  | +    umount "/tmp/meow${i}"
 | ||||||
|  | +done
 | ||||||
|  | +
 | ||||||
|  | +# figure out if we have entered the rate limit state
 | ||||||
|  | +
 | ||||||
|  | +exited_rl=0
 | ||||||
|  | +timeout="$(date -ud "2 minutes" +%s)"
 | ||||||
|  | +while [[ $(date -u +%s) -le ${timeout} ]]; do
 | ||||||
|  | +    if journalctl -u init.scope | grep -q "(mount-monitor-dispatch) entered rate limit"; then
 | ||||||
|  | +        entered_rl=1
 | ||||||
|  | +        break
 | ||||||
|  | +    fi
 | ||||||
|  | +    sleep 5
 | ||||||
|  | +done
 | ||||||
|  | +
 | ||||||
|  | +# if the infra is slow we might not enter the rate limit state; in that case skip the exit check
 | ||||||
|  | +
 | ||||||
|  | +if [ "${entered_rl}" = "1" ]; then
 | ||||||
|  | +    exited_rl=0
 | ||||||
|  | +    timeout="$(date -ud "2 minutes" +%s)"
 | ||||||
|  | +    while [[ $(date -u +%s) -le ${timeout} ]]; do
 | ||||||
|  | +        if journalctl -u init.scope | grep -q "(mount-monitor-dispatch) left rate limit"; then
 | ||||||
|  | +            exited_rl=1
 | ||||||
|  | +            break
 | ||||||
|  | +        fi
 | ||||||
|  | +        sleep 5
 | ||||||
|  | +    done
 | ||||||
|  | +
 | ||||||
|  | +    if [ "${exited_rl}" = "0" ]; then
 | ||||||
|  | +        exit 24
 | ||||||
|  | +    fi
 | ||||||
|  | +fi
 | ||||||
|  | +
 | ||||||
|  | +# give some time for units to settle so we don't race between exiting the rate limit state and cleaning up the units
 | ||||||
|  | +
 | ||||||
|  | +sleep 60
 | ||||||
|  | +systemctl daemon-reload
 | ||||||
|  | +sleep 60
 | ||||||
|  | +
 | ||||||
|  | +# verify that the mount units are always cleaned up at the end
 | ||||||
|  | +
 | ||||||
|  | +if systemctl list-units -t mount tmp-meow* | grep -q tmp-meow; then
 | ||||||
|  | +    exit 42
 | ||||||
|  | +fi
 | ||||||
|  | +
 | ||||||
|  | +systemd-analyze log-level info
 | ||||||
|  | +
 | ||||||
|  | +echo OK >/testok
 | ||||||
|  | +
 | ||||||
|  | +exit 0
 | ||||||
							
								
								
									
										42
									
								
								SOURCES/0765-tests-add-test-case-for-long-unit-names.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								SOURCES/0765-tests-add-test-case-for-long-unit-names.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | From 7363f240c0bb9032c0c615934d5fe4d1eaa56077 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Michal Sekletar <msekleta@redhat.com> | ||||||
|  | Date: Wed, 23 Mar 2022 13:35:44 +0100 | ||||||
|  | Subject: [PATCH] tests: add test case for long unit names | ||||||
|  | 
 | ||||||
|  | (cherry picked from commit 2ef0101e0b2813e8c99fc8f137dbaa763ca16057) | ||||||
|  | 
 | ||||||
|  | Related: #2094712 | ||||||
|  | ---
 | ||||||
|  |  test/TEST-60-MOUNT-RATELIMIT/testsuite.sh | 19 +++++++++++++++++++ | ||||||
|  |  1 file changed, 19 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh b/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh
 | ||||||
|  | index 8158754667..6211050faf 100755
 | ||||||
|  | --- a/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh
 | ||||||
|  | +++ b/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh
 | ||||||
|  | @@ -7,6 +7,25 @@ systemd-analyze log-target journal
 | ||||||
|  |   | ||||||
|  |  NUM_DIRS=20 | ||||||
|  |   | ||||||
|  | +# make sure we can handle mounts at very long paths such that mount unit name must be hashed to fall within our unit name limit
 | ||||||
|  | +LONGPATH="$(printf "/$(printf "x%0.s" {1..255})%0.s" {1..7})"
 | ||||||
|  | +LONGMNT="$(systemd-escape --suffix=mount --path "$LONGPATH")"
 | ||||||
|  | +TS="$(date '+%H:%M:%S')"
 | ||||||
|  | +
 | ||||||
|  | +mkdir -p "$LONGPATH"
 | ||||||
|  | +mount -t tmpfs tmpfs "$LONGPATH"
 | ||||||
|  | +systemctl daemon-reload
 | ||||||
|  | +
 | ||||||
|  | +# check that unit is active(mounted)
 | ||||||
|  | +systemctl --no-pager show -p SubState --value "$LONGPATH" | grep -q mounted
 | ||||||
|  | +
 | ||||||
|  | +# check that relevant part of journal doesn't contain any errors related to unit
 | ||||||
|  | +[ "$(journalctl -b --since="$TS" --priority=err | grep -c "$LONGMNT")" = "0" ]
 | ||||||
|  | +
 | ||||||
|  | +# check that we can successfully stop the mount unit
 | ||||||
|  | +systemctl stop "$LONGPATH"
 | ||||||
|  | +rm -rf "$LONGPATH"
 | ||||||
|  | +
 | ||||||
|  |  # mount/unmount enough times to trigger the /proc/self/mountinfo parsing rate limiting | ||||||
|  |   | ||||||
|  |  for ((i = 0; i < NUM_DIRS; i++)); do | ||||||
| @ -0,0 +1,255 @@ | |||||||
|  | From eef171ea21cf4b77f62269aabfd8bf0fdd92b7bf Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Daan De Meyer <daan.j.demeyer@gmail.com> | ||||||
|  | Date: Fri, 17 Dec 2021 19:39:29 +0100 | ||||||
|  | Subject: [PATCH] Revert "core: Propagate condition failed state to triggering | ||||||
|  |  units." | ||||||
|  | 
 | ||||||
|  | This reverts commit 12ab94a1e4961a39c32efb60b71866ab588d3ea2. | ||||||
|  | 
 | ||||||
|  | (cherry picked from commit 40f41f34d4af15d0147b5b2525f0b87ff62eae9a) | ||||||
|  | 
 | ||||||
|  | Related: #2123801 | ||||||
|  | ---
 | ||||||
|  |  src/core/automount.c | 14 ++++---------- | ||||||
|  |  src/core/automount.h |  1 - | ||||||
|  |  src/core/path.c      | 16 +++++----------- | ||||||
|  |  src/core/path.h      |  1 - | ||||||
|  |  src/core/socket.c    | 28 +++++++++------------------- | ||||||
|  |  src/core/socket.h    |  1 - | ||||||
|  |  src/core/timer.c     | 12 +++--------- | ||||||
|  |  src/core/timer.h     |  1 - | ||||||
|  |  src/core/unit.c      | 10 ---------- | ||||||
|  |  src/core/unit.h      |  2 -- | ||||||
|  |  10 files changed, 21 insertions(+), 65 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/src/core/automount.c b/src/core/automount.c
 | ||||||
|  | index bac3b2fab7..c1c513d4a5 100644
 | ||||||
|  | --- a/src/core/automount.c
 | ||||||
|  | +++ b/src/core/automount.c
 | ||||||
|  | @@ -776,11 +776,6 @@ static void automount_enter_running(Automount *a) {
 | ||||||
|  |                  goto fail; | ||||||
|  |          } | ||||||
|  |   | ||||||
|  | -        if (unit_has_failed_condition_or_assert(trigger)) {
 | ||||||
|  | -                automount_enter_dead(a, AUTOMOUNT_FAILURE_MOUNT_CONDITION_FAILED);
 | ||||||
|  | -                return;
 | ||||||
|  | -        }
 | ||||||
|  | -
 | ||||||
|  |          r = manager_add_job(UNIT(a)->manager, JOB_START, trigger, JOB_REPLACE, NULL, &error, NULL); | ||||||
|  |          if (r < 0) { | ||||||
|  |                  log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r)); | ||||||
|  | @@ -1092,11 +1087,10 @@ static int automount_can_start(Unit *u) {
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { | ||||||
|  | -        [AUTOMOUNT_SUCCESS]                        = "success",
 | ||||||
|  | -        [AUTOMOUNT_FAILURE_RESOURCES]              = "resources",
 | ||||||
|  | -        [AUTOMOUNT_FAILURE_START_LIMIT_HIT]        = "start-limit-hit",
 | ||||||
|  | -        [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT]  = "mount-start-limit-hit",
 | ||||||
|  | -        [AUTOMOUNT_FAILURE_MOUNT_CONDITION_FAILED] = "mount-condition-failed",
 | ||||||
|  | +        [AUTOMOUNT_SUCCESS] = "success",
 | ||||||
|  | +        [AUTOMOUNT_FAILURE_RESOURCES] = "resources",
 | ||||||
|  | +        [AUTOMOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
 | ||||||
|  | +        [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT] = "mount-start-limit-hit",
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult); | ||||||
|  | diff --git a/src/core/automount.h b/src/core/automount.h
 | ||||||
|  | index a7417d195c..21dd1c0774 100644
 | ||||||
|  | --- a/src/core/automount.h
 | ||||||
|  | +++ b/src/core/automount.h
 | ||||||
|  | @@ -10,7 +10,6 @@ typedef enum AutomountResult {
 | ||||||
|  |          AUTOMOUNT_FAILURE_RESOURCES, | ||||||
|  |          AUTOMOUNT_FAILURE_START_LIMIT_HIT, | ||||||
|  |          AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT, | ||||||
|  | -        AUTOMOUNT_FAILURE_MOUNT_CONDITION_FAILED,
 | ||||||
|  |          _AUTOMOUNT_RESULT_MAX, | ||||||
|  |          _AUTOMOUNT_RESULT_INVALID = -1 | ||||||
|  |  } AutomountResult; | ||||||
|  | diff --git a/src/core/path.c b/src/core/path.c
 | ||||||
|  | index bf7e1bf3c2..c2facf0b16 100644
 | ||||||
|  | --- a/src/core/path.c
 | ||||||
|  | +++ b/src/core/path.c
 | ||||||
|  | @@ -453,7 +453,7 @@ static void path_enter_dead(Path *p, PathResult f) {
 | ||||||
|  |          else | ||||||
|  |                  unit_log_failure(UNIT(p), path_result_to_string(p->result)); | ||||||
|  |   | ||||||
|  | -        path_set_state(p, p->result == PATH_SUCCESS ? PATH_DEAD : PATH_FAILED);
 | ||||||
|  | +        path_set_state(p, p->result != PATH_SUCCESS ? PATH_FAILED : PATH_DEAD);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void path_enter_running(Path *p) { | ||||||
|  | @@ -711,11 +711,6 @@ static void path_trigger_notify(Unit *u, Unit *other) {
 | ||||||
|  |                  return; | ||||||
|  |          } | ||||||
|  |   | ||||||
|  | -        if (unit_has_failed_condition_or_assert(other)) {
 | ||||||
|  | -                path_enter_dead(p, PATH_FAILURE_UNIT_CONDITION_FAILED);
 | ||||||
|  | -                return;
 | ||||||
|  | -        }
 | ||||||
|  | -
 | ||||||
|  |          /* Don't propagate anything if there's still a job queued */ | ||||||
|  |          if (other->job) | ||||||
|  |                  return; | ||||||
|  | @@ -768,11 +763,10 @@ static const char* const path_type_table[_PATH_TYPE_MAX] = {
 | ||||||
|  |  DEFINE_STRING_TABLE_LOOKUP(path_type, PathType); | ||||||
|  |   | ||||||
|  |  static const char* const path_result_table[_PATH_RESULT_MAX] = { | ||||||
|  | -        [PATH_SUCCESS]                       = "success",
 | ||||||
|  | -        [PATH_FAILURE_RESOURCES]             = "resources",
 | ||||||
|  | -        [PATH_FAILURE_START_LIMIT_HIT]       = "start-limit-hit",
 | ||||||
|  | -        [PATH_FAILURE_UNIT_START_LIMIT_HIT]  = "unit-start-limit-hit",
 | ||||||
|  | -        [PATH_FAILURE_UNIT_CONDITION_FAILED] = "unit-condition-failed",
 | ||||||
|  | +        [PATH_SUCCESS] = "success",
 | ||||||
|  | +        [PATH_FAILURE_RESOURCES] = "resources",
 | ||||||
|  | +        [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
 | ||||||
|  | +        [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit",
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult); | ||||||
|  | diff --git a/src/core/path.h b/src/core/path.h
 | ||||||
|  | index 0ad6bd12c6..8a69f06c13 100644
 | ||||||
|  | --- a/src/core/path.h
 | ||||||
|  | +++ b/src/core/path.h
 | ||||||
|  | @@ -46,7 +46,6 @@ typedef enum PathResult {
 | ||||||
|  |          PATH_FAILURE_RESOURCES, | ||||||
|  |          PATH_FAILURE_START_LIMIT_HIT, | ||||||
|  |          PATH_FAILURE_UNIT_START_LIMIT_HIT, | ||||||
|  | -        PATH_FAILURE_UNIT_CONDITION_FAILED,
 | ||||||
|  |          _PATH_RESULT_MAX, | ||||||
|  |          _PATH_RESULT_INVALID = -1 | ||||||
|  |  } PathResult; | ||||||
|  | diff --git a/src/core/socket.c b/src/core/socket.c
 | ||||||
|  | index 6f9a0f7575..74c1cc70cb 100644
 | ||||||
|  | --- a/src/core/socket.c
 | ||||||
|  | +++ b/src/core/socket.c
 | ||||||
|  | @@ -2272,15 +2272,6 @@ static void socket_enter_running(Socket *s, int cfd) {
 | ||||||
|  |                  goto refuse; | ||||||
|  |          } | ||||||
|  |   | ||||||
|  | -        if (UNIT_ISSET(s->service) && cfd < 0) {
 | ||||||
|  | -                Unit *service = UNIT_DEREF(s->service);
 | ||||||
|  | -
 | ||||||
|  | -                if (unit_has_failed_condition_or_assert(service)) {
 | ||||||
|  | -                        socket_enter_dead(s, SOCKET_FAILURE_SERVICE_CONDITION_FAILED);
 | ||||||
|  | -                        return;
 | ||||||
|  | -                }
 | ||||||
|  | -        }
 | ||||||
|  | -
 | ||||||
|  |          if (cfd < 0) { | ||||||
|  |                  bool pending = false; | ||||||
|  |                  Unit *other; | ||||||
|  | @@ -3296,16 +3287,15 @@ static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
 | ||||||
|  |  DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand); | ||||||
|  |   | ||||||
|  |  static const char* const socket_result_table[_SOCKET_RESULT_MAX] = { | ||||||
|  | -        [SOCKET_SUCCESS]                          = "success",
 | ||||||
|  | -        [SOCKET_FAILURE_RESOURCES]                = "resources",
 | ||||||
|  | -        [SOCKET_FAILURE_TIMEOUT]                  = "timeout",
 | ||||||
|  | -        [SOCKET_FAILURE_EXIT_CODE]                = "exit-code",
 | ||||||
|  | -        [SOCKET_FAILURE_SIGNAL]                   = "signal",
 | ||||||
|  | -        [SOCKET_FAILURE_CORE_DUMP]                = "core-dump",
 | ||||||
|  | -        [SOCKET_FAILURE_START_LIMIT_HIT]          = "start-limit-hit",
 | ||||||
|  | -        [SOCKET_FAILURE_TRIGGER_LIMIT_HIT]        = "trigger-limit-hit",
 | ||||||
|  | -        [SOCKET_FAILURE_SERVICE_START_LIMIT_HIT]  = "service-start-limit-hit",
 | ||||||
|  | -        [SOCKET_FAILURE_SERVICE_CONDITION_FAILED] = "service-condition-failed",
 | ||||||
|  | +        [SOCKET_SUCCESS] = "success",
 | ||||||
|  | +        [SOCKET_FAILURE_RESOURCES] = "resources",
 | ||||||
|  | +        [SOCKET_FAILURE_TIMEOUT] = "timeout",
 | ||||||
|  | +        [SOCKET_FAILURE_EXIT_CODE] = "exit-code",
 | ||||||
|  | +        [SOCKET_FAILURE_SIGNAL] = "signal",
 | ||||||
|  | +        [SOCKET_FAILURE_CORE_DUMP] = "core-dump",
 | ||||||
|  | +        [SOCKET_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
 | ||||||
|  | +        [SOCKET_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit",
 | ||||||
|  | +        [SOCKET_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit"
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult); | ||||||
|  | diff --git a/src/core/socket.h b/src/core/socket.h
 | ||||||
|  | index b171b94316..2409dbf2a0 100644
 | ||||||
|  | --- a/src/core/socket.h
 | ||||||
|  | +++ b/src/core/socket.h
 | ||||||
|  | @@ -39,7 +39,6 @@ typedef enum SocketResult {
 | ||||||
|  |          SOCKET_FAILURE_START_LIMIT_HIT, | ||||||
|  |          SOCKET_FAILURE_TRIGGER_LIMIT_HIT, | ||||||
|  |          SOCKET_FAILURE_SERVICE_START_LIMIT_HIT, | ||||||
|  | -        SOCKET_FAILURE_SERVICE_CONDITION_FAILED,
 | ||||||
|  |          _SOCKET_RESULT_MAX, | ||||||
|  |          _SOCKET_RESULT_INVALID = -1 | ||||||
|  |  } SocketResult; | ||||||
|  | diff --git a/src/core/timer.c b/src/core/timer.c
 | ||||||
|  | index 3c8d89771d..990f05fee4 100644
 | ||||||
|  | --- a/src/core/timer.c
 | ||||||
|  | +++ b/src/core/timer.c
 | ||||||
|  | @@ -567,11 +567,6 @@ static void timer_enter_running(Timer *t) {
 | ||||||
|  |                  return; | ||||||
|  |          } | ||||||
|  |   | ||||||
|  | -        if (unit_has_failed_condition_or_assert(trigger)) {
 | ||||||
|  | -                timer_enter_dead(t, TIMER_FAILURE_UNIT_CONDITION_FAILED);
 | ||||||
|  | -                return;
 | ||||||
|  | -        }
 | ||||||
|  | -
 | ||||||
|  |          r = manager_add_job(UNIT(t)->manager, JOB_START, trigger, JOB_REPLACE, NULL, &error, NULL); | ||||||
|  |          if (r < 0) | ||||||
|  |                  goto fail; | ||||||
|  | @@ -855,10 +850,9 @@ static const char* const timer_base_table[_TIMER_BASE_MAX] = {
 | ||||||
|  |  DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase); | ||||||
|  |   | ||||||
|  |  static const char* const timer_result_table[_TIMER_RESULT_MAX] = { | ||||||
|  | -        [TIMER_SUCCESS]                       = "success",
 | ||||||
|  | -        [TIMER_FAILURE_RESOURCES]             = "resources",
 | ||||||
|  | -        [TIMER_FAILURE_START_LIMIT_HIT]       = "start-limit-hit",
 | ||||||
|  | -        [TIMER_FAILURE_UNIT_CONDITION_FAILED] = "unit-condition-failed",
 | ||||||
|  | +        [TIMER_SUCCESS] = "success",
 | ||||||
|  | +        [TIMER_FAILURE_RESOURCES] = "resources",
 | ||||||
|  | +        [TIMER_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  DEFINE_STRING_TABLE_LOOKUP(timer_result, TimerResult); | ||||||
|  | diff --git a/src/core/timer.h b/src/core/timer.h
 | ||||||
|  | index d23e19d622..833aadb0b8 100644
 | ||||||
|  | --- a/src/core/timer.h
 | ||||||
|  | +++ b/src/core/timer.h
 | ||||||
|  | @@ -32,7 +32,6 @@ typedef enum TimerResult {
 | ||||||
|  |          TIMER_SUCCESS, | ||||||
|  |          TIMER_FAILURE_RESOURCES, | ||||||
|  |          TIMER_FAILURE_START_LIMIT_HIT, | ||||||
|  | -        TIMER_FAILURE_UNIT_CONDITION_FAILED,
 | ||||||
|  |          _TIMER_RESULT_MAX, | ||||||
|  |          _TIMER_RESULT_INVALID = -1 | ||||||
|  |  } TimerResult; | ||||||
|  | diff --git a/src/core/unit.c b/src/core/unit.c
 | ||||||
|  | index 0810bf5a58..dfe0c243ef 100644
 | ||||||
|  | --- a/src/core/unit.c
 | ||||||
|  | +++ b/src/core/unit.c
 | ||||||
|  | @@ -5661,16 +5661,6 @@ int unit_thaw_vtable_common(Unit *u) {
 | ||||||
|  |          return unit_cgroup_freezer_action(u, FREEZER_THAW); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -bool unit_has_failed_condition_or_assert(Unit *u) {
 | ||||||
|  | -        if (dual_timestamp_is_set(&u->condition_timestamp) && !u->condition_result)
 | ||||||
|  | -                return true;
 | ||||||
|  | -
 | ||||||
|  | -        if (dual_timestamp_is_set(&u->assert_timestamp) && !u->assert_result)
 | ||||||
|  | -                return true;
 | ||||||
|  | -
 | ||||||
|  | -        return false;
 | ||||||
|  | -}
 | ||||||
|  | -
 | ||||||
|  |  static const char* const collect_mode_table[_COLLECT_MODE_MAX] = { | ||||||
|  |          [COLLECT_INACTIVE] = "inactive", | ||||||
|  |          [COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed", | ||||||
|  | diff --git a/src/core/unit.h b/src/core/unit.h
 | ||||||
|  | index a924bd2e83..b8b914711f 100644
 | ||||||
|  | --- a/src/core/unit.h
 | ||||||
|  | +++ b/src/core/unit.h
 | ||||||
|  | @@ -847,8 +847,6 @@ void unit_thawed(Unit *u);
 | ||||||
|  |  int unit_freeze_vtable_common(Unit *u); | ||||||
|  |  int unit_thaw_vtable_common(Unit *u); | ||||||
|  |   | ||||||
|  | -bool unit_has_failed_condition_or_assert(Unit *u);
 | ||||||
|  | -
 | ||||||
|  |  /* Macros which append UNIT= or USER_UNIT= to the message */ | ||||||
|  |   | ||||||
|  |  #define log_unit_full(unit, level, error, ...)                          \ | ||||||
							
								
								
									
										137
									
								
								SOURCES/0767-core-Check-unit-start-rate-limiting-earlier.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								SOURCES/0767-core-Check-unit-start-rate-limiting-earlier.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,137 @@ | |||||||
|  | From 6ec2c387cd4fe081e6a5561b5c7e66ec0555c353 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Daan De Meyer <daan.j.demeyer@gmail.com> | ||||||
|  | Date: Tue, 24 Aug 2021 16:46:47 +0100 | ||||||
|  | Subject: [PATCH] core: Check unit start rate limiting earlier | ||||||
|  | 
 | ||||||
|  | [dtardon: This adds the test that's been left out by commit | ||||||
|  | 471eda89a25a3ceac91a2d05e39a54aae78038ed] | ||||||
|  | 
 | ||||||
|  | (cherry picked from commit 9727f2427ff6b2e1f4ab927cc57ad8e888f04e95) | ||||||
|  | 
 | ||||||
|  | Related: #2123801 | ||||||
|  | ---
 | ||||||
|  |  test/TEST-10-ISSUE-2467/test.sh            |  3 ++ | ||||||
|  |  test/TEST-63-ISSUE-17433/Makefile          |  1 + | ||||||
|  |  test/TEST-63-ISSUE-17433/test.sh           | 42 ++++++++++++++++++++++ | ||||||
|  |  test/TEST-63-ISSUE-17433/test63.path       |  2 ++ | ||||||
|  |  test/TEST-63-ISSUE-17433/test63.service    |  5 +++ | ||||||
|  |  test/TEST-63-ISSUE-17433/testsuite.service | 17 +++++++++ | ||||||
|  |  6 files changed, 70 insertions(+) | ||||||
|  |  create mode 120000 test/TEST-63-ISSUE-17433/Makefile | ||||||
|  |  create mode 100755 test/TEST-63-ISSUE-17433/test.sh | ||||||
|  |  create mode 100644 test/TEST-63-ISSUE-17433/test63.path | ||||||
|  |  create mode 100644 test/TEST-63-ISSUE-17433/test63.service | ||||||
|  |  create mode 100644 test/TEST-63-ISSUE-17433/testsuite.service | ||||||
|  | 
 | ||||||
|  | diff --git a/test/TEST-10-ISSUE-2467/test.sh b/test/TEST-10-ISSUE-2467/test.sh
 | ||||||
|  | index 0e61236686..a839ef79de 100755
 | ||||||
|  | --- a/test/TEST-10-ISSUE-2467/test.sh
 | ||||||
|  | +++ b/test/TEST-10-ISSUE-2467/test.sh
 | ||||||
|  | @@ -42,6 +42,9 @@ EOF
 | ||||||
|  |  [Unit] | ||||||
|  |  Requires=test.socket | ||||||
|  |  ConditionPathExistsGlob=/tmp/nonexistent | ||||||
|  | +# Make sure we hit the socket trigger limit in the test and not the service start limit.
 | ||||||
|  | +StartLimitInterval=1000
 | ||||||
|  | +StartLimitBurst=1000
 | ||||||
|  |   | ||||||
|  |  [Service] | ||||||
|  |  ExecStart=/bin/true | ||||||
|  | diff --git a/test/TEST-63-ISSUE-17433/Makefile b/test/TEST-63-ISSUE-17433/Makefile
 | ||||||
|  | new file mode 120000 | ||||||
|  | index 0000000000..e9f93b1104
 | ||||||
|  | --- /dev/null
 | ||||||
|  | +++ b/test/TEST-63-ISSUE-17433/Makefile
 | ||||||
|  | @@ -0,0 +1 @@
 | ||||||
|  | +../TEST-01-BASIC/Makefile
 | ||||||
|  | \ No newline at end of file | ||||||
|  | diff --git a/test/TEST-63-ISSUE-17433/test.sh b/test/TEST-63-ISSUE-17433/test.sh
 | ||||||
|  | new file mode 100755 | ||||||
|  | index 0000000000..406a1e214c
 | ||||||
|  | --- /dev/null
 | ||||||
|  | +++ b/test/TEST-63-ISSUE-17433/test.sh
 | ||||||
|  | @@ -0,0 +1,42 @@
 | ||||||
|  | +#!/usr/bin/env bash
 | ||||||
|  | +set -e
 | ||||||
|  | +
 | ||||||
|  | +TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/17433"
 | ||||||
|  | +
 | ||||||
|  | +# shellcheck source=test/test-functions
 | ||||||
|  | +. "${TEST_BASE_DIR:?}/test-functions"
 | ||||||
|  | +
 | ||||||
|  | +test_setup() {
 | ||||||
|  | +    create_empty_image
 | ||||||
|  | +    mkdir -p $TESTDIR/root
 | ||||||
|  | +    mount ${LOOPDEV}p1 $TESTDIR/root
 | ||||||
|  | +
 | ||||||
|  | +    # Create what will eventually be our root filesystem onto an overlay
 | ||||||
|  | +    (
 | ||||||
|  | +        LOG_LEVEL=5
 | ||||||
|  | +        eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
 | ||||||
|  | +
 | ||||||
|  | +        setup_basic_environment
 | ||||||
|  | +
 | ||||||
|  | +        # setup the testsuite service
 | ||||||
|  | +        cp testsuite.service $initdir/etc/systemd/system/testsuite.service
 | ||||||
|  | +
 | ||||||
|  | +        cp test63.path $initdir/etc/systemd/system/test63.path
 | ||||||
|  | +        cp test63.service $initdir/etc/systemd/system/test63.service
 | ||||||
|  | +
 | ||||||
|  | +        setup_testsuite
 | ||||||
|  | +    ) || return 1
 | ||||||
|  | +    setup_nspawn_root
 | ||||||
|  | +
 | ||||||
|  | +    # mask some services that we do not want to run in these tests
 | ||||||
|  | +    ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
 | ||||||
|  | +    ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
 | ||||||
|  | +    ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
 | ||||||
|  | +    ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
 | ||||||
|  | +    ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
 | ||||||
|  | +
 | ||||||
|  | +    ddebug "umount $TESTDIR/root"
 | ||||||
|  | +    umount $TESTDIR/root
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +do_test "$@"
 | ||||||
|  | diff --git a/test/TEST-63-ISSUE-17433/test63.path b/test/TEST-63-ISSUE-17433/test63.path
 | ||||||
|  | new file mode 100644 | ||||||
|  | index 0000000000..a6573bda0a
 | ||||||
|  | --- /dev/null
 | ||||||
|  | +++ b/test/TEST-63-ISSUE-17433/test63.path
 | ||||||
|  | @@ -0,0 +1,2 @@
 | ||||||
|  | +[Path]
 | ||||||
|  | +PathExists=/tmp/test63
 | ||||||
|  | diff --git a/test/TEST-63-ISSUE-17433/test63.service b/test/TEST-63-ISSUE-17433/test63.service
 | ||||||
|  | new file mode 100644 | ||||||
|  | index 0000000000..c83801874d
 | ||||||
|  | --- /dev/null
 | ||||||
|  | +++ b/test/TEST-63-ISSUE-17433/test63.service
 | ||||||
|  | @@ -0,0 +1,5 @@
 | ||||||
|  | +[Unit]
 | ||||||
|  | +ConditionPathExists=!/tmp/nonexistent
 | ||||||
|  | +
 | ||||||
|  | +[Service]
 | ||||||
|  | +ExecStart=true
 | ||||||
|  | diff --git a/test/TEST-63-ISSUE-17433/testsuite.service b/test/TEST-63-ISSUE-17433/testsuite.service
 | ||||||
|  | new file mode 100644 | ||||||
|  | index 0000000000..d3ca5b002b
 | ||||||
|  | --- /dev/null
 | ||||||
|  | +++ b/test/TEST-63-ISSUE-17433/testsuite.service
 | ||||||
|  | @@ -0,0 +1,17 @@
 | ||||||
|  | +[Unit]
 | ||||||
|  | +Description=TEST-63-ISSUE-17433
 | ||||||
|  | +
 | ||||||
|  | +[Service]
 | ||||||
|  | +ExecStartPre=rm -f /failed /testok
 | ||||||
|  | +Type=oneshot
 | ||||||
|  | +ExecStart=rm -f /tmp/nonexistent
 | ||||||
|  | +ExecStart=systemctl start test63.path
 | ||||||
|  | +ExecStart=touch /tmp/test63
 | ||||||
|  | +# Make sure systemd has sufficient time to hit the start limit for test63.service.
 | ||||||
|  | +ExecStart=sleep 2
 | ||||||
|  | +ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p ActiveState)" = failed'
 | ||||||
|  | +ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p Result)" = start-limit-hit'
 | ||||||
|  | +# FIXME: The path remains active, which it should not
 | ||||||
|  | +# ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p ActiveState)" = failed'
 | ||||||
|  | +# ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p Result)" = unit-start-limit-hit'
 | ||||||
|  | +ExecStart=sh -x -c 'echo OK >/testok'
 | ||||||
							
								
								
									
										127
									
								
								SOURCES/0768-core-Add-trigger-limit-for-path-units.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								SOURCES/0768-core-Add-trigger-limit-for-path-units.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,127 @@ | |||||||
|  | From d61bd956e599dd747490d36ff793b63fb6a9fedc Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Daan De Meyer <daan.j.demeyer@gmail.com> | ||||||
|  | Date: Fri, 17 Dec 2021 20:01:31 +0100 | ||||||
|  | Subject: [PATCH] core: Add trigger limit for path units | ||||||
|  | 
 | ||||||
|  | When conditions fail on a service unit, a path unit can cause | ||||||
|  | PID 1 to busy loop as it keeps trying to activate the service unit. | ||||||
|  | To avoid this from happening, add a trigger limit to the path unit, | ||||||
|  | identical to the trigger limit we have for socket units. | ||||||
|  | 
 | ||||||
|  | Initially, let's start with a high limit and not make it configurable. | ||||||
|  | If needed, we can add properties to configure the rate limit similar | ||||||
|  | to the ones we have for socket units. | ||||||
|  | 
 | ||||||
|  | (cherry picked from commit aaae822b37aa3ca39aebb516fdc6bef36d730c25) | ||||||
|  | 
 | ||||||
|  | Resolves: #2123801 | ||||||
|  | ---
 | ||||||
|  |  src/core/path.c                            | 10 ++++++++++ | ||||||
|  |  src/core/path.h                            |  3 +++ | ||||||
|  |  test/TEST-63-ISSUE-17433/test63.service    |  2 +- | ||||||
|  |  test/TEST-63-ISSUE-17433/testsuite.service | 21 +++++++++++++++++---- | ||||||
|  |  4 files changed, 31 insertions(+), 5 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/src/core/path.c b/src/core/path.c
 | ||||||
|  | index c2facf0b16..b899bde0de 100644
 | ||||||
|  | --- a/src/core/path.c
 | ||||||
|  | +++ b/src/core/path.c
 | ||||||
|  | @@ -238,6 +238,9 @@ static void path_init(Unit *u) {
 | ||||||
|  |          assert(u->load_state == UNIT_STUB); | ||||||
|  |   | ||||||
|  |          p->directory_mode = 0755; | ||||||
|  | +
 | ||||||
|  | +        p->trigger_limit.interval = 2 * USEC_PER_SEC;
 | ||||||
|  | +        p->trigger_limit.burst = 200;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  void path_free_specs(Path *p) { | ||||||
|  | @@ -467,6 +470,12 @@ static void path_enter_running(Path *p) {
 | ||||||
|  |          if (unit_stop_pending(UNIT(p))) | ||||||
|  |                  return; | ||||||
|  |   | ||||||
|  | +        if (!ratelimit_below(&p->trigger_limit)) {
 | ||||||
|  | +                log_unit_warning(UNIT(p), "Trigger limit hit, refusing further activation.");
 | ||||||
|  | +                path_enter_dead(p, PATH_FAILURE_TRIGGER_LIMIT_HIT);
 | ||||||
|  | +                return;
 | ||||||
|  | +        }
 | ||||||
|  | +
 | ||||||
|  |          trigger = UNIT_TRIGGER(UNIT(p)); | ||||||
|  |          if (!trigger) { | ||||||
|  |                  log_unit_error(UNIT(p), "Unit to trigger vanished."); | ||||||
|  | @@ -767,6 +776,7 @@ static const char* const path_result_table[_PATH_RESULT_MAX] = {
 | ||||||
|  |          [PATH_FAILURE_RESOURCES] = "resources", | ||||||
|  |          [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit", | ||||||
|  |          [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit", | ||||||
|  | +        [PATH_FAILURE_TRIGGER_LIMIT_HIT]    = "trigger-limit-hit",
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult); | ||||||
|  | diff --git a/src/core/path.h b/src/core/path.h
 | ||||||
|  | index 8a69f06c13..12fd13fbe3 100644
 | ||||||
|  | --- a/src/core/path.h
 | ||||||
|  | +++ b/src/core/path.h
 | ||||||
|  | @@ -46,6 +46,7 @@ typedef enum PathResult {
 | ||||||
|  |          PATH_FAILURE_RESOURCES, | ||||||
|  |          PATH_FAILURE_START_LIMIT_HIT, | ||||||
|  |          PATH_FAILURE_UNIT_START_LIMIT_HIT, | ||||||
|  | +        PATH_FAILURE_TRIGGER_LIMIT_HIT,
 | ||||||
|  |          _PATH_RESULT_MAX, | ||||||
|  |          _PATH_RESULT_INVALID = -1 | ||||||
|  |  } PathResult; | ||||||
|  | @@ -63,6 +64,8 @@ struct Path {
 | ||||||
|  |          mode_t directory_mode; | ||||||
|  |   | ||||||
|  |          PathResult result; | ||||||
|  | +
 | ||||||
|  | +        RateLimit trigger_limit;
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  void path_free_specs(Path *p); | ||||||
|  | diff --git a/test/TEST-63-ISSUE-17433/test63.service b/test/TEST-63-ISSUE-17433/test63.service
 | ||||||
|  | index c83801874d..6292434c5c 100644
 | ||||||
|  | --- a/test/TEST-63-ISSUE-17433/test63.service
 | ||||||
|  | +++ b/test/TEST-63-ISSUE-17433/test63.service
 | ||||||
|  | @@ -1,5 +1,5 @@
 | ||||||
|  |  [Unit] | ||||||
|  | -ConditionPathExists=!/tmp/nonexistent
 | ||||||
|  | +ConditionPathExists=/tmp/nonexistent
 | ||||||
|  |   | ||||||
|  |  [Service] | ||||||
|  |  ExecStart=true | ||||||
|  | diff --git a/test/TEST-63-ISSUE-17433/testsuite.service b/test/TEST-63-ISSUE-17433/testsuite.service
 | ||||||
|  | index d3ca5b002b..39f9643890 100644
 | ||||||
|  | --- a/test/TEST-63-ISSUE-17433/testsuite.service
 | ||||||
|  | +++ b/test/TEST-63-ISSUE-17433/testsuite.service
 | ||||||
|  | @@ -4,14 +4,27 @@ Description=TEST-63-ISSUE-17433
 | ||||||
|  |  [Service] | ||||||
|  |  ExecStartPre=rm -f /failed /testok | ||||||
|  |  Type=oneshot | ||||||
|  | +
 | ||||||
|  | +# Test that a path unit continuously triggering a service that fails condition checks eventually fails with
 | ||||||
|  | +# the trigger-limit-hit error.
 | ||||||
|  |  ExecStart=rm -f /tmp/nonexistent | ||||||
|  |  ExecStart=systemctl start test63.path | ||||||
|  |  ExecStart=touch /tmp/test63 | ||||||
|  | -# Make sure systemd has sufficient time to hit the start limit for test63.service.
 | ||||||
|  | +# Make sure systemd has sufficient time to hit the trigger limit for test63.path.
 | ||||||
|  |  ExecStart=sleep 2 | ||||||
|  | -ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p ActiveState)" = failed'
 | ||||||
|  | -ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p Result)" = start-limit-hit'
 | ||||||
|  | +ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p ActiveState)" = inactive'
 | ||||||
|  | +ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p Result)" = success'
 | ||||||
|  |  # FIXME: The path remains active, which it should not | ||||||
|  |  # ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p ActiveState)" = failed' | ||||||
|  | -# ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p Result)" = unit-start-limit-hit'
 | ||||||
|  | +# ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p Result)" = trigger-limit-hit'
 | ||||||
|  | +
 | ||||||
|  | +# Test that starting the service manually doesn't affect the path unit.
 | ||||||
|  | +ExecStart=rm -f /tmp/test63
 | ||||||
|  | +ExecStart=systemctl reset-failed
 | ||||||
|  | +ExecStart=systemctl start test63.path
 | ||||||
|  | +ExecStart=systemctl start test63.service
 | ||||||
|  | +ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p ActiveState)" = inactive'
 | ||||||
|  | +ExecStart=sh -x -c 'test "$(systemctl show test63.service --value -p Result)" = success'
 | ||||||
|  | +ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p ActiveState)" = active'
 | ||||||
|  | +ExecStart=sh -x -c 'test "$(systemctl show test63.path --value -p Result)" = success'
 | ||||||
|  |  ExecStart=sh -x -c 'echo OK >/testok' | ||||||
| @ -1,4 +1,4 @@ | |||||||
| From a4f08c798cabd5c43f2578a9e2b048fa1ad4a52c Mon Sep 17 00:00:00 2001 | From b92fae31236301ba1fcca604c68bb4e908318c49 Mon Sep 17 00:00:00 2001 | ||||||
| From: Lennart Poettering <lennart@poettering.net> | From: Lennart Poettering <lennart@poettering.net> | ||||||
| Date: Tue, 4 Dec 2018 22:13:39 +0100 | Date: Tue, 4 Dec 2018 22:13:39 +0100 | ||||||
| Subject: [PATCH] resolved: pin stream while calling callbacks for it | Subject: [PATCH] resolved: pin stream while calling callbacks for it | ||||||
| @ -16,7 +16,7 @@ Resolves: #2110548 | |||||||
|  1 file changed, 3 insertions(+), 1 deletion(-) |  1 file changed, 3 insertions(+), 1 deletion(-) | ||||||
| 
 | 
 | ||||||
| diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c
 | diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c
 | ||||||
| index 066daef96e..2d0162483a 100644
 | index 555e200a23..ca0313d1d7 100644
 | ||||||
| --- a/src/resolve/resolved-dns-stream.c
 | --- a/src/resolve/resolved-dns-stream.c
 | ||||||
| +++ b/src/resolve/resolved-dns-stream.c
 | +++ b/src/resolve/resolved-dns-stream.c
 | ||||||
| @@ -42,6 +42,8 @@ static int dns_stream_update_io(DnsStream *s) {
 | @@ -42,6 +42,8 @@ static int dns_stream_update_io(DnsStream *s) {
 | ||||||
| @ -28,7 +28,7 @@ index 066daef96e..2d0162483a 100644 | |||||||
|          assert(s); |          assert(s); | ||||||
|   |   | ||||||
|  #if ENABLE_DNS_OVER_TLS |  #if ENABLE_DNS_OVER_TLS | ||||||
| @@ -315,7 +317,7 @@ static int on_stream_timeout(sd_event_source *es, usec_t usec, void *userdata) {
 | @@ -316,7 +318,7 @@ static int on_stream_timeout(sd_event_source *es, usec_t usec, void *userdata) {
 | ||||||
|  } |  } | ||||||
|   |   | ||||||
|  static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *userdata) { |  static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *userdata) { | ||||||
| @ -37,6 +37,3 @@ index 066daef96e..2d0162483a 100644 | |||||||
|          int r; |          int r; | ||||||
|   |   | ||||||
|          assert(s); |          assert(s); | ||||||
| -- 
 |  | ||||||
| 2.37.1 |  | ||||||
| 
 |  | ||||||
| @ -0,0 +1,49 @@ | |||||||
|  | From 34aeec27c86917e7284ea562f62e46384d5da5ba Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Anita Zhang <the.anitazha@gmail.com> | ||||||
|  | Date: Thu, 17 Sep 2020 01:49:17 -0700 | ||||||
|  | Subject: [PATCH] core: move reset_arguments() to the end of main's finish | ||||||
|  | 
 | ||||||
|  | Fixes #16991 | ||||||
|  | 
 | ||||||
|  | fb39af4ce42d7ef9af63009f271f404038703704 replaced `free_arguments()` with | ||||||
|  | `reset_arguments()`, which frees arg_* variables as before, but also resets all | ||||||
|  | of them to the default values. `reset_arguments()` was positioned | ||||||
|  | in such a way that it overrode some arg_* values still in use at shutdown. | ||||||
|  | 
 | ||||||
|  | To avoid further unintentional resets, I moved `reset_arguments()` | ||||||
|  | right before the return, when nothing else will be using the arg_* variables. | ||||||
|  | 
 | ||||||
|  | (cherry picked from commit 7d9eea2bd3d4f83668c7a78754d201b226acbf1e) | ||||||
|  | 
 | ||||||
|  | Resolves: #2127171 | ||||||
|  | ---
 | ||||||
|  |  src/core/main.c | 3 ++- | ||||||
|  |  1 file changed, 2 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/src/core/main.c b/src/core/main.c
 | ||||||
|  | index d897155644..a4cdb28884 100644
 | ||||||
|  | --- a/src/core/main.c
 | ||||||
|  | +++ b/src/core/main.c
 | ||||||
|  | @@ -2622,7 +2622,6 @@ finish:
 | ||||||
|  |                  m = manager_free(m); | ||||||
|  |          } | ||||||
|  |   | ||||||
|  | -        reset_arguments();
 | ||||||
|  |          mac_selinux_finish(); | ||||||
|  |   | ||||||
|  |          if (reexecute) | ||||||
|  | @@ -2647,6 +2646,7 @@ finish:
 | ||||||
|  |                   * in become_shutdown() so normally we cannot free them yet. */ | ||||||
|  |                  watchdog_free_device(); | ||||||
|  |                  arg_watchdog_device = mfree(arg_watchdog_device); | ||||||
|  | +                reset_arguments();
 | ||||||
|  |                  return retval; | ||||||
|  |          } | ||||||
|  |  #endif | ||||||
|  | @@ -2668,5 +2668,6 @@ finish:
 | ||||||
|  |                  freeze_or_reboot(); | ||||||
|  |          } | ||||||
|  |   | ||||||
|  | +        reset_arguments();
 | ||||||
|  |          return retval; | ||||||
|  |  } | ||||||
| @ -13,7 +13,7 @@ | |||||||
| Name:           systemd | Name:           systemd | ||||||
| Url:            http://www.freedesktop.org/wiki/Software/systemd | Url:            http://www.freedesktop.org/wiki/Software/systemd | ||||||
| Version:        239 | Version:        239 | ||||||
| Release:        58%{?dist}.7 | Release:        58%{?dist}.8 | ||||||
| # For a breakdown of the licensing, see README | # For a breakdown of the licensing, see README | ||||||
| License:        LGPLv2+ and MIT and GPLv2+ | License:        LGPLv2+ and MIT and GPLv2+ | ||||||
| Summary:        System and Service Manager | Summary:        System and Service Manager | ||||||
| @ -811,8 +811,16 @@ Patch0758: 0758-sd-event-don-t-invalidate-source-type-on-disconnect.patch | |||||||
| Patch0759: 0759-test-procfs-util-skip-test-on-certain-errors.patch | Patch0759: 0759-test-procfs-util-skip-test-on-certain-errors.patch | ||||||
| Patch0760: 0760-Try-stopping-MD-RAID-devices-in-shutdown-too.patch | Patch0760: 0760-Try-stopping-MD-RAID-devices-in-shutdown-too.patch | ||||||
| Patch0761: 0761-shutdown-get-only-active-md-arrays.patch | Patch0761: 0761-shutdown-get-only-active-md-arrays.patch | ||||||
|  | Patch0762: 0762-unit-name-tighten-checks-for-building-valid-unit-nam.patch | ||||||
|  | Patch0763: 0763-core-shorten-long-unit-names-that-are-based-on-paths.patch | ||||||
|  | Patch0764: 0764-test-add-extended-test-for-triggering-mount-rate-lim.patch | ||||||
|  | Patch0765: 0765-tests-add-test-case-for-long-unit-names.patch | ||||||
|  | Patch0766: 0766-Revert-core-Propagate-condition-failed-state-to-trig.patch | ||||||
|  | Patch0767: 0767-core-Check-unit-start-rate-limiting-earlier.patch | ||||||
|  | Patch0768: 0768-core-Add-trigger-limit-for-path-units.patch | ||||||
|  | Patch0769: 0769-resolved-pin-stream-while-calling-callbacks-for-it.patch | ||||||
|  | Patch0770: 0770-core-move-reset_arguments-to-the-end-of-main-s-finis.patch | ||||||
| 
 | 
 | ||||||
| Patch9000: 9000-resolved-pin-stream-while-calling-callbacks-for-it.patch |  | ||||||
| 
 | 
 | ||||||
| %ifarch %{ix86} x86_64 aarch64 | %ifarch %{ix86} x86_64 aarch64 | ||||||
| %global have_gnu_efi 1 | %global have_gnu_efi 1 | ||||||
| @ -1442,6 +1450,17 @@ fi | |||||||
| %files tests -f .file-list-tests | %files tests -f .file-list-tests | ||||||
| 
 | 
 | ||||||
| %changelog | %changelog | ||||||
|  | * Wed Sep 21 2022 systemd maintenance team <systemd-maint@redhat.com> - 239-58.8 | ||||||
|  | - unit-name: tighten checks for building valid unit names (#2094712) | ||||||
|  | - core: shorten long unit names that are based on paths and append path hash at the end (#2094712) | ||||||
|  | - test: add extended test for triggering mount rate limit (#2094712) | ||||||
|  | - tests: add test case for long unit names (#2094712) | ||||||
|  | - Revert "core: Propagate condition failed state to triggering units." (#2123801) | ||||||
|  | - core: Check unit start rate limiting earlier (#2123801) | ||||||
|  | - core: Add trigger limit for path units (#2123801) | ||||||
|  | - resolved: pin stream while calling callbacks for it (#2110548) | ||||||
|  | - core: move reset_arguments() to the end of main's finish (#2127171) | ||||||
|  | 
 | ||||||
| * Thu Aug 25 2022 systemd maintenance team <systemd-maint@redhat.com> - 239-58.7 | * Thu Aug 25 2022 systemd maintenance team <systemd-maint@redhat.com> - 239-58.7 | ||||||
| - sd-event: don't invalidate source type on disconnect (#2116892) | - sd-event: don't invalidate source type on disconnect (#2116892) | ||||||
| - test-procfs-util: skip test on certain errors (#2087152) | - test-procfs-util: skip test on certain errors (#2087152) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user