Get process ID from "lxc exec" on host machine

,

Hello, I am trying to build automatization tool to deploy applications in containers and start them from host machine using “lxc exec”. I have issues monitoring them since I cannot retrieve PID of the process started.

I started a script inside container like this: “lxc exec c1 – /home/scripts/myscript.sh”
contents:

java -jar server.jar

Process of this script received PID 7705 (on host machine) but this script started a java application inside the container and the java process received PID 7749 (on host machine), however when I did pstree I do not see this process as subprocess (on host machine).

pstree -p -s 7705 -a

              └─lxc,7705 exec pidtest -- /home/scripts/myscript.sh
                  ├─{lxc},7738
                  ├─{lxc},7739
                  ├─{lxc},7740
                  ├─{lxc},7741
                  ├─{lxc},7742
                  ├─{lxc},7745
                  ├─{lxc},12997
                  ├─{lxc},12998
                  ├─{lxc},12999
                  ├─{lxc},28669
                  └─{lxc},28670

What is the corrent way to monitor processes (from the host machine) that are running inside containers ?

It’s reasonably straightforward to translate a host PID into a pidns PID by looking at /proc/PID/status but the reverse isn’t particularly easy.

You may have a PID 7749 in every container on your system. There is a mechanism to translate those PIDs but that involves send a specifically crafted structure (ucred) over a unix socket from within the container to the outside.

In your case, I guess you could get the PID of the container through lxc info, then iterate through /proc to get all the child processes for that container and for those, match them with the PID you’re looking for based on their status file. But this is going to be very inefficient and quite racy.

That PID 7749 is on the host machine. I dont need to know which PIDs the processes have inside container, cause as you said, they are irrelevant. I want to monitor them from outside. But I was able only to extract the PID of the “lxc” process and not the actual process started inside by “lxc exec”.

For example, when I start processes from my automatization tool without lxc virtualization I just interate the child processes until I get the final process, because the first process PID is always PID of the shell interpreter like sh or bash. But I am struggling to apply this when my auto deploy tool is trying to execute processes inside the lxc container.

Right because lxc exec just talks to the LXD daemon over a REST API which then talks to the LXC monitor process over a unix socket which then spawns the process you care about.

You can run a script through lxc exec which would effectively do:

whatever &
echo $!

To get you a PID, but that will be a PID inside the container so not of much use to you and the PID of the lxc process is similarly of little use.

So you’re back to what I was saying, if you care about the host PID, you need to iterate through the container processes to locate the one you want.

And how can I get list of processes from the host machine that are running inside a certain container please ?

In your case, I guess you could get the PID of the container through lxc info, then iterate through /proc to get all the child processes for that container and for those, match them with the PID you’re looking for based on their status file. But this is going to be very inefficient and quite racy.

I only need to get this value once the process starts. And I have noticed that the PID is not too far from the PID that lxc received, its always in the range of +50 PIDs, but this requieres additional testing and I am not sure if that will be the case on all distros.

On which value you recommend to match the process ? I was thinking about /proc/PID/cmdline but then again there can be more processes having the same cmd line. Then checking the process home directory came to my mind so something like readlink /proc/PID/cwd. But then again 2 processes might have same home.

Any recommendations please ?

Thanks.

Alright I think I found solution:

First I am gonna check if process is in the correct container:
/proc/PID/cgroup

Then I am going to check the process home:
readlink /proc/PID/cwd

This will identify my process 100% correctly. I will have to still iterate a lot of processes.

Be careful, the cgroup name may have a suffix added if a conflict is detected at startup time, so you may see a -1, -2 or whatever appended.

I am creating all my containers via my my own automatization tool that is preventing 2 containers having the same name so in my case that should not be a problem.

Also all the processes are ment to be running at least 20 hours so when they start once per day I think this process search wont be that power hungry.