]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl: implement a new "whoami" verb, that just returns unit of caller/PID
authorLennart Poettering <lennart@poettering.net>
Mon, 3 Jul 2023 12:36:14 +0000 (14:36 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Tue, 4 Jul 2023 00:05:02 +0000 (01:05 +0100)
man/systemctl.xml
src/systemctl/meson.build
src/systemctl/systemctl-whoami.c [new file with mode: 0644]
src/systemctl/systemctl-whoami.h [new file with mode: 0644]
src/systemctl/systemctl.c
test/units/testsuite-23.whoami.sh [new file with mode: 0755]

index cc7d2ea08a26c097bde50308f366a0f20ded1ee8..2e2daa4526cb5402db269c8d3f2eae52fcf37371 100644 (file)
@@ -740,6 +740,15 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
             to be started again, use this command to make it startable again.</para>
           </listitem>
         </varlistentry>
+
+        <varlistentry>
+          <term><command>whoami [<replaceable>PID</replaceable>…]</command></term>
+
+          <listitem><para>Returns the units the processes referenced by the given PIDs belong to (one per
+          line). If no PID is specified returns the unit the <command>systemctl</command> command is invoked
+          in.</para></listitem>
+        </varlistentry>
+
       </variablelist>
     </refsect2>
 
index 07049ca920fcba78140141d1cece730f2d6da6c9..f45cbc47d305780e2bb02d7015435a087ab00b53 100644 (file)
@@ -36,6 +36,7 @@ systemctl_sources = files(
         'systemctl-sysv-compat.c',
         'systemctl-trivial-method.c',
         'systemctl-util.c',
+        'systemctl-whoami.c',
         'systemctl.c',
 )
 
diff --git a/src/systemctl/systemctl-whoami.c b/src/systemctl/systemctl-whoami.c
new file mode 100644 (file)
index 0000000..4ee6592
--- /dev/null
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "bus-error.h"
+#include "bus-locator.h"
+#include "systemctl.h"
+#include "systemctl-util.h"
+#include "systemctl-whoami.h"
+#include "parse-util.h"
+
+static int lookup_pid(sd_bus *bus, pid_t pid) {
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        _cleanup_free_ char *unit = NULL;
+        const char *path;
+        int r;
+
+        r = bus_call_method(bus, bus_systemd_mgr, "GetUnitByPID", &error, &reply, "u", (uint32_t) pid);
+        if (r < 0)
+                return log_error_errno(r, "Failed to get unit for ourselves: %s", bus_error_message(&error, r));
+
+        r = sd_bus_message_read(reply, "o", &path);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = unit_name_from_dbus_path(path, &unit);
+        if (r < 0)
+                return log_error_errno(r, "Failed to extract unit name from D-Bus object path '%s': %m", path);
+
+        printf("%s\n", unit);
+        return 0;
+}
+
+int verb_whoami(int argc, char *argv[], void *userdata) {
+        sd_bus *bus;
+        int r;
+
+        r = acquire_bus(BUS_FULL, &bus);
+        if (r < 0)
+                return r;
+
+        char **pids = strv_skip(argv, 1);
+
+        if (strv_isempty(pids)) {
+
+                if (arg_transport != BUS_TRANSPORT_LOCAL)
+                        return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), "Refusing to look up local PID on remote host.");
+
+                return lookup_pid(bus, 0);
+        } else {
+                int ret = 0;
+
+                STRV_FOREACH(p, pids) {
+                        pid_t pid;
+
+                        r = parse_pid(*p, &pid);
+                        if (r < 0) {
+                                log_error_errno(r, "Failed to parse PID: %s", *p);
+                                if (ret >= 0)
+                                        ret = r;
+                                continue;
+                        }
+
+                        r = lookup_pid(bus, pid);
+                        if (r < 0 && ret >= 0)
+                                ret = r;
+                }
+
+                return ret;
+        }
+}
diff --git a/src/systemctl/systemctl-whoami.h b/src/systemctl/systemctl-whoami.h
new file mode 100644 (file)
index 0000000..abdd13b
--- /dev/null
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+int verb_whoami(int argc, char *argv[], void *userdata);
index 143c8b41b28aa525a41006d1e3d8387b994a10ff..989318360cf33c2e2e1fb7ff36ee33c8e627f878 100644 (file)
@@ -59,6 +59,7 @@
 #include "systemctl-sysv-compat.h"
 #include "systemctl-trivial-method.h"
 #include "systemctl-util.h"
+#include "systemctl-whoami.h"
 #include "systemctl.h"
 #include "terminal-util.h"
 #include "time-util.h"
@@ -193,7 +194,9 @@ static int systemctl_help(void) {
                "  service-log-level SERVICE [LEVEL]   Get/set logging threshold for service\n"
                "  service-log-target SERVICE [TARGET] Get/set logging target for service\n"
                "  reset-failed [PATTERN...]           Reset failed state for all, one, or more\n"
-               "                                      units"
+               "                                      units\n"
+               "  whoami [PID...]                     Return unit caller or specified PIDs are\n"
+               "                                      part of\n"
                "\n%3$sUnit File Commands:%4$s\n"
                "  list-unit-files [PATTERN...]        List installed unit files\n"
                "  enable [UNIT...|PATH...]            Enable one or more unit files\n"
@@ -1213,6 +1216,7 @@ static int systemctl_main(int argc, char *argv[]) {
                 { "edit",                  2,        VERB_ANY, VERB_ONLINE_ONLY, verb_edit                    },
                 { "bind",                  3,        4,        VERB_ONLINE_ONLY, verb_bind                    },
                 { "mount-image",           4,        5,        VERB_ONLINE_ONLY, verb_mount_image             },
+                { "whoami",                VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_whoami                  },
                 {}
         };
 
diff --git a/test/units/testsuite-23.whoami.sh b/test/units/testsuite-23.whoami.sh
new file mode 100755 (executable)
index 0000000..a0c73b8
--- /dev/null
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+set -eux
+set -o pipefail
+
+test "$(systemctl whoami)" = testsuite-23.service
+test "$(systemctl whoami $$)" = testsuite-23.service
+
+systemctl whoami 1 $$ 1 | cmp - /dev/fd/3 3<<'EOF'
+init.scope
+testsuite-23.service
+init.scope
+EOF