]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/analyze/analyze.c
tree-wide: hook up image dissection policy logic everywhere
[thirdparty/systemd.git] / src / analyze / analyze.c
index ef2e60962b3e346ad46a6014c6da832cededdfcf..8bc533b20d860434bf181c55e417e1a24b8fe286 100644 (file)
 #include "analyze-calendar.h"
 #include "analyze-capability.h"
 #include "analyze-cat-config.h"
+#include "analyze-compare-versions.h"
 #include "analyze-condition.h"
 #include "analyze-critical-chain.h"
 #include "analyze-dot.h"
 #include "analyze-dump.h"
 #include "analyze-exit-status.h"
+#include "analyze-fdstore.h"
 #include "analyze-filesystems.h"
 #include "analyze-inspect-elf.h"
 #include "analyze-log-control.h"
+#include "analyze-malloc.h"
 #include "analyze-plot.h"
 #include "analyze-security.h"
 #include "analyze-service-watchdogs.h"
@@ -35,7 +38,6 @@
 #include "analyze-timestamp.h"
 #include "analyze-unit-files.h"
 #include "analyze-unit-paths.h"
-#include "analyze-compare-versions.h"
 #include "analyze-verify.h"
 #include "build.h"
 #include "bus-error.h"
@@ -90,7 +92,7 @@ usec_t arg_fuzz = 0;
 PagerFlags arg_pager_flags = 0;
 BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
 const char *arg_host = NULL;
-LookupScope arg_scope = LOOKUP_SCOPE_SYSTEM;
+RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
 RecursiveErrors arg_recursive_errors = _RECURSIVE_ERRORS_INVALID;
 bool arg_man = true;
 bool arg_generators = false;
@@ -107,6 +109,7 @@ bool arg_quiet = false;
 char *arg_profile = NULL;
 bool arg_legend = true;
 bool arg_table = false;
+ImagePolicy *arg_image_policy = NULL;
 
 STATIC_DESTRUCTOR_REGISTER(arg_dot_from_patterns, strv_freep);
 STATIC_DESTRUCTOR_REGISTER(arg_dot_to_patterns, strv_freep);
@@ -115,20 +118,20 @@ STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_security_policy, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_unit, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_profile, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
 
 int acquire_bus(sd_bus **bus, bool *use_full_bus) {
-        bool user = arg_scope != LOOKUP_SCOPE_SYSTEM;
         int r;
 
         if (use_full_bus && *use_full_bus) {
-                r = bus_connect_transport(arg_transport, arg_host, user, bus);
+                r = bus_connect_transport(arg_transport, arg_host, arg_runtime_scope, bus);
                 if (IN_SET(r, 0, -EHOSTDOWN))
                         return r;
 
                 *use_full_bus = false;
         }
 
-        return bus_connect_transport_systemd(arg_transport, arg_host, user, bus);
+        return bus_connect_transport_systemd(arg_transport, arg_host, arg_runtime_scope, bus);
 }
 
 int bus_get_unit_property_strv(sd_bus *bus, const char *path, const char *property, char ***strv) {
@@ -166,6 +169,23 @@ void time_parsing_hint(const char *p, bool calendar, bool timestamp, bool timesp
                            "Use 'systemd-analyze timespan \"%s\"' instead?", p);
 }
 
