Question about rc.sysinit and the filesystem availability

Hello,

I have just encountered something strange regarding accessing the filesystem from rc.sysinit.

In rc.sysinit I wanted to test for the existance of a file and if there take specific action. So I put in the following code:

if test -a /home/MAD/.setPerms; then
/home/MAD/spm_upgrade_root
rm -f /home/MAD/.setPerms
fi

However, upon testing I noted that this always fails the test. That is, whether or not the file is there, it always reports as if it isn’t.

But if I instead tested for a directory using the same code:

if test -a /home/MAD; then
/home/MAD/spm_upgrade_root
rm -f /home/MAD/.setPerms
fi

This always passes successfully.

So I wrapped a waitfor() command call just in front of the test for /home/MAD/.setPerms in the initial code snippet. What I observed was that it always passes through the waitfor loop at least once when the file does exist (so it needs a 1 second delay). However if I test for /home/MAD it never passes through the waitfor loop because it always finds the directory.

My question is, why is it not able to find the .setPerms file right away while it can always find the /home/MAD directory that it resides in?

It’s not a huge issue because I’ve just added a wait for up to 3 seconds for the file but I am curious as to why I need it.

Tim

A copy of my rc.sysint:

#!/bin/sh

rc.sysinit

This script sets up your environment & starts system services

echo Executing rc.sysinit Ver 1.1

Add the system utilities to the path…

export PATH=/sbin:/usr/sbin:/bin:/usr/bin

A useful function

function waitfor {
typeset -i i=0
while test $i -lt $2 -a ! $1 -ef $1 ; do
sleep 1;
let i=i+1;
done
unset i
}

Start random, this is needed for things like OpenSSH

#random -t

make dir and allow all to use it

if ! test -d /var/dumps
then
mkdir -p /var/dumps
chmod -R 777 /var
fi

dumper -d /home/MAD/MAD/output

allow ftp to use /tmp

if ! test -d /tmp
then
mkdir /tmp
fi
chmod 777 /tmp

Start networking

Remove from here to…–>>

-------------------------------------------------

This is the setting for the ethernet chip on the MIC 3000 boards

Changed to Large tcpip stack since OS had networking problems

io-net -ptcpip -ppppmgr -dspeedo pci=0 -dspeedo pci=1 &

wait until io-net manifests itself and then start networkng manager

which uses /etc/net.cfg by default

waitfor /dev/io-net 60
netmanager
inetd &

Qnet

Enable qnet - can only be used on target systems

slay inetd
slay io-net
echo “Waiting for io-net to release sockets…”
sleep 5
io-net -ptcpip -ppppmgr -pqnet -dspeedo pci=0 -dspeedo pci=1 &
echo “Waiting for io-net to re-establish sockets…”
sleep 10
netmanager
inetd &

-----------------------------------------------------------

–>>…here if you do not require networking.

export TERM=qansi-m

Check to see if the permissions need to be set on the MADCurrent

directory. Ideally these would be set on every re-boot but in an

effort to save the life of the flash disk they will now only be

set once after S/W upgrade.

waitfor /home/MAD/.setPerms 3
if test -a /home/MAD/.setPerms; then
/home/MAD/spm_upgrade_root
rm -f /home/MAD/.setPerms
fi

Auto login as MAD to start the spm (now done from boot image instead

of here)

Don’t know what is happening but I don’t think you can use -a to test for a directory. I’m surprise it passed the test.

Mario,

The -a option works just fine when specifying a directory. If the directory does not exist it returns false and when it does it returns true. I assume it works because a directory is just a special file and the -a test is just looking for file.

I realize normally one would test for a directory with -d but in this case I was just attempting something down and dirty to figure out why the test command in general was failing in rc.sysinit.

Tim

Tim - I would use rc.local to do this work since it can just be copied between machines without having to worry about versions or other updates to rc.sysinit.

Chris I think he is using a custom version of rc.sysinit?

Tim why are you starting two io-nets, both apparently using the same network card ?

Chris, Mario,

