]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Add parser and printer for coredump filter mask
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 4 Apr 2020 13:02:12 +0000 (15:02 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 9 Apr 2020 10:51:41 +0000 (12:51 +0200)
src/shared/coredump-util.c [new file with mode: 0644]
src/shared/coredump-util.h [new file with mode: 0644]
src/shared/meson.build
src/test/meson.build
src/test/test-coredump-util.c [new file with mode: 0644]

diff --git a/src/shared/coredump-util.c b/src/shared/coredump-util.c
new file mode 100644 (file)
index 0000000..3fa8664
--- /dev/null
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "coredump-util.h"
+#include "extract-word.h"
+#include "string-table.h"
+
+static const char *const coredump_filter_table[_COREDUMP_FILTER_MAX] = {
+        [COREDUMP_FILTER_PRIVATE_ANONYMOUS]   = "private-anonymous",
+        [COREDUMP_FILTER_SHARED_ANONYMOUS]    = "shared-anonymous",
+        [COREDUMP_FILTER_PRIVATE_FILE_BACKED] = "private-file-backed",
+        [COREDUMP_FILTER_SHARED_FILE_BACKED]  = "shared-file-backed",
+        [COREDUMP_FILTER_ELF_HEADERS]         = "elf-headers",
+        [COREDUMP_FILTER_PRIVATE_HUGE]        = "private-huge",
+        [COREDUMP_FILTER_SHARED_HUGE]         = "shared-huge",
+        [COREDUMP_FILTER_PRIVATE_DAX]         = "private-dax",
+        [COREDUMP_FILTER_SHARED_DAX]          = "shared-dax",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(coredump_filter, CoredumpFilter);
+
+int coredump_filter_mask_from_string(const char *s, uint64_t *ret) {
+        uint64_t m = 0;
+
+        assert(s);
+        assert(ret);
+
+        for (;;) {
+                _cleanup_free_ char *n = NULL;
+                CoredumpFilter v;
+                int r;
+
+                r = extract_first_word(&s, &n, NULL, 0);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        break;
+
+                if (streq(n, "default")) {
+                        m |= COREDUMP_FILTER_MASK_DEFAULT;
+                        continue;
+                }
+
+                if (streq(n, "all")) {
+                        m = UINT64_MAX;
+                        continue;
+                }
+
+                v = coredump_filter_from_string(n);
+                if (v >= 0) {
+                        m |= 1u << v;
+                        continue;
+                }
+
+                uint64_t x;
+                r = safe_atoux64(n, &x);
+                if (r < 0)
+                        return r;
+
+                m |= x;
+        }
+
+        *ret = m;
+        return 0;
+}
diff --git a/src/shared/coredump-util.h b/src/shared/coredump-util.h
new file mode 100644 (file)
index 0000000..f7fb5f1
--- /dev/null
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include "macro.h"
+
+typedef enum CoredumpFilter {
+        COREDUMP_FILTER_PRIVATE_ANONYMOUS = 0,
+        COREDUMP_FILTER_SHARED_ANONYMOUS,
+        COREDUMP_FILTER_PRIVATE_FILE_BACKED,
+        COREDUMP_FILTER_SHARED_FILE_BACKED,
+        COREDUMP_FILTER_ELF_HEADERS,
+        COREDUMP_FILTER_PRIVATE_HUGE,
+        COREDUMP_FILTER_SHARED_HUGE,
+        COREDUMP_FILTER_PRIVATE_DAX,
+        COREDUMP_FILTER_SHARED_DAX,
+        _COREDUMP_FILTER_MAX,
+        _COREDUMP_FILTER_INVALID = -1,
+} CoredumpFilter;
+
+#define COREDUMP_FILTER_MASK_DEFAULT (1u << COREDUMP_FILTER_PRIVATE_ANONYMOUS | \
+                                      1u << COREDUMP_FILTER_SHARED_ANONYMOUS | \
+                                      1u << COREDUMP_FILTER_ELF_HEADERS | \
+                                      1u << COREDUMP_FILTER_PRIVATE_HUGE)
+
+const char* coredump_filter_to_string(CoredumpFilter i) _const_;
+CoredumpFilter coredump_filter_from_string(const char *s) _pure_;
+int coredump_filter_mask_from_string(const char *s, uint64_t *ret);
index 45a723f3633256e20cb55f2b76a3e05bdcd9243c..d1832a1f53f2774e88ef3fcbe0580e33ff9c1292 100644 (file)
@@ -51,6 +51,8 @@ shared_sources = files('''
         condition.h
         conf-parser.c
         conf-parser.h
+        coredump-util.c
+        coredump-util.h
         cpu-set-util.c
         cpu-set-util.h
         crypt-util.c
index 6297875c0d9b96563b1a650f29c95fc407217d9c..a674d6cfe9313c13ac319535bb6e304fe1a4bafb 100644 (file)
@@ -588,6 +588,10 @@ tests += [
          [],
          []],
 
+        [['src/test/test-coredump-util.c'],
+         [],
+         []],
+
         [['src/test/test-daemon.c'],
          [],
          []],
diff --git a/src/test/test-coredump-util.c b/src/test/test-coredump-util.c
new file mode 100644 (file)
index 0000000..14a7800
--- /dev/null
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "alloc-util.h"
+#include "coredump-util.h"
+#include "macro.h"
+#include "tests.h"
+
+static void test_coredump_filter_to_from_string(void) {
+        log_info("/* %s */", __func__);
+
+        for (CoredumpFilter i = 0; i < _COREDUMP_FILTER_MAX; i++) {
+                const char *n;
+
+                assert_se(n = coredump_filter_to_string(i));
+                log_info("0x%x\t%s", 1<<i, n);
+                assert_se(coredump_filter_from_string(n) == i);
+
+                uint64_t f;
+                assert_se(coredump_filter_mask_from_string(n, &f) == 0);
+                assert_se(f == 1u << i);
+        }
+}
+
+static void test_coredump_filter_mask_from_string(void) {
+        log_info("/* %s */", __func__);
+
+        uint64_t f;
+        assert_se(coredump_filter_mask_from_string("default", &f) == 0);
+        assert_se(f == COREDUMP_FILTER_MASK_DEFAULT);
+
+        assert_se(coredump_filter_mask_from_string("  default\tdefault\tdefault  ", &f) == 0);
+        assert_se(f == COREDUMP_FILTER_MASK_DEFAULT);
+
+        assert_se(coredump_filter_mask_from_string("defaulta", &f) < 0);
+        assert_se(coredump_filter_mask_from_string("default defaulta default", &f) < 0);
+        assert_se(coredump_filter_mask_from_string("default default defaulta", &f) < 0);
+
+        assert_se(coredump_filter_mask_from_string("private-anonymous default", &f) == 0);
+        assert_se(f == COREDUMP_FILTER_MASK_DEFAULT);
+
+        assert_se(coredump_filter_mask_from_string("shared-file-backed shared-dax", &f) == 0);
+        assert_se(f == (1 << COREDUMP_FILTER_SHARED_FILE_BACKED |
+                        1 << COREDUMP_FILTER_SHARED_DAX));
+
+        assert_se(coredump_filter_mask_from_string("private-file-backed private-dax 0xF", &f) == 0);
+        assert_se(f == (1 << COREDUMP_FILTER_PRIVATE_FILE_BACKED |
+                        1 << COREDUMP_FILTER_PRIVATE_DAX |
+                        0xF));
+
+        assert_se(coredump_filter_mask_from_string("11", &f) == 0);
+        assert_se(f == 0x11);
+
+        assert_se(coredump_filter_mask_from_string("0x1101", &f) == 0);
+        assert_se(f == 0x1101);
+
+        assert_se(coredump_filter_mask_from_string("0", &f) == 0);
+        assert_se(f == 0);
+
+        assert_se(coredump_filter_mask_from_string("all", &f) == 0);
+        assert_se(FLAGS_SET(f, (1 << COREDUMP_FILTER_PRIVATE_ANONYMOUS |
+                                1 << COREDUMP_FILTER_SHARED_ANONYMOUS |
+                                1 << COREDUMP_FILTER_PRIVATE_FILE_BACKED |
+                                1 << COREDUMP_FILTER_SHARED_FILE_BACKED |
+                                1 << COREDUMP_FILTER_ELF_HEADERS |
+                                1 << COREDUMP_FILTER_PRIVATE_HUGE |
+                                1 << COREDUMP_FILTER_SHARED_HUGE |
+                                1 << COREDUMP_FILTER_PRIVATE_DAX |
+                                1 << COREDUMP_FILTER_SHARED_DAX)));
+}
+
+int main(int argc, char **argv) {
+        test_setup_logging(LOG_INFO);
+
+        test_coredump_filter_to_from_string();
+        test_coredump_filter_mask_from_string();
+
+        return 0;
+}