All of lore.kernel.org
 help / color / mirror / Atom feed
* Documentation for init
@ 2014-08-26  5:48 Shea Levy
  2014-08-26 12:34 ` Austin S Hemmelgarn
  0 siblings, 1 reply; 6+ messages in thread
From: Shea Levy @ 2014-08-26  5:48 UTC (permalink / raw)
  To: linux-kernel

Hi all,

Is there any official documentation of the init process? I'm
specifically interested in the process state at kernel handoff (argv,
envp, open fds, etc.) as well as any special properties pid 1 has
(parent of all orphans, anything else?).

Thanks,
Shea Levy

P.S. I am not subscribed to LKML, please CC me in responses

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Documentation for init
  2014-08-26  5:48 Documentation for init Shea Levy
@ 2014-08-26 12:34 ` Austin S Hemmelgarn
  2014-08-26 22:00   ` Rob Landley
  0 siblings, 1 reply; 6+ messages in thread
From: Austin S Hemmelgarn @ 2014-08-26 12:34 UTC (permalink / raw)
  To: Shea Levy, linux-kernel

On 2014-08-26 01:48, Shea Levy wrote:
> Hi all,
> 
> Is there any official documentation of the init process? I'm
> specifically interested in the process state at kernel handoff (argv,
> envp, open fds, etc.) as well as any special properties pid 1 has
> (parent of all orphans, anything else?).
> 
> Thanks,
> Shea Levy
> 
> P.S. I am not subscribed to LKML, please CC me in responses
This is following is just my understanding based on what I have seen and
read, and I may well be totally wrong on some points (if that is the
case, I would love to know about it, I'm always trying to learn more).

As far as I can tell, the argv that gets passed to the init process is
the concatenation of all arguments on the kernel command-line that the
kernel doesn't recognize or parse.  A lot of LiveCD's make use of this
to control hardware detection and module loading.  The only open file
descriptors (i believe, I may be wrong) are 0, 1, and 2, all pointing at
/dev/console.

As for special properties:
 * Parent of all orphans
 * Doesn't have a session ID until it calls setsid() (not certain about
this one)
 * Calling exit() will cause either a reboot or possibly a panic (I
think that this is dependent on the argument passed to exit())
 * Not catching a fatal signal will cause a panic (this means that
sending SIGKILL and SIGABRT to PID 1 will always cause a panic).
 * Has a PPID of 0, only other process like this is kthreadd
 * Becomes the parent of most X programs (almost all of them dissociate
very quickly from whatever started them.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Documentation for init
  2014-08-26 12:34 ` Austin S Hemmelgarn