+int dump_fd_reply(sd_bus_message *message) {
+        int fd, r;
+
+        assert(message);
+
+        r = sd_bus_message_read(message, "h", &fd);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        fflush(stdout);
+        r = copy_bytes(fd, STDOUT_FILENO, UINT64_MAX, 0);
+        if (r < 0)
+                return r;
+
+        return 1;  /* Success */
+}
+
 static int help(int argc, char *argv[], void *userdata) {
         _cleanup_free_ char *link = NULL, *dot_link = NULL;
         int r;
@@ -211,6 +231,8 @@ static int help(int argc, char *argv[], void *userdata) {
                "  timespan SPAN...           Validate a time span\n"
                "  security [UNIT...]         Analyze security of unit\n"
                "  inspect-elf FILE...        Parse and print ELF package metadata\n"
+               "  malloc [D-BUS SERVICE...]  Dump malloc stats of a D-Bus service\n"
+               "  fdstore SERVICE...         Show file descriptor store contents of service\n"
                "\nOptions:\n"
                "     --recursive-errors=MODE Control which units are verified\n"
                "     --offline=BOOL          Perform a security review on unit file(s)\n"
@@ -248,6 +270,7 @@ static int help(int argc, char *argv[], void *userdata) {
                "  -q --quiet                 Do not emit hints\n"
                "     --root=PATH             Operate on an alternate filesystem root\n"
                "     --image=PATH            Operate on disk image as filesystem root\n"
+               "     --image-policy=POLICY   Specify disk image dissection policy\n"
                "\nSee the %s for details.\n",
                program_invocation_short_name,
                ansi_highlight(),
@@ -287,6 +310,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_PROFILE,
                 ARG_TABLE,
                 ARG_NO_LEGEND,
+                ARG_IMAGE_POLICY,
         };
 
         static const struct option options[] = {
@@ -319,6 +343,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "profile",          required_argument, NULL, ARG_PROFILE          },
                 { "table",            optional_argument, NULL, ARG_TABLE            },
                 { "no-legend",        optional_argument, NULL, ARG_NO_LEGEND        },
+                { "image-policy",     required_argument, NULL, ARG_IMAGE_POLICY     },
                 {}
         };
 
@@ -365,15 +390,15 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_SYSTEM:
-                        arg_scope = LOOKUP_SCOPE_SYSTEM;
+                        arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
                         break;
 
                 case ARG_USER:
-                        arg_scope = LOOKUP_SCOPE_USER;
+                        arg_runtime_scope = RUNTIME_SCOPE_USER;
                         break;
 
                 case ARG_GLOBAL:
-                        arg_scope = LOOKUP_SCOPE_GLOBAL;
+                        arg_runtime_scope = RUNTIME_SCOPE_GLOBAL;
                         break;
 
                 case ARG_ORDER:
@@ -502,6 +527,18 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_legend = false;
                         break;
 
+                case ARG_IMAGE_POLICY: {
+                        _cleanup_(image_policy_freep) ImagePolicy *p = NULL;
+
+                        r = image_policy_from_string(optarg, &p);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse image policy: %s", optarg);
+
+                        image_policy_free(arg_image_policy);
+                        arg_image_policy = TAKE_PTR(p);
+                        break;
+                }
+
                 case '?':
                         return -EINVAL;
 
@@ -513,20 +550,20 @@ static int parse_argv(int argc, char *argv[]) {
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Option --offline= is only supported for security right now.");
 
-        if (arg_json_format_flags != JSON_FORMAT_OFF && !STRPTR_IN_SET(argv[optind], "security", "inspect-elf", "plot"))
+        if (arg_json_format_flags != JSON_FORMAT_OFF && !STRPTR_IN_SET(argv[optind], "security", "inspect-elf", "plot", "fdstore"))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "Option --json= is only supported for security, inspect-elf, and plot right now.");
+                                       "Option --json= is only supported for security, inspect-elf, plot, and fdstore right now.");
 
         if (arg_threshold != 100 && !streq_ptr(argv[optind], "security"))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Option --threshold= is only supported for security right now.");
 
-        if (arg_scope == LOOKUP_SCOPE_GLOBAL &&
+        if (arg_runtime_scope == RUNTIME_SCOPE_GLOBAL &&
             !STR_IN_SET(argv[optind] ?: "time", "dot", "unit-paths", "verify"))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Option --global only makes sense with verbs dot, unit-paths, verify.");
 
-        if (streq_ptr(argv[optind], "cat-config") && arg_scope == LOOKUP_SCOPE_USER)
+        if (streq_ptr(argv[optind], "cat-config") && arg_runtime_scope == RUNTIME_SCOPE_USER)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Option --user is not supported for cat-config right now.");
 
@@ -601,6 +638,8 @@ static int run(int argc, char *argv[]) {
                 { "timespan",          2,        VERB_ANY, 0,            verb_timespan          },
                 { "security",          VERB_ANY, VERB_ANY, 0,            verb_security          },
                 { "inspect-elf",       2,        VERB_ANY, 0,            verb_elf_inspection    },
+                { "malloc",            VERB_ANY, VERB_ANY, 0,            verb_malloc            },
+                { "fdstore",           2,        VERB_ANY, 0,            verb_fdstore           },
                 {}
         };
 
@@ -621,10 +660,12 @@ static int run(int argc, char *argv[]) {
 
                 r = mount_image_privately_interactively(
                                 arg_image,
+                                arg_image_policy,
                                 DISSECT_IMAGE_GENERIC_ROOT |
                                 DISSECT_IMAGE_RELAX_VAR_CHECK |
                                 DISSECT_IMAGE_READ_ONLY,
                                 &unlink_dir,
+                                /* ret_dir_fd= */ NULL,
                                 &loop_device);
                 if (r < 0)
                         return r;