Plenty of discussions going, but...really...simplest way to determine if your 
running directly from a systemd service is just check what cgroup you're 
running under.

Just check /proc/self/cgroup
________________________________
From: systemd-devel <systemd-devel-boun...@lists.freedesktop.org> on behalf of 
Chris Kottaridis <ch...@quietwind.net>
Sent: Monday, July 21, 2025 12:54 PM
To: Stef Bon <stef...@gmail.com>; systemd Mailing List 
<systemd-devel@lists.freedesktop.org>
Subject: [EXTERNAL] Re: [systemd-devel] Howto detect a program/service is 
started by systemd?

I don't know if it is appropriate or not, but I used the sd-bus library. I just 
ask systemd if my service is running. If it is running I then get the service's 
MainPID. If the mainPID matches my process pid then I started from the systemd. 
If


I don't know if it is appropriate or not, but I used the sd-bus library.
I just ask systemd if my service is running. If it is running I then
get the service's MainPID. If the mainPID matches my process pid then
I started from the systemd. If not then I didn't.

I only use it for debugging. If I started it from command line when I
debug I want logging to go to a file. If it started from systemd it
goes to journal. That is the extent of my usage.

The top level logic looks like:

const std::string systemd_destination = "org.freedesktop.systemd1";
const std::string systemd_quietwind_service_path = 
"/org/freedesktop/systemd1/unit/quietwind_2eweather_2eservice";
const std::string systemd_unit_interface = "org.freedesktop.systemd1.Unit";
const std::string systemd_service_interface = 
"org.freedesktop.systemd1.Service";

/*
    * If we have started from systemd then we always use
    * LOGGER_MODE_JOURNAL.
    */
  SdUnit sd_qw_unit(systemd_destination,
                       systemd_quietwind_service_path,
                       systemd_unit_interface);
  SdServiceUnit sd_qw_service_unit(systemd_destination,
                       systemd_quietwind_service_path,
                       systemd_service_interface);

  service_state = sd_qw_unit.getSubState();
  if (service_state.has_value() != true) {
    logger.log(LOG_ERR, "Can't get substate of quietwind weather service");
    exit(1);
  }

  service_pid = sd_qw_service_unit.getMainPID();
  if (service_pid.has_value() != true) {
    logger.log(LOG_ERR, "Can't get main pid of quietwind weather service");
    exit(1);
  }

  if (service_state == "running" && service_pid == getpid()) {
    in_systemd = true;
  }

  if (in_systemd == true) {
    logger.setMode(LOGGER_MODE_JOURNAL);
    logger.log(LOG_INFO, "Logging in Journal Mode");
  }

It took a while to figure out the naming structure. But after that getting
properties and executing commands is not so difficult. I used these pages
to figure it out:

Information about sd-bus library can be found here.
https://www.freedesktop.org/wiki/Software/dbus/<https://www.freedesktop.org/wiki/Software/dbus/
 >
https://www.freedesktop.org/software/systemd/man/latest/sd-bus.html<https://www.freedesktop.org/software/systemd/man/latest/sd-bus.html
 >
https://0pointer.net/blog/the-new-sd-bus-api-of-systemd.html<https://0pointer.net/blog/the-new-sd-bus-api-of-systemd.html
 >
https://manpages.ubuntu.com/manpages/bionic/man1/busctl.1.html<https://manpages.ubuntu.com/manpages/bionic/man1/busctl.1.html
 >
https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.systemd1.html<https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.systemd1.html
 >

Thanks
Chris


On 6/30/25 5:25 AM, Stef Bon wrote:

Hi,

it's important for a program to detect it has been started by systemd.
For example it does not have to fork since it has already been forked.

I've written a test script, which calls env, and there are a few
unique environment variables which are an indication it has been
started by systemd: SYSTEMD_EXEC_PID and INVOCATION_ID.

Is it a good way to test these environment vars (to detect started by
systemd) or is there a better way?

S. Bon

Reply via email to