@ 2014-08-26 22:00   ` Rob Landley
  2014-08-26 22:56     ` Rogelio Serrano
  2014-08-28 11:37     ` Austin S Hemmelgarn
  0 siblings, 2 replies; 6+ messages in thread
From: Rob Landley @ 2014-08-26 22:00 UTC (permalink / raw)
  To: Austin S Hemmelgarn; +Cc: Shea Levy, Kernel Mailing List

On Tue, Aug 26, 2014 at 7:34 AM, Austin S Hemmelgarn
<ahferroin7@gmail.com> wrote:
> On 2014-08-26 01:48, Shea Levy wrote:
>> Hi all,
>>
>> Is there any official documentation of the init process? I'm
>> specifically interested in the process state at kernel handoff (argv,
>> envp, open fds, etc.) as well as any special properties pid 1 has
>> (parent of all orphans, anything else?).
>>
>> Thanks,
>> Shea Levy
>>
>> P.S. I am not subscribed to LKML, please CC me in responses
> This is following is just my understanding based on what I have seen and
> read, and I may well be totally wrong on some points (if that is the
> case, I would love to know about it, I'm always trying to learn more).

I used to maintain busybox init, and am researching to do a "lunchd"
on toybox (mdev is to udev as lunchd is to systemd, think "OSX launchd
without the insane xml file formats", only with at least one less
letter's worth of functionality), so I have to know far more about
this than is strictly recommended. :)

> As far as I can tell, the argv that gets passed to the init process is
> the concatenation of all arguments on the kernel command-line that the
> kernel doesn't recognize or parse.

For a definition of "recognize" where each KEYWORD=VALUE gets set as
an environment variable, and for the longest time there was this
horrible check where any argument with a period in it was jettisoned
with "you didn't _really_ mean to say init=/sbin/init.sh" obviously
you had some sort of attack, we'll call an ambulance immediately.

http://linux-kernel.2935.n7.nabble.com/patch-zap-broken-heuristic-in-init-main-c-td49698.html

Presumably fixed long since, but I bring it up to show that the
parsing done here is pretty crappy and assumption-filled. (Is there a
way to escape spaces in an environment variable you set? Who knows? I
couldn't find one when I looked...)

>  A lot of LiveCD's make use of this
> to control hardware detection and module loading.  The only open file
> descriptors (i believe, I may be wrong) are 0, 1, and 2, all pointing at
> /dev/console.

Specifically to the /dev/console out of initramfs. If you don't supply
an initramfs, it'll fake one for you, but if you _do_ you need a
/dev/console in there. (I have a todo item to fix the devtmpfs
auto-mount so it actually applies to initramfs/initmpfs instead of
only applying to the root= filesystem.)

Note that /dev/console is broken, and does not provide a controlling
tty. I have no idea why this is the case, but it's been that way
forever. The dance you have to do to get a shell prompt that actually
responds to ctrl-c and ctrl-z is:

http://landley.net/hg/toybox/file/tip/toys/other/oneit.c

> As for special properties:
>  * Parent of all orphans

Because I complained about this in early 2.4 and Andrew Morton added
reparent_to_init. :)

Now that we have containers, the container init process

>  * Doesn't have a session ID until it calls setsid() (not certain about
> this one)

News to me.

>  * Calling exit() will cause either a reboot or possibly a panic (I
> think that this is dependent on the argument passed to exit())

No, it's a panic. You can set "panic=1" on the kernel command line to
convert all panics into a reboot after a 1 second delay.

There's a mostly complete list of kernel command line options at:

https://www.kernel.org/doc/Documentation/kernel-parameters.txt

(And there's some syntax for passing arguments to statically linked
modules that I never remember. Might be involved with that dot
nonsense mentioned above.)

>  * Not catching a fatal signal will cause a panic (this means that
> sending SIGKILL and SIGABRT to PID 1 will always cause a panic).

No, the kernel starts with SIG_IGNORE on all signals. If you supply a
handler, your handler gets called. If you don't supply a handler, the
signal is ignored.

>  * Has a PPID of 0, only other process like this is kthreadd

Or the init task within any container (I.E. the first process in any
new PID context. "man 2 clone" and then look for CLONE_NEWNS.)

>  * Becomes the parent of most X programs (almost all of them dissociate
> very quickly from whatever started them.

That's another variant of "reparent to init", above.

Note that if the SIGCHLD handler is set to SIG_IGNORE then the zombie
trying to deliver a signal is allowed to finish exiting with its
status discarded. So reparenting to init is just one way to prevent
zombies from accumulating.

Rob

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Documentation for init
  2014-08-26 22:00   ` Rob Landley
@ 2014-08-26 22:56     ` Rogelio Serrano
  2014-08-28 11:37     ` Austin S Hemmelgarn
  1 sibling, 0 replies; 6+ messages in thread
From: Rogelio Serrano @ 2014-08-26 22:56 UTC (permalink / raw)
  To: Rob Landley; +Cc: Austin S Hemmelgarn, Shea Levy, Kernel Mailing List

On Tue, Aug 26, 2014 at 11:00 PM, Rob Landley <rob@landley.net> wrote:
<snipped>
> I used to maintain busybox init, and am researching to do a "lunchd"
> on toybox (mdev is to udev as lunchd is to systemd, think "OSX launchd
> without the insane xml file formats", only with at least one less
> letter's worth of functionality), so I have to know far more about
> this than is strictly recommended. :)

Hi Rob,

Im in the middle of implementing one. its at
www.github.com/r0j3r/serviceman. im thinking of changing
the name to cathurdr but i digress...

is it similar to what you have in mind?

<snipped>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Documentation for init
  2014-08-26 22:00   ` Rob Landley
  2014-08-26 22:56     ` Rogelio Serrano
