From 6bdf70432614ad7609daab8b7e0d6040ce45d76a Mon Sep 17 00:00:00 2001 From: Dylan Ratcliffe Date: Mon, 13 Dec 2021 09:19:33 +0000 Subject: [PATCH 1/2] dbus: add ability to query by pid Allows users to get the unit name by PID. Similar to `systemctl status {pid}` --- dbus/methods.go | 18 ++++++++++++++++++ dbus/methods_test.go | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/dbus/methods.go b/dbus/methods.go index f577ab37..8ab380d9 100644 --- a/dbus/methods.go +++ b/dbus/methods.go @@ -417,6 +417,24 @@ func (c *Conn) listUnitsInternal(f storeFunc) ([]UnitStatus, error) { return status, nil } +func (c *Conn) getUnitInternal(f storeFunc) (string, error) { + var result dbus.ObjectPath + + err := f(&result) + + // Nothing in this library actually accepts a dbus.ObjectPath, so it's much + // more useful as a name + name := unitName(result) + + return name, err +} + +// GetUnitByPIDContext returns the unit name for a given PID. The PID must refer +// to an existing system process +func (c *Conn) GetUnitByPIDContext(ctx context.Context, pid uint32) (string, error) { + return c.getUnitInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.GetUnitByPID", 0, pid).Store) +} + // Deprecated: use ListUnitsContext instead. func (c *Conn) ListUnits() ([]UnitStatus, error) { return c.ListUnitsContext(context.Background()) diff --git a/dbus/methods_test.go b/dbus/methods_test.go index 55bc2c9c..d0ba2bf2 100644 --- a/dbus/methods_test.go +++ b/dbus/methods_test.go @@ -450,6 +450,22 @@ func TestReloadOrRestartUnit(t *testing.T) { } } +// Ensure that GetUnitByPIDContext works. +func TestGetUnitByPIDContext(t *testing.T) { + conn := setupConn(t) + defer conn.Close() + + name, err := conn.GetUnitByPIDContext(context.Background(), 1) + + if err != nil { + t.Error(err) + } + + if name == "" { + t.Fatal("name is empty") + } +} + // Ensure that ListUnitsByNames works. func TestListUnitsByNames(t *testing.T) { target1 := "systemd-journald.service" From fd56b7311968ab0add68760d4bd1f7add80fc3f2 Mon Sep 17 00:00:00 2001 From: Dylan Ratcliffe Date: Mon, 13 Dec 2021 10:01:25 +0000 Subject: [PATCH 2/2] dbus: add options for name & path PID-based queries can now return either a name or a path --- dbus/methods.go | 27 ++++++++++++++++----------- dbus/methods_test.go | 22 +++++++++++++++++++--- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/dbus/methods.go b/dbus/methods.go index 8ab380d9..074148cb 100644 --- a/dbus/methods.go +++ b/dbus/methods.go @@ -417,22 +417,27 @@ func (c *Conn) listUnitsInternal(f storeFunc) ([]UnitStatus, error) { return status, nil } -func (c *Conn) getUnitInternal(f storeFunc) (string, error) { +// GetUnitByPID returns the unit object path of the unit a process ID +// belongs to. It takes a UNIX PID and returns the object path. The PID must +// refer to an existing system process +func (c *Conn) GetUnitByPID(ctx context.Context, pid uint32) (dbus.ObjectPath, error) { var result dbus.ObjectPath - err := f(&result) - - // Nothing in this library actually accepts a dbus.ObjectPath, so it's much - // more useful as a name - name := unitName(result) + err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.GetUnitByPID", 0, pid).Store(&result) - return name, err + return result, err } -// GetUnitByPIDContext returns the unit name for a given PID. The PID must refer -// to an existing system process -func (c *Conn) GetUnitByPIDContext(ctx context.Context, pid uint32) (string, error) { - return c.getUnitInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.GetUnitByPID", 0, pid).Store) +// GetUnitNameByPID returns the name of the unit a process ID belongs to. It +// takes a UNIX PID and returns the object path. The PID must refer to an +// existing system process +func (c *Conn) GetUnitNameByPID(ctx context.Context, pid uint32) (string, error) { + path, err := c.GetUnitByPID(ctx, pid) + if err != nil { + return "", err + } + + return unitName(path), nil } // Deprecated: use ListUnitsContext instead. diff --git a/dbus/methods_test.go b/dbus/methods_test.go index d0ba2bf2..30cc1324 100644 --- a/dbus/methods_test.go +++ b/dbus/methods_test.go @@ -450,12 +450,28 @@ func TestReloadOrRestartUnit(t *testing.T) { } } -// Ensure that GetUnitByPIDContext works. -func TestGetUnitByPIDContext(t *testing.T) { +// Ensure that GetUnitByPID works. +func TestGetUnitByPID(t *testing.T) { conn := setupConn(t) defer conn.Close() - name, err := conn.GetUnitByPIDContext(context.Background(), 1) + path, err := conn.GetUnitByPID(context.Background(), 1) + + if err != nil { + t.Error(err) + } + + if path == "" { + t.Fatal("path is empty") + } +} + +// Ensure that GetUnitNameByPID works. +func TestGetUnitNameByPID(t *testing.T) { + conn := setupConn(t) + defer conn.Close() + + name, err := conn.GetUnitNameByPID(context.Background(), 1) if err != nil { t.Error(err)