Add well-known-names -> unique names on graph
authorDawid Kuczma <d.kuczma@partner.samsung.com>
Tue, 5 Dec 2017 08:31:16 +0000 (09:31 +0100)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Mon, 12 Feb 2024 15:37:43 +0000 (16:37 +0100)
Usage:
--well-known-names=true

Change-Id: Ife01bd8d1a2d6acc4a45c6595bcc52c15d523742

src/libsystemd/sd-bus/bus-dump.c
src/libsystemd/sd-bus/bus-dump.h
src/libsystemd/sd-bus/busctl.c

index 548a6ba..301915d 100644 (file)
@@ -109,6 +109,77 @@ int bus_message_dot_dump(sd_bus_message *m, FILE *f) {
         return 0;
 }
 
+void dot_dump_unique_name(sd_bus *bus, char *name, Hashmap *hashmap_wkn, FILE *f, sd_bus_message *m) {
+        int r;
+        bool update = false;
+        int obtained;
+        char *uname;
+        char *contents = NULL;
+        char type;
+        union {
+                uint8_t u8;
+                uint16_t u16;
+                int16_t s16;
+                uint32_t u32;
+                int32_t s32;
+                uint64_t u64;
+                int64_t s64;
+                double d64;
+                const char *string;
+                int i;
+        } basic;
+        sd_bus_creds *creds = NULL;
+
+        if (m->member && !strcmp(m->member, "NameOwnerChanged")) {
+
+                r = sd_bus_message_peek_type(m, &type, &contents);
+
+                if (r > 0 && bus_type_is_container(type) <= 0) {
+                        if (r >= 0)
+                                r = sd_bus_message_read_basic(m, type, &basic);
+
+                        if (r >= 0) {
+                                char *free_name = hashmap_get(hashmap_wkn, basic.string);
+                                free(free_name);
+                                update = true;
+                        }
+                }
+        }
+
+        int x, y;
+
+        if (!f)
+                f = stdout;
+
+        if (!name)
+                return;
+
+        if (name[0] == ':')
+                return;
+
+        obtained = hashmap_get(hashmap_wkn, name);
+
+        if (obtained && !update)
+                return;
+
+        r = sd_bus_get_name_creds(bus, name, SD_BUS_CREDS_UNIQUE_NAME, &creds);
+
+        if (r >= 0)
+                r = sd_bus_creds_get_unique_name(creds, &uname);
+
+        if (r < 0)
+                return;
+
+        fprintf(f, "\t\"%s\"->\"%s\" [ color = blue, penwidth = 4];\n", name, uname);
+
+        if (update)
+                hashmap_update(hashmap_wkn, name, strdup(uname));
+        else
+                hashmap_put(hashmap_wkn, strdup(name), strdup(uname));
+
+}
+
+
 int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
         unsigned level = 1;
         int r;
index 5b6bde5..1a5e9bc 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <stdbool.h>
 #include <stdio.h>
+#include <hashmap.h>
 
 #include "sd-bus.h"
 
@@ -30,6 +31,7 @@ enum {
 };
 
 int bus_message_dot_dump(sd_bus_message *m, FILE *f);
+void dot_dump_unique_name(sd_bus *bus, char *name, Hashmap *hashmap_wkn, FILE *f, sd_bus_message *m);
 
 int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags);
 
index f8c799d..9270195 100644 (file)
@@ -68,6 +68,7 @@ static int arg_receiver_pid = 0;
 static bool arg_pid = false;
 static bool arg_dot = false;
 static bool monitor_run_condi = true;
+static bool arg_well_known_names;
 
 #define NAME_IS_ACQUIRED INT_TO_PTR(1)
 #define NAME_IS_ACTIVATABLE INT_TO_PTR(2)
@@ -1077,19 +1078,26 @@ static int introspect(sd_bus *bus, char **argv) {
         return 0;
 }
 