@ 2014-08-28 11:37     ` Austin S Hemmelgarn
  2014-08-28 18:25       ` Rob Landley
  1 sibling, 1 reply; 6+ messages in thread
From: Austin S Hemmelgarn @ 2014-08-28 11:37 UTC (permalink / raw)
  To: Rob Landley; +Cc: Shea Levy, Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 3163 bytes --]

On 2014-08-26 18:00, Rob Landley wrote:
> On Tue, Aug 26, 2014 at 7:34 AM, Austin S Hemmelgarn
> <ahferroin7@gmail.com> wrote:
>>  A lot of LiveCD's make use of this
>> to control hardware detection and module loading.  The only open file
>> descriptors (i believe, I may be wrong) are 0, 1, and 2, all pointing at
>> /dev/console.
> 
> Specifically to the /dev/console out of initramfs. If you don't supply
> an initramfs, it'll fake one for you, but if you _do_ you need a
> /dev/console in there. (I have a todo item to fix the devtmpfs
> auto-mount so it actually applies to initramfs/initmpfs instead of
> only applying to the root= filesystem.)
> 
> Note that /dev/console is broken, and does not provide a controlling
> tty. I have no idea why this is the case, but it's been that way
> forever. The dance you have to do to get a shell prompt that actually
> responds to ctrl-c and ctrl-z is:
> 
> http://landley.net/hg/toybox/file/tip/toys/other/oneit.c
> 
>> As for special properties:
>>  * Parent of all orphans
> 
> Because I complained about this in early 2.4 and Andrew Morton added
> reparent_to_init. :)
> 
> Now that we have containers, the container init process
> 
>>  * Doesn't have a session ID until it calls setsid() (not certain about
>> this one)
> 
> News to me.
> 
I think now (after reading the rest of your e-mail) that I am wrong
about this.  I assumed that this was the case because I had heard
something about needing to call setsid() to get a shell to behave
properly when started as init.
>>  * Calling exit() will cause either a reboot or possibly a panic (I
>> think that this is dependent on the argument passed to exit())
> 
> No, it's a panic. You can set "panic=1" on the kernel command line to
> convert all panics into a reboot after a 1 second delay.
> 
Yeah, I usually use panic=-1 when I'm not doing debugging, so I can't
always tell the difference.
> There's a mostly complete list of kernel command line options at:
> 
> https://www.kernel.org/doc/Documentation/kernel-parameters.txt
> 
> (And there's some syntax for passing arguments to statically linked
> modules that I never remember. Might be involved with that dot
> nonsense mentioned above.)
> 
Yeah, the dot thing is a result of using that for statically linked
modules (ie, to pass the argument bar to statically linked module foo,
you specify foo.bar on the kernel commandline).  There are still some
edge-cases here where things that should work don't, I keep meaning to
look into this code further, but never have had the time.
>>  * Not catching a fatal signal will cause a panic (this means that
>> sending SIGKILL and SIGABRT to PID 1 will always cause a panic).
> 
> No, the kernel starts with SIG_IGNORE on all signals. If you supply a
> handler, your handler gets called. If you don't supply a handler, the
> signal is ignored.
I actually hadn't realized this, are you sure that it does that for all
signals?  If that is the case, then there must be some special handling
in the kernel for if init does something to get a SIGSEGV or SIGFPE that
it doesn't set a handler for.


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 2455 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Documentation for init
  2014-08-28 11:37     ` Austin S Hemmelgarn
@ 2014-08-28 18:25       ` Rob Landley
  0 siblings, 0 replies; 6+ messages in thread
From: Rob Landley @ 2014-08-28 18:25 UTC (permalink / raw)
  To: Austin S Hemmelgarn; +Cc: Shea Levy, Kernel Mailing List

On Thu, Aug 28, 2014 at 6:37 AM, Austin S Hemmelgarn
<ahferroin7@gmail.com> wrote:
> On 2014-08-26 18:00, Rob Landley wrote:
>>>  * Doesn't have a session ID until it calls setsid() (not certain about
>>> this one)
>>
>> News to me.
>>
> I think now (after reading the rest of your e-mail) that I am wrong
> about this.  I assumed that this was the case because I had heard
> something about needing to call setsid() to get a shell to behave
> properly when started as init.

I haven't _tested_ it, just saying I was unaware of this being unique. :)

