0

I'm using linux kernel 4.1.8 32bit.

My init process (using /etc/inittab and /etc/rd5.d Scripts) run the "Hello" process during boot time:

int main(){
     int val;
     printf("Hello\n");
     scanf("%d",val);
     return 0;
}

(with all the necessary includes to work with linux,signals,i/o...)

My problem is both practical and conceptual:

practical:

  1. This process ignores the ctrl z/x/c signals only when it executes via the init scripts and before the login process. If I run it after I login into shell - all works fine. Additionally, I added some code to it to run the: "ps -eo pid,lstart,cmd" command and I saw that during its execution at init time there is no shell process exists.

Conceptual:

  1. At first I thought the shell is the one responsible for sending signals to the process. From reading other posts I understood that's incorrect and the one responsible is the terminal console. The thing is that terminal console is not a process. Its just some kind of CLI "GUI". By that I mean that a shell without a terminal can run and executes scripts without the user awareness and a terminal without a shell can do nothing.. maybe only shows a prompt or something? but in order for our input to impact in some way - command or an interrupt we need a shell that will read and interpret our input. isn't that right?

  2. What am I missing here? and if the reason for my process ignoring these signals is not related to the fact that it executes before the login process and before my interactive shell opens , then what it could be? (again, if i run it after my shell opens and not part of the init scripts then everything works fine)

  3. Is there any literature explaining this topic?

edit:

/etc/inittab:

# /etc/inittab: init(8) configuration.
# $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $
# The default runlevel.
id:5:initdefault:
# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS
# What to do in single-user mode.
~~:S:wait:/sbin/sulogin
# /etc/init.d executes the S and K scripts upon change
# of runlevel.
#
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# Normally not reached, but fallthrough in case of emergency.
z6:6:respawn:/sbin/sulogin
S0:12345:respawn:/sbin/getty -L 115200 ttyS0

script inside /etc/init.d/rcS folder:

# source function library
. /etc/init.d/functions
        echo "Starting gripen applications"
    cd /appsys/bin
    /bin/sh -c ./testApp
    echo "done."
  • Can you say which distribution you are using? I'd like to see if I can reproduce this but don't know what is acting as init here. It feels like the stein may not be your terminal but I can't tell without testing. – Philip Couling Nov 2 at 20:56
  • Im using the yocto env , powerpc p4080ds SoC , centos dis – hutcruchi Nov 3 at 6:32
  • I've not had chance to try this yet. As you are running this as a service I wonder if the service manager (systemd?) is running without stdin attached. You might want to write another test that checks what stdin is, see this answer stackoverflow.com/a/13544447/453851 if this comes up blank then it is a pipe and NOT attached to the terminal. – Philip Couling Nov 4 at 7:08
0

I don't know your exact situation from the information you post, so let me answer some of your conceptual confusions first.

command or an interrupt we need a shell that will read and interpret our input. isn't that right?

No. A shell is not necessary needed for passing a keyboard-generated signal (like Ctrl-C). To receiving the keyboard-generated signal -

  • your process need to be a foreground process;

  • your process need to have a controlling terminal.

A running foreground process will block its terminal and grab current input from the terminal.

Generally a login process ls launched by a getty command, processes ran by your logged-in shell take the terminal specified by getty as their controlling terminal. Before login, you early init processes take the kernel console terminal as their controlling terminal by default.

You can learn more about this in APUE 3rd edition Chapter9.

Back to your situation, normally, programs in /etc/rc?.d are able to receive keyboard-generated signals from kernel console terminal. I suggest you to post your init script for us to see how your program started.

Hope this helps.

  • this is the /etc/inittab file (how can I write it in code format?): # The default runlevel. id:5:initdefault: si::sysinit:/etc/init.d/rcS # What to do in single-user mode. ~~:S:wait:/sbin/sulogin l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 # Normally not reached, but fallthrough in case of emergency. z6:6:respawn:/sbin/sulogin S0:12345:respawn:/sbin/getty -L 115200 ttyS0 – hutcruchi Nov 4 at 6:22
  • my goal is that the inittab will run a process (or a script which will run the process) , but I need that process to run with "low" priviliges and that will be able to recieve ctrl z/x/c signals – hutcruchi Nov 4 at 6:25
  • Not the inittab, I want to see the exact script you start your c program. You mean you need that process block the bootup process until you enter something or make a signal on the keyboard? You don't want to see the "login:" prompt until your process exit, right? – ZhouZhuo Nov 4 at 6:31
  • Would you mind pasting the script in your question? It's not well-formatted in the comment. – ZhouZhuo Nov 4 at 6:34
  • yes. I don't want to see the prompt until I exit the process. I attached the inittab and the script – hutcruchi Nov 4 at 11:07
-1

I just did a test, booting with:

vmlinuz root=/dev/sdaX init=/bin/bash (no initrd, no init)

Result is: "bash: no job control" in the last boot message lines. After "Enter" you get a normal looking prompt. I did ls -R, and then I could not stop it with control-C, nor switch the terminal. Ctrl-alt-del worked though. So I guess you can say I had a single console, but no virtual terminal.

This had also worked without /etc/passwd, just as an anonymous uid "0". Then I added the agetty lines in inittab (see below, different variations). This looked quite good. But "pam" was not happy, so I made a user "root". And for D-Bus and sockets I needed systemd anyway, just to be able to start firefox.

