rc scripts aren't running on xM board under Ubuntu Maverick

Hi.

I've added an rc script to /etc/init.d/ and /etc/rcX.d

root@omap:~# ls -al /etc/init.d/*foo* /etc/rc2.d/*foo*
-rwxr-xr-x 1 root root 176 2011-01-12 18:33 /etc/init.d/foo
lrwxrwxrwx 1 root root 19 2011-01-12 18:27 /etc/rc2.d/S99foo -> ../
init.d/foo

but when the board boots, this script is apparently not called. I
note the system defaults into runlevel 2:

root@omap:~# runlevel
N 2

Can someone please describe how to the init system works under Ubuntu
Maverick.

Thanks.

I have a script in rcX.d too. It works fine. How do know your script was not called? Don't forget that you need to put the full path in your startup script.

-Eric

Thanks for the reply.

I've never seen anything like the failure I've described.

Yes, you are right: the script is actually being called.

I've inserted into the script some probes, such as "date >> /opt/
d.txt" which work (i.e., date produces output in /opt/d.txt). But,
e.g., I can't run a utility such as /usr/sbin/ntpdate to set the
clock, yet I can run ntpdate just fine from the command line. Nor
when I insert "echo starting..." in the script do I see this output on
the console.

I'm totally stumped. The failure mode must be so blindingly obvious
that I can't see it, or this is something peculiar to embedded linux
(to which I am fairly new) that I'm not accustomed to seeing.

I have three hours in this problem thus far. I'm well into the phase
of questioning mine own eyes.

did you capture stderr and stdout?
did you examine the exit code from ntpdate?
try adding any verbose and debug flags to ntpdate arguments
long shot: run ldd ntpdate in the script; all the libs found?

something like this (untested):

exec > /opt/stdout.log
exec 2> /opt/stderr.log
ldd /usr/sbin/ntpdate
ntpdate <args...>
echo ntpdate exit code was $?

Thanks for the reply.

I thought I would see signs of trouble on the console, but I was
wrong. Your suggestion of capturing stderr to a file provides new
information.

My code emits to stderr this error condition:

setsockopt() failed: No such device

in response to this application code:

    /* set reuse port to on to allow multiple binds per host */
    if ((setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag_on,
sizeof(flag_on))) < 0) {
        perror("setsockopt() failed");
        exit(1);
    }

It looks like the network is not available when this code runs, which
I guess surprises me. Here is the set of scripts in /etc/rc2.d/:

root@omap:~# ls /etc/rc2.d/
README S75sudo S99ondemand S99rc.local S99foo

I don't see any networking script. Nor do I see any networking script
anywhere but in /etc/rc6.d, which I think is the reboot runlevel.

ID | Name | Description |

  • | - | - |
    1 | Single-User Mode | Does not configure network interfaces, start daemons, or allow non-root logins.[3] |
    2 | Multi-User Mode | Does not configure network interfaces or start daemons.[4] |
    3 | Multi-User Mode with Networking | Starts the system normally.[5] |
    4 | Not used/User-definable | For special purposes. |
    5 | X11 | As runlevel 3 + display manager. |

You are using run-level “2”. Please check the table above. I have my version of rc.local reading files from NFS directories on run-level “3”. My rc.local works fine. May be you should try something really simple such as “echo hello > /home/root/hello.txt”.

Thanks.

echoing to a file when invoked from the script works. I posted that
in Jan 13, 7:43am message. And for the beagleboard Ubuntu Maverick
image, runlevels 2 and 3 have exactly the same scripts. So changing
from 2 to 3 does not promise doing any good. But I tried it anyway.
And it did not improve the situation with respect to the function of
my daemon.

So I went off and read the man page for the Ubuntu /sbin/init daemon,
which was quite a revelation for someone expecting the last word to be
the scripts in /etc/rcX.d/. For now, I'm backing off the use of
scripts in /etc/rX.d, in favor of using Ubuntu start daemon .conf
files in /etc/init. I know the rc script method should work, but I'm
so deep into looking without seeing that I'm taking as few chances as
possible with with simulated runlevels. And runlevels are simulated
in Ubuntu Maverick. See this nice write up: http://www.linux.com/archive/feature/125977

