Attach user/shell session to systemd slice/cgroup

On an RHEL7.X box, I have created a custom service for systemd at /etc/systemd/system/myService@.service

[Unit]
Description="myService Instance : %i"
#Wants=network-online.target


[Service]
User=%i
Group=%i
<remainder of myService@.service file>

Its working where I can see the CGroup/Systemd-slice list of processes after startup

[myInstance@myHostname config]$ systemctl status myService@myInstance
● myService@myInstance.service - "myService Instance : myInstance"
   Loaded: loaded (/etc/systemd/system/myService@.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2022-04-10 19:11:43 BST; 1h 24min ago
 Main PID: 15042 (myMainProcess)
   Status: "Restarted all services successfully"
   CGroup: /system.slice/system-myService.slice/myService@myInstance.service
           ├─15042 /myPathTo/myInstance/bin/myMainProcess -c 20319 -m 20320
           ├─16918 /myPathTo/myInstance/bin/myOtherProc1
           └─17440 /myPathTo/myInstance/bin/myOtherProc2

But occasionally I need to login manually as USER=myInstance to manually action a few things including starting additional services, but when I start a new process in this SUDO session, I understandably have a different CGROUP context

sudo su - myInstance
bash-4.2$ % myNewManualProcess3 &
[1] 7665
bash-4.2$ ps -o cgroup -p 7665
CGROUP
11:devices:/user.slice,1:name=systemd:/user.slice/user-0.slice/session-22808.scope

In ideal world, I'd like all commands from that SUDO login-session to be in the Systemd-based CGROUP:

/system.slice/system-myService.slice/myService@myInstance.service

But I would settle for the ability to start a new process with the correct CGROUP context.

Either way at the end of the day, I am hoping to see something like this. Not just for visual purposes, but systemd monitoring/mgmt, especially on "systemctl stop myService@myInstance"

[myInstance@myHostname config]$ systemctl status myService@myInstance
● myService@myInstance.service - "myService Instance : myInstance"
   Loaded: loaded (/etc/systemd/system/myService@.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2022-04-10 19:11:43 BST; 1h 24min ago
 Main PID: 15042 (myMainProcess)
   Status: "Restarted all services successfully"
   CGroup: /system.slice/system-myService.slice/myService@myInstance.service
           ├─15042 /myPathTo/myInstance/bin/myMainProcess -c 20319 -m 20320
           ├─16918 /myPathTo/myInstance/bin/myOtherProc1
           └─17440 /myPathTo/myInstance/bin/myOtherProc2
           └─7665  /myPathTo/myInstance/bin/myNewManualProcess3

I can imagine all sorts of security arguments against trying this, but can we assume for now proper network/SUDO security is in place against unauthorized users and skip that type of answer. If there is a stablity argument against doing this, that would be intereseting to hear.

I would also like to avoid an alternative solution where we add a "launcher" service or shell in the original systemd startup context and then trying to attach to it, like with a "screen" session. I am really just trying to find a solution with CGROUP context switching.

Thanks In Advance!

Hello,

One way of doing this would be to start the process, then add its PID to the tasklist for the service cgroup in question.

For example, here's a sample session where I run a pre-prepared script as the Web server user (which does nothing other than run sleep 1 in an infinite loop), and then as root I add that script to the httpd.service cgroup task list, thus making it show up in the output of systemctl status httpd.service:

# id
uid=0(root) gid=0(root) groups=0(root)
# systemctl status httpd.service | grep -A12 CGroup
   CGroup: /system.slice/httpd.service
           ├─  415 /usr/sbin/httpd -DFOREGROUND
           ├─10811 /usr/sbin/httpd -DFOREGROUND
           ├─18780 /usr/sbin/httpd -DFOREGROUND
           ├─18781 /usr/sbin/httpd -DFOREGROUND
           ├─18782 /usr/sbin/httpd -DFOREGROUND
           ├─18783 /usr/sbin/httpd -DFOREGROUND
           ├─18784 /usr/sbin/httpd -DFOREGROUND
           ├─19067 /usr/sbin/httpd -DFOREGROUND
           ├─20172 /usr/sbin/httpd -DFOREGROUND
           ├─20178 /usr/sbin/httpd -DFOREGROUND
           └─20179 /usr/sbin/httpd -DFOREGROUND

# su - apache
Last login: Sun Apr 10 23:04:19 BST 2022 on pts/4
-bash-4.2$ /tmp/test.sh &
[1] 20213
-bash-4.2$ exit
logout
# echo 20213 > /sys/fs/cgroup/systemd/system.slice/httpd.service/tasks 
# systemctl status httpd.service | grep -A14 CGroup
   CGroup: /system.slice/httpd.service
           ├─  415 /usr/sbin/httpd -DFOREGROUND
           ├─10811 /usr/sbin/httpd -DFOREGROUND
           ├─18780 /usr/sbin/httpd -DFOREGROUND
           ├─18781 /usr/sbin/httpd -DFOREGROUND
           ├─18782 /usr/sbin/httpd -DFOREGROUND
           ├─18783 /usr/sbin/httpd -DFOREGROUND
           ├─18784 /usr/sbin/httpd -DFOREGROUND
           ├─19067 /usr/sbin/httpd -DFOREGROUND
           ├─20172 /usr/sbin/httpd -DFOREGROUND
           ├─20178 /usr/sbin/httpd -DFOREGROUND
           ├─20179 /usr/sbin/httpd -DFOREGROUND
           ├─20213 /bin/bash /tmp/test.sh
           └─20284 sleep 1

# 

Hope this helps !

This method seems to work on a single PID basis and all the child PIDs come along for the ride, but fundamentally requires me to exit the $SHELL back to root (or do some SUDO voodoo) after logging into the $SHELL .

I was hoping to change default CGROUP on login and/or invoke commands using a different CGROUP.

How about :

sudo systemd-run --slice=your.slice <command or script>

That didn't work, I got this error

% systemd-run --slice=/system.slice/system-myService.slice/myService@myInstance.service tcsh
Failed to start transient service unit: Invalid slice name system.slice-system\x2dmyService.slice-myService\x40myInstance.service.mount

NAME
systemd-run - Run programs in transient scope or service or timer units

SYNOPSIS
systemd-run [OPTIONS...] COMMAND [ARGS...]

MANPAGE seems to indicate this cmd is more for transient units

   systemd-run [OPTIONS...] [TIMER OPTIONS...] {COMMAND} [ARGS...]

DESCRIPTION
systemd-run may be used to create and start a transient .service or a transient .timer or a .scope unit and run the specified COMMAND in it.

You do not specify service but slice.

systemd-run --slice="system-myService.slice"  <command or script>

This will not work if you specify shell, as it will just run in slice and exit immediately.
Try to test something like sleep 100 and check output of systemd-cgls --no-pager to see if result is expected.