]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-device: make TAGS= property prefixed and suffixed with ":"
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 10 Dec 2020 23:34:13 +0000 (08:34 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 14 Dec 2020 05:04:53 +0000 (14:04 +0900)
The commit 6f3ac0d51766b0b9101676cefe5c4ba81feba436 drops the prefix and
suffix in TAGS= property. But there exists several rules that have like
`TAGS=="*:tag:*"`. So, the property must be always prefixed and suffixed
with ":".

Fixes #17930.

src/basic/hashmap.c
src/basic/set.h
src/libsystemd/sd-device/sd-device.c
src/test/test-set.c
test/units/testsuite-55.sh

index e38e5805300e0a8adaca00fa30bad94974d032ba..cdc6847edf021eb19c2f07861490791527ca0701 100644 (file)
@@ -1977,23 +1977,33 @@ IteratedCache* iterated_cache_free(IteratedCache *cache) {
         return mfree(cache);
 }
 
-int set_strjoin(Set *s, const char *separator, char **ret) {
+int set_strjoin(Set *s, const char *separator, bool wrap_with_separator, char **ret) {
         size_t separator_len, allocated = 0, len = 0;
         _cleanup_free_ char *str = NULL;
         const char *value;
-        bool first = true;
+        bool first;
 
         assert(ret);
 
+        if (set_isempty(s)) {
+                *ret = NULL;
+                return 0;
+        }
+
         separator_len = strlen_ptr(separator);
 
+        if (separator_len == 0)
+                wrap_with_separator = false;
+
+        first = !wrap_with_separator;
+
         SET_FOREACH(value, s) {
                 size_t l = strlen_ptr(value);
 
                 if (l == 0)
                         continue;
 
-                if (!GREEDY_REALLOC(str, allocated, len + l + (first ? 0 : separator_len) + 1))
+                if (!GREEDY_REALLOC(str, allocated, len + l + (first ? 0 : separator_len) + (wrap_with_separator ? separator_len : 0) + 1))
                         return -ENOMEM;
 
                 if (separator_len > 0 && !first) {
@@ -2005,8 +2015,13 @@ int set_strjoin(Set *s, const char *separator, char **ret) {
                 len += l;
                 first = false;
         }
-        if (str)
-                str[len] = '\0';
+
+        if (wrap_with_separator) {
+                memcpy(str + len, separator, separator_len);
+                len += separator_len;
+        }
+
+        str[len] = '\0';
 
         *ret = TAKE_PTR(str);
         return 0;
index 2b06c39cbe5647c4d8b2441443f6d8f1bfe145f1..57ff713039bd457eefeddcde79416fb085f58b48 100644 (file)
@@ -151,4 +151,4 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free);
 #define _cleanup_set_free_ _cleanup_(set_freep)
 #define _cleanup_set_free_free_ _cleanup_(set_free_freep)
 
-int set_strjoin(Set *s, const char *separator, char **ret);
+int set_strjoin(Set *s, const char *separator, bool wrap_with_separator, char **ret);
index 005801e1a69bb7bd9a6e2dd2d34682d2d5e344bc..d1aa3282bf4bfc394323abc757942760f790e31d 100644 (file)
@@ -1534,7 +1534,7 @@ int device_properties_prepare(sd_device *device) {
         if (device->property_devlinks_outdated) {
                 _cleanup_free_ char *devlinks = NULL;
 
-                r = set_strjoin(device->devlinks, " ", &devlinks);
+                r = set_strjoin(device->devlinks, " ", false, &devlinks);
                 if (r < 0)
                         return r;
 
@@ -1550,7 +1550,7 @@ int device_properties_prepare(sd_device *device) {
         if (device->property_tags_outdated) {
                 _cleanup_free_ char *tags = NULL;
 
-                r = set_strjoin(device->all_tags, ":", &tags);
+                r = set_strjoin(device->all_tags, ":", true, &tags);
                 if (r < 0)
                         return r;
 
@@ -1561,7 +1561,7 @@ int device_properties_prepare(sd_device *device) {
                 }
 
                 tags = mfree(tags);
-                r = set_strjoin(device->current_tags, ":", &tags);
+                r = set_strjoin(device->current_tags, ":", true, &tags);
                 if (r < 0)
                         return r;
 
index 897940824255d70f31ca4d36a2b68c453d2436f9..b4d07b20783b5cefc898599bf2e6b7525b93f3b8 100644 (file)
@@ -154,50 +154,77 @@ static void test_set_strjoin(void) {
         _cleanup_set_free_ Set *m = NULL;
         _cleanup_free_ char *joined = NULL;
 
-        assert_se(set_strjoin(m, NULL, &joined) >= 0);
+        /* Empty set */
+        assert_se(set_strjoin(m, NULL, false, &joined) >= 0);
         assert_se(!joined);
-        assert_se(set_strjoin(m, "", &joined) >= 0);
+        assert_se(set_strjoin(m, "", false, &joined) >= 0);
         assert_se(!joined);
-        assert_se(set_strjoin(m, " ", &joined) >= 0);
+        assert_se(set_strjoin(m, " ", false, &joined) >= 0);
         assert_se(!joined);
-        assert_se(set_strjoin(m, "xxx", &joined) >= 0);
+        assert_se(set_strjoin(m, "xxx", false, &joined) >= 0);
+        assert_se(!joined);
+        assert_se(set_strjoin(m, NULL, true, &joined) >= 0);
+        assert_se(!joined);
+        assert_se(set_strjoin(m, "", true, &joined) >= 0);
+        assert_se(!joined);
+        assert_se(set_strjoin(m, " ", true, &joined) >= 0);
+        assert_se(!joined);
+        assert_se(set_strjoin(m, "xxx", true, &joined) >= 0);
         assert_se(!joined);
 
+        /* Single entry */
         assert_se(set_put_strdup(&m, "aaa") == 1);
-
-        assert_se(set_strjoin(m, NULL, &joined) >= 0);
+        assert_se(set_strjoin(m, NULL, false, &joined) >= 0);
         assert_se(streq(joined, "aaa"));
-
         joined = mfree(joined);
-        assert_se(set_strjoin(m, "", &joined) >= 0);
+        assert_se(set_strjoin(m, "", false, &joined) >= 0);
         assert_se(streq(joined, "aaa"));
-
         joined = mfree(joined);
-        assert_se(set_strjoin(m, " ", &joined) >= 0);
+        assert_se(set_strjoin(m, " ", false, &joined) >= 0);
+        assert_se(streq(joined, "aaa"));
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, "xxx", false, &joined) >= 0);
+        assert_se(streq(joined, "aaa"));
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, NULL, true, &joined) >= 0);
         assert_se(streq(joined, "aaa"));
-
         joined = mfree(joined);
-        assert_se(set_strjoin(m, "xxx", &joined) >= 0);
+        assert_se(set_strjoin(m, "", true, &joined) >= 0);
         assert_se(streq(joined, "aaa"));
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, " ", true, &joined) >= 0);
+        assert_se(streq(joined, " aaa "));
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, "xxx", true, &joined) >= 0);
+        assert_se(streq(joined, "xxxaaaxxx"));
 
+        /* Two entries */
         assert_se(set_put_strdup(&m, "bbb") == 1);
         assert_se(set_put_strdup(&m, "aaa") == 0);
-
         joined = mfree(joined);
-        assert_se(set_strjoin(m, NULL, &joined) >= 0);
+        assert_se(set_strjoin(m, NULL, false, &joined) >= 0);
         assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
-
         joined = mfree(joined);
-        assert_se(set_strjoin(m, "", &joined) >= 0);
+        assert_se(set_strjoin(m, "", false, &joined) >= 0);
         assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
-
         joined = mfree(joined);
-        assert_se(set_strjoin(m, " ", &joined) >= 0);
+        assert_se(set_strjoin(m, " ", false, &joined) >= 0);
         assert_se(STR_IN_SET(joined, "aaa bbb", "bbb aaa"));
-
         joined = mfree(joined);
-        assert_se(set_strjoin(m, "xxx", &joined) >= 0);
+        assert_se(set_strjoin(m, "xxx", false, &joined) >= 0);
         assert_se(STR_IN_SET(joined, "aaaxxxbbb", "bbbxxxaaa"));
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, NULL, true, &joined) >= 0);
+        assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, "", true, &joined) >= 0);
+        assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, " ", true, &joined) >= 0);
+        assert_se(STR_IN_SET(joined, " aaa bbb ", " bbb aaa "));
+        joined = mfree(joined);
+        assert_se(set_strjoin(m, "xxx", true, &joined) >= 0);
+        assert_se(STR_IN_SET(joined, "xxxaaaxxxbbbxxx", "xxxbbbxxxaaaxxx"));
 }
 
 int main(int argc, const char *argv[]) {
index 19f5683f57a104fa01ae4c54531db07462a6e537..ffceefb6a57ae2fe1beb5d0923aef7fc88fad0ca 100755 (executable)
@@ -2,26 +2,14 @@
 set -ex
 set -o pipefail
 
-function has_tag_internal() {
-    udevadm info /dev/null | sed -n '/E: '$1'=/ {s/E: '$1'=/:/; s/$/:/; p}' | grep -q ":$2:"
-}
-
-function has_tag() {
-    has_tag_internal TAGS $1
-}
-
-function has_current_tag() {
-    has_tag_internal CURRENT_TAGS $1
-}
-
 mkdir -p /run/udev/rules.d/
 
 ! test -f /run/udev/tags/added/c1:3 &&
     ! test -f /run/udev/tags/changed/c1:3 &&
-    ! has_tag added &&
-    ! has_current_tag added &&
-    ! has_tag changed &&
-    ! has_current_tag changed
+    udevadm info /dev/null | grep -q -v 'E: TAGS=.*:added:.*' &&
+    udevadm info /dev/null | grep -q -v 'E: CURRENT_TAGS=.*:added:.*' &&
+    udevadm info /dev/null | grep -q -v 'E: TAGS=.*:changed:.*' &&
+    udevadm info /dev/null | grep -q -v 'E: CURRENT_TAGS=.*:changed:.*'
 
 cat > /run/udev/rules.d/50-testsuite.rules <<EOF
 ACTION=="add", SUBSYSTEM=="mem", KERNEL=="null", TAG+="added"
@@ -34,10 +22,10 @@ udevadm trigger -c add /dev/null
 while : ; do
     test -f /run/udev/tags/added/c1:3 &&
         ! test -f /run/udev/tags/changed/c1:3 &&
-        has_tag added &&
-        has_current_tag added &&
-        ! has_tag changed &&
-        ! has_current_tag changed &&
+        udevadm info /dev/null | grep -q 'E: TAGS=.*:added:.*' &&
+        udevadm info /dev/null | grep -q 'E: CURRENT_TAGS=.*:added:.*' &&
+        udevadm info /dev/null | grep -q -v 'E: TAGS=.*:changed:.*' &&
+        udevadm info /dev/null | grep -q -v 'E: CURRENT_TAGS=.*:changed:.*' &&
         break
 
     sleep .5
@@ -49,10 +37,10 @@ udevadm trigger -c change /dev/null
 while : ; do
     test -f /run/udev/tags/added/c1:3 &&
         test -f /run/udev/tags/changed/c1:3 &&
-        has_tag added &&
-        ! has_current_tag added &&
-        has_tag changed &&
-        has_current_tag changed &&
+        udevadm info /dev/null | grep -q 'E: TAGS=.*:added:.*' &&
+        udevadm info /dev/null | grep -q -v 'E: CURRENT_TAGS=.*:added:.*' &&
+        udevadm info /dev/null | grep -q 'E: TAGS=.*:changed:.*' &&
+        udevadm info /dev/null | grep -q 'E: CURRENT_TAGS=.*:changed:.*' &&
         break
 
     sleep .5
@@ -64,10 +52,10 @@ udevadm trigger -c add /dev/null
 while : ; do
     test -f /run/udev/tags/added/c1:3 &&
         test -f /run/udev/tags/changed/c1:3 &&
-        has_tag added &&
-        has_current_tag added &&
-        has_tag changed &&
-        ! has_current_tag changed &&
+        udevadm info /dev/null | grep -q 'E: TAGS=.*:added:.*' &&
+        udevadm info /dev/null | grep -q 'E: CURRENT_TAGS=.*:added:.*' &&
+        udevadm info /dev/null | grep -q 'E: TAGS=.*:changed:.*' &&
+        udevadm info /dev/null | grep -q -v 'E: CURRENT_TAGS=.*:changed:.*' &&
         break
 
     sleep .5