So here is the .conf file I constructed, which is a clone of the .conf
file sshd uses (and sshd works). I also note that my mcagent daemon
does in fact fork, so "expect fork" is valid in the config.

start on filesystem
stop on runlevel [!2345]

expect fork
respawn
respawn limit 10 5
umask 022

pre-start script
    test -x /opt/local/bin/mcagent || { stop; exit 0; }
    ifconfig -a > /opt/if.log
end script

exec /opt/local/bin/mcagent 225.0.0.37 12345 1>/var/log/mcagent.log
2>&1
# --- cut here

The daemon fails to start successfully, and logs this to stderr, which
I capture in the mcagent.log:

setsockopt() failed: No such device

The code that generated this error looks like

    /* construct an IGMP join request structure */
    mc_req.imr_multiaddr.s_addr = inet_addr(mc_addr_str);
    mc_req.imr_interface.s_addr = htonl(INADDR_ANY);

    /* send an ADD MEMBERSHIP message via setsockopt */
    if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)
&mc_req, sizeof(mc_req))) < 0) {
        perror("setsockopt() failed");
        exit(1);
    }

I capture the output of ifconfig -a as a pre-start action. That
output looks like

lo Link encap:Local Loopback
          inet addr:127.0.0.1 Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING MTU:16436 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

usb0 Link encap:Ethernet HWaddr f2:a2:36:7c:49:6a
          BROADCAST MULTICAST MTU:1500 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

usb1 Link encap:Ethernet HWaddr 12:82:26:5e:aa:ae
          inet6 addr: fe80::1082:26ff:fe5e:aaae/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST MTU:1492 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B) TX bytes:534 (534.0 B)

However, when I login to the board, and type ifconfig -a I get this,
noting that usb1 (the interface that ultimately gets an address from
the dhcp server) has no IPv4 address when the .conf script runs, but
has one by the time I login.

lo Link encap:Local Loopback
          inet addr:127.0.0.1 Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING MTU:16436 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

usb0 Link encap:Ethernet HWaddr f2:a2:36:7c:49:6a
          BROADCAST MULTICAST MTU:1500 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

usb1 Link encap:Ethernet HWaddr 12:82:26:5e:aa:ae
          inet addr:192.168.0.139 Bcast:192.168.0.255 Mask:
255.255.255.0
          inet6 addr: fe80::1082:26ff:fe5e:aaae/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST MTU:1492 Metric:1
          RX packets:96 errors:0 dropped:0 overruns:0 frame:0
          TX packets:20 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:12518 (12.5 KB) TX bytes:3032 (3.0 KB)

So it sounds like I need to use in the .conf file a different start-
event than "filesystem" (a weird choice for openssh-server to have
used, which I inherited in the .conf file clone. But sshd works, so
who am I to question). I searched for standard event-names associated
with the new Ubuntu init daemon, but found none. Logically, I want
some event named "network-is-all-the-way-up".

BTW, usb0 does not seem to be a usable physical interface. What is it
actually doing there??

Halle-fricking-lujah.

This works as an adequate event in the .conf file:

start on net-device-up

which I gleaned from studying mountall-net.conf.

Wow. That was quite the hellish odyssey.

With the barebones scripts that are installed by default in /etc/
rc2.d, I have no idea what the right way is to prepare the network for
use in an /etc/rc2.d script. If anyone has any ideas, I'm all ears.
But at least I have a system that's usable at boot time.

Thanks to everyone who replied.

Actually, this "works" even better for the start condition:

start on filesystem and net-device-up IFACE=usb1 # usb1 is the
interface backed by a usable physical device

In retrospect, I'm concerned about embedding a particular interface
name in the start up event spec.

It would be better to have 'initctl' emit an event when *all* the
interfaces in /etc/network/interfaces have been configured. But I
could not figure out which script in /etc/init/*.conf drives this mass
interface provisioning.

Does someone here know?