-static int message_dump(sd_bus_message *m, FILE *f) {
+static int message_dump(sd_bus_message *m, FILE *f, Hashmap *hashmap_wkn, sd_bus *bus) {
         return bus_message_dump(m, f, BUS_MESSAGE_DUMP_WITH_HEADER);
 }
 
-static int message_pcap(sd_bus_message *m, FILE *f) {
+static int message_pcap(sd_bus_message *m, FILE *f, Hashmap *hashmap_wkn, sd_bus *bus) {
         return bus_message_pcap_frame(m, arg_snaplen, f);
 }
 
-static int message_dot(sd_bus_message *m, FILE *f) {
+static int message_dot(sd_bus_message *m, FILE *f, Hashmap *hashmap_wkn, sd_bus *bus) {
+
+        if (arg_well_known_names){
+
+                dot_dump_unique_name(bus, sd_bus_message_get_sender(m), hashmap_wkn, f, m);
+                dot_dump_unique_name(bus, sd_bus_message_get_destination(m), hashmap_wkn, f, m);
+        }
+
         return bus_message_dot_dump(m, f);
 }
 
-static bool check_pid(sd_bus *bus, Hashmap *hashmap_pids, char *name, int compare_pid, sd_bus_message *m) {
+static bool check_pid(sd_bus *bus, Hashmap *hashmap_pids, char *name, int compare_pid) {
         pid_t pid;
         sd_bus_creds *creds = NULL;
         int r;
@@ -1116,19 +1124,22 @@ static bool check_pid(sd_bus *bus, Hashmap *hashmap_pids, char *name, int compar
 
 }
 
-static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FILE *f)) {
+static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FILE *f, Hashmap *hashmap_wkn, sd_bus *bus)) {
         bool added_something = false;
         char **i;
         int r;
         bool receiver_pid_match;
         bool sender_pid_match;
+        sd_bus_creds *creds = NULL;
         _cleanup_hashmap_free_ Hashmap *hashmap_pids = NULL;
+        _cleanup_hashmap_free_ Hashmap *hashmap_names = NULL;
+        _cleanup_strv_free_ char **acquired = NULL, **activatable = NULL;
 
         hashmap_pids = hashmap_new(&string_hash_ops);
+        hashmap_names = hashmap_new(&string_hash_ops);
 
         STRV_FOREACH(i, argv+1) {
                 _cleanup_free_ char *m = NULL;
-
                 if (!service_name_is_valid(*i)) {
                         log_error("Invalid service name '%s'", *i);
                         return -EINVAL;
@@ -1179,13 +1190,13 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL
                         return log_error_errno(r, "Failed to process bus: %m");
 
                 if (m) {
+
                         if (arg_sender_pid != 0) {
                                 sender_pid_match = check_pid(
                                                         bus,
                                                         hashmap_pids,
                                                         sd_bus_message_get_sender(m),
-                                                        arg_sender_pid,
-                                                        m);
+                                                        arg_sender_pid);
                         }
 
                         if (arg_receiver_pid != 0) {
@@ -1193,12 +1204,11 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL
                                                         bus,
                                                         hashmap_pids,
                                                         sd_bus_message_get_destination(m),
-                                                        arg_receiver_pid,
-                                                        m);
+                                                        arg_receiver_pid);
                         }
 
                         if ((!arg_pid && receiver_pid_match && sender_pid_match) || (arg_pid && (receiver_pid_match || sender_pid_match))) {
-                                dump(m, stdout);
+                                dump(m, stdout, hashmap_names, bus);
                         }
 
                         fflush(stdout);
@@ -1805,6 +1815,8 @@ static int help(void) {
                "                          Only show message with sender pid equals SENDER_PID\n"
                "     --receiver-pid=RECEIVER_PID\n"
                "                          Only show message with receiver pid equals RECEIVER_PID\n"
+               "     --well-known-names=BOOL \n"
+               "                          Show well know names connected to unique names on graph\n"
                "Commands:\n"
                "  list                    List bus names\n"
                "  status [SERVICE]        Show bus service, process or bus owner credentials\n"
@@ -1871,6 +1883,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_PID,
                 ARG_SENDER_PID,
                 ARG_RECEIVER_PID,
+                ARG_WELL_KNOWN_NAMES,
         };
 
         static const struct option options[] = {
@@ -1900,6 +1913,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "pid",          required_argument, NULL, ARG_PID},
                 { "sender-pid", required_argument, NULL, ARG_SENDER_PID},
                 { "receiver-pid", required_argument, NULL, ARG_RECEIVER_PID},
+                { "well-known-names", required_argument, NULL, ARG_WELL_KNOWN_NAMES},
                 {},
         };
 
@@ -2069,6 +2083,10 @@ static int parse_argv(int argc, char *argv[]) {
                                 return 0;
                         break;
 
+                case ARG_WELL_KNOWN_NAMES:
+                        arg_well_known_names = parse_boolean(optarg);
+                        break;
+
                 case '?':
                         return -EINVAL;