Here is my inittab, with comments and experimental entries:

# etc/inittab for sysvinit 2.88 (2010)
#
# Fields:
# id : runlevels : action : process
#
# Runlevels: 
# "S" does not require inittab -> sulogin on console 
# 0-6 traditional (0=halt, 1=single, 6=reboot...) 
# 0-9 Runlevels
# ABC Ondemand


# Simple "old Linux" inittab from manpage:
# one (default) runlevel, 4 gettys, one bootwait rc-script
id:2:initdefault:

# sysinit/boot-scripts, they run first
#si::sysinit:/etc/sysinit.init 

bw::bootwait:/etc/boot.init
#b::boot:/etc/rc

# gettys for runlevels
r21:2:respawn:/sbin/agetty -J -l /bin/bash -o "-l" tty1
r22:2:respawn:/sbin/agetty -J tty2
r23:2:respawn:/sbin/agetty -n -l /bin/bash tty3
r24:2:respawn:/sbin/agetty -n -l /bin/bash tty4

and then some more tests; after adding another set of ttys on another runlevel, I could easily change RLs with init X.

The shutdown under sysvinit I still don't understand.

With init A I could run that /etc/d1 script (but what for exactly?)

I can confirm that you can have a runlevel 9 which opens a tty13

r31:3:respawn:/sbin/agetty -J -l /bin/bash -o "-l" tty1
r32:3:respawn:/sbin/agetty -J tty2

re:6:once:/sbin/reboot 
ha:0:once:/sbin/halt -p 

d1:A:once:/etc/d1 
C:C:once:/sbin/halt -p 

91:9:respawn:/sbin/agetty -J tty13
92:9:respawn:/sbin/agetty -J tty1
93:9:respawn:/sbin/agetty -J tty12

This is how I see the "old" sysvinit - simple and fundamental. No S and K scripts with hundreds of greps to see if there is some process to stop or not. Systemd only turned a mess into a big efficient mess.


My init process.../etc/inittab

This means you have lines like this:

r22:2:respawn:/sbin/agetty -J tty2

...but instead of agetty you have your "hello"?

This has to create some "misbehaviour", because this /etc/inttab (with non-systemd=sysvinit /sbin/init) is where shell, terminal and login are set up. The three lines above show different variations - some might not really work. With agetty ("Get me a TTY") you give a tty-number, and a shell and a login program (defaul login).

wikipedia, "getty":

Personal computers running Unix-like operating systems, even if they do not provide any remote login services, may still use getty as a means of logging in on a local virtual console.

"Logging in" includes, or rather means, that you reach your shell, and that your VC is working.

"User Interface" (GUI/CLI)

The kernel does not offer one, but it has "rules" on how to hand over to user space i.e. to the first process. In Documentation/admin-guide/init.rst it says:

And before tackling scripts, better first test a simple non-script binary such as /bin/sh and confirm its successful execution.

This shows that you need a strategy - step by step.

The "dreaded no-init" message / "no working init found" panic is in init/main.c

        /*
         * We try each of these until one succeeds.
         *
         * The Bourne shell can be used instead of init if we are
         * trying to recover a really broken machine.
         */
        if (execute_command) {
                ret = run_init_process(execute_command);
                if (!ret)
                        return 0;
                panic("Requested init %s failed (error %d).",
                      execute_command, ret);
        }
        if (!try_to_run_init_process("/sbin/init") ||
            !try_to_run_init_process("/etc/init") ||
            !try_to_run_init_process("/bin/init") ||
            !try_to_run_init_process("/bin/sh"))
                return 0;

        panic("No working init found.  Try passing init= option to kernel. "
              "See Linux Documentation/admin-guide/init.rst for guidance.");
}

So actually the "worst" way to boot into your "hello" would be with init=/bin/hello; then it is the "naked" kernel and your program alone.

literature: when it comes to concepts, I think wikipedia is the best. You will soon find out that there are no easy definitions. Simplifications are useful, but also misleading.

  • 1
    this is not the case. inside the /etc/inittab i have the row: si::sysinit:/etc/rc.5 which says that upon init run all scripts (S and K scripts) from /etc/rc.5 folder. the last script in that folder (called S99myprogram) executes my program – hutcruchi Nov 2 at 8:06
  • O so then it is a completely different situation of course – rastafile Nov 2 at 8:28
  • do you think that because this process executes before my login and shell processes do , it can't receive or ignores the ctrl z/c/x signals? – hutcruchi Nov 2 at 18:47
  • si::sysinit:/etc/rc.5: Here i think you have to put a script, not a folder. 'sysinit' and 'boot(wait)` are run before the runlevel-scripts are started. There is no runlevel here. So you might be too early. Excuse my irony before - I just thought this kind of info would have been helpful from the start. – rastafile Nov 2 at 19:48
  • ...and while I like to experiment with sysvinit a bit, I don't care for these "runlevel" S- and K-folders. I use inittab only to start a set of ttys in a runlevel, not to have services stopped and started. Your "practical" problem, I don't really understand. But for the conceptual one I gave some ideas. You could e.g. boot with init=/bin/bash and then try your program manually. – rastafile Nov 2 at 19:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.