(Don't mistake me for an expert, just somebody who's been through the
code a few times with machette and flaming torch, to make things like
oneit and busybox init and initmpfs work. I'm just very experienced at
being ignorant.)

>>>  * Calling exit() will cause either a reboot or possibly a panic (I
>>> think that this is dependent on the argument passed to exit())
>>
>> No, it's a panic. You can set "panic=1" on the kernel command line to
>> convert all panics into a reboot after a 1 second delay.
>>
> Yeah, I usually use panic=-1 when I'm not doing debugging, so I can't
> always tell the difference.
>> There's a mostly complete list of kernel command line options at:
>>
>> https://www.kernel.org/doc/Documentation/kernel-parameters.txt
>>
>> (And there's some syntax for passing arguments to statically linked
>> modules that I never remember. Might be involved with that dot
>> nonsense mentioned above.)
>>
> Yeah, the dot thing is a result of using that for statically linked
> modules (ie, to pass the argument bar to statically linked module foo,
> you specify foo.bar on the kernel commandline).  There are still some
> edge-cases here where things that should work don't, I keep meaning to
> look into this code further, but never have had the time.

I looked into it years ago, figured out how to fix it, submitted a
patch upstream, the patch got ignored, I maintained the patch locally
and moved on with my life. (That happens a lot.)

>>>  * Not catching a fatal signal will cause a panic (this means that
>>> sending SIGKILL and SIGABRT to PID 1 will always cause a panic).
>>
>> No, the kernel starts with SIG_IGNORE on all signals. If you supply a
>> handler, your handler gets called. If you don't supply a handler, the
>> signal is ignored.
> I actually hadn't realized this, are you sure that it does that for all
> signals?  If that is the case, then there must be some special handling
> in the kernel for if init does something to get a SIGSEGV or SIGFPE that
> it doesn't set a handler for.

Hmmm, I wandered across kernel code that implemented this a year or
two back, where was that...

Ah: kernel/signal.c function unhandled_signal(). First thing it does
is check is_global_init(tsk) and if so returns 1. Except... this only
seems to be used to print debug messages from architecture code? Odd.
Let's see...

Back in kernel/signal.c there's get_signal() with a comment "Global
init gets no signals it doesn't want." (Which oddly seems to have
become detached from any code that would actually _implement_ such a
thing...?) But the comment goes on to say that a nonblockable signal
that could only have been generated inside the kernel (illegal memory
access and such) gets passed through. And that _is_ the next test
after the comment. How the rest of them got ignored isn't specified
here, and I've learned not to trust comments in this codebase....

(Sigh... Not seeing it in init_task.h... init/main.c function
rest_init() creates PID 1 and starts it running kernel_init() and
_that_ calls kernel_init_freeable() to do the dirty work, and _that_
calls do_basic_setup() which calls a bunch of functions, none of which
are obviously this part of process state setup but it could be a side
effect of any of them....)

And that's about all the time I have for this right now. How the rest
of them are ignored is not obvious from the code (this is the 3.x
linux kernel, _nothing_ is obvious from the code), but easy to
experimentally determine from userspace. QEMU makes this sort of thing
a lot easier...

If you want to track it down in the kernel code yourself, I'd
recommend checking out something like the 2.2 kernel back before the
codebase went from merely crazy to the modern levels of outright
psychotic, track it down in there, and then bisect your way forward to
find each commit that screwed it up.

(I have a git repository that goes from 0.0.1 to 3.0 at
http://landley.net/kdocs/local/linux-fullhist.tar.bz2 , if you extract
that, "git checkout -f" to get the files (the tarball is just the .git
directory), and then "git pull", then you have a repo you can actually
do proper historical research in. I really need to go back and label
the early releases, but you can "git log | tail -n 1000 | less" to
find the 0.01 commit, and then bisect and look at the date...)

Rob

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-08-28 18:25 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-26  5:48 Documentation for init Shea Levy
2014-08-26 12:34 ` Austin S Hemmelgarn
2014-08-26 22:00   ` Rob Landley
2014-08-26 22:56     ` Rogelio Serrano
2014-08-28 11:37     ` Austin S Hemmelgarn
2014-08-28 18:25       ` Rob Landley

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.