Actually I’m inheriting this project from the people who began work on it about 3 years ago. It’s a medical device that’s about to be launched (pending final FDA approval). The actual QNX version running is 6.10 (some unreleased unsupported QNX version I was told by my QNX rep). I have begun the work to upgrade to 6.3 but it’s going to have to wait until after launch before the the O/S upgrade makes it into the field.

That said, I’d like to use rc.local too. I’m not even that happy with the rc.sysinit as it is because all the consoles are created in the boot image via a re-open command so once you exit the console it’s gone forever (as opposed to using tinit where they are auto-started again) which is quite annoying when you are debugging.

But the people who began the project were not QNX savvy and my guess is they had no idea that rc.local existed (because there isn’t one by default in 6.10) or even that you could use tinit to create consoles. The .bld file that creates our boot image (goes on a flash disk) looks to be virtually the one supplied by QNX under /boot/build. So my guess is they found that, got it working and never changed anything because it worked. The same I assume goes for rc.sysint.

When I get the project ported and working under 6.3 I will change the boot image and rc.sysint and rc.local files to be more in line with what one would expect (ie. there is nothing really custom about the rc.sysinit we use other than the few lines I added at the end to test for the file and the comment about not starting consoles in rc.sysinit).

As for the 2 io-nets, I have to confess I never really looked that closely at it before. LOL. Your right, I have ZERO idea why they start it, slay it and then re-start it (we certainly are not using QNET since we talk to a Windows GUI). Again, my guess is those lines were copied directly from someplace else into rc.sysint (perhaps from early QNX tech support they once had). We actually have 2 network cards on our board and both work but one is only used for debugging purposes and so is essentially inactive in the field. Is there any reason they need to slay io-net and re-start it (maybe there were weird errors under 6.10)?

Tim

You might want to look at the Controlling How Neutrino Starts chapter of the 6.3 Neutrino User’s Guide. It goes into great (some say excessive) detail about rc.sysinit and its friends.

I can’t remember if the device enumerators existed in 6.1 – perhaps slaying io-net was the only way to customize it.I added a section on customizing the enumerators to the User’s Guide, but not in time for it to get into the release. Here it is – I hope it helps:

If you need to set up devices or options that are specific to your
particular system configuration, create an overrides file under
/etc/system/enum. The enumerator includes this file last and adds any
definitions in it to the set that enum-devices works with. If the
overrides file has something that a previously included file also has,
the later definition wins.
For example:

  • If you want to stop a particular device from running, or change how it
    starts, create a /etc/system/enum/overrides file and add a device(…)
    entry for the device:

    device(pci, ven=1234, dev=2000)
    device(pci, ven=1234, dev=2001)
    requires( $(IONET_CMD), )
    uniq(netnum, devn-en, 0)
    mount(-Tio-net /lib/dll/devn-pcnet.so, “/dev/io-net/en$(netnum)”)

    device(pci, ven=1234, dev=2002)
    device(pci, ven=1234, dev=2003)

    The first block of this code specifies to do the following if the
    enumerator detects devices 2000 and 2001 from vendor 1234:

    1.If io-net isn’t running, start it. IONET_CMD is a macro, defined in
    /etc/system/enum/include/net, that specifies the default io-net command
    line.
    2.Set netnum to the next unique network interface device number,
    starting at 0.
    3.Mount the PCNET driver into io-net.

    The second block of code tells the enumerator to do nothing if it
    detects devices 2002 or 2003 from vendor 1234.


When you add device entries to prevent devices from being enumerated, 
make sure that there aren't any action clauses after them. Any group of 
actions clauses found after any single or set of device entries is used 
for those devices. Place these device entries at the end of your 
overrides configuration file. 

  • If you want to change the way the enumerator starts TCP/IP, you have to
    override the definition of the basic io-net command that’s defined in
    /etc/systems/enum/include/net. By default, the command is:

    io-net -ptcpip

    If you want to enable IPSec, add this code to your overrides file:

    all
    set(IONET_CMD, io-net -ptcpip ipsec)