[Q] Is the proc_listallpids like the proc_pidpath a Voldemort API? Everyone can see it, but you are not allowed to discuss it, and to get more info about it, you need to contact DTS.
To quote the header:
/*
* This header file contains private interfaces to obtain process information.
* These interfaces are subject to change in future releases.
*/
That warning is there because those functions are one of the core channel the kernel uses to export information to user space. If we decide that there is an issue with them or we need to add/change something, we've reserved the right to immediately make that change without any warning or notice. That's different from public API, where we expect the functions’ behavior to be stable between system versions and where we try to notify developers if/when something changes. We may not always succeed in those goals, but with the functions in libproc, we're saying that we're not even going to try.
That's also why DTS generally doesn't answer support these APIs. We can't really recommend you use an API whose behavior could change at any time.
Or is it possible to know the right way to use this API and its results?
Well, the best guide is probably our own code with "top" being the most straightforward example.
Finally, a note here:
Numerous projects are just skipping pid = 0, but are using the pids after 0 as if they were valid. From what I'm seeing, these are not valid pids, and the correct way to handle the array of pids is to stop at pid 0 (or 1 if you want to skip the "kernel").
No, that's not what's going on. Both of those pids will always be returned by proc_listallpids because they're "special" within the system. More specifically:
-
pid 0 -> The kernel. Strictly speaking, this isn't a "normal" pid, as the kernel isn't a normal process (or really a “process” at all). It primarily exists because it lets the kernel export information about “itself” using the same channels it uses to export information about other processes.
-
pid 1 -> This is launchd, which will always exist and will always be pid 1, because launchd is special.
Expanding on what makes launchd "special”, there's an inherent contradiction in UNIX's process management APIs, which is that there isn't any API to "create" new processes and all processes have a "parent". Processes are created by duplicating their parent ("fork") and then (optionally) replacing that process’s executable content with "something else" ("exec"). Of course, that creates a bit of a chicken and the egg problem, namely how do you create a process if there isn't any parent (and, no, the kernel isn't a process you can actually "fork").
The answer to that question is what makes launchd special, as the kernel essentially creates launchd "by hand" as part of its start-up processes. That is, it does all of the work of setting up launchd to run "by hand", then tells the scheduler "start running this thread" as part of a dedicated step in the boot process. Launchd then uses its own configuration data to get all of the rest of the system running.
Earlier I said that pid 1 will always be present. That's because launchd is the top-level parent of ALL processes on the system, which means killing launchd will destroy ALL other processes on the system. In other words, pid 1 will always be present because if it's not present, there isn't any process that could call proc_listallpids.
Finally, as an aside, I'll note that launchd's role in the system is so critical that if it's killed (or crashes), the kernel doesn't actually make any attempt to relaunch it. What the kernel actually does is power cycle itself, repeating the entire boot sequence which eventually creates launchd.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware