Reihenfolge von Startupscripten

teuk

Well-Known Member
Hallo,

ich habe folgendes Problem:

Ich bin grade dabei einen AFS-Clienten mit Hilfe von arla-0.40 unter FreeBSD 5.4-RELEASE-p6 einzurichten.

Vorweg sei noch gesagt, dass ich mir dazu die arla sourcen direkt von der Stacken Seite runtergeladen habe, weil der Port ja leider immer noch broken ist. So ganz installiert habe ich es auch nicht (lediglich configure && make), da sich zumindest der Port mit Heimdal nicht vertraegt. Deshalb vorerst die etwas ungewoehnlichen Pfadnamen.

Aber nun zu meinem eigentlichen Problem. Wie oben schon erwaehnt ist arla bereits "installiert" und eingerichtet, was mir nun noch fehlt ist die Moeglichkeit alles waehrend des Bootens zu laden und zu mounten. Dazu habe ich die folgenden beiden Skripte erstellt:

/usr/local/etc/rc.d/arlad.sh:
Code:
#!/bin/sh
#
# PROVIDE: arlad
# REQUIRE: NETWORKING
# KEYWORD: FreeBSD
# BEFORE: arla_mount
#
# DO NOT CHANGE THESE DEFAULT VALUES HERE
arlad_enable="NO"

. /etc/rc.subr

name="arlad"
rcvar=`set_rcvar`

start_cmd="arlad_start_cmd"
stop_cmd="arlad_stop_cmd"

arlad_start_cmd()
{
        echo -n "Starting arla: "
        /sbin/kldload /usr/home/ianus/arla/arla-0.40/nnpfs/bsd/nnpfs.ko
        /usr/home/ianus/arla/arla-0.40/arlad/arlad -z /dev/nnpfs0
}

arlad_stop_cmd()
{
        echo -n "Stopping arla."
        /sbin/kldunload nnpfs
}


load_rc_config $name
run_rc_command "$1"

/usr/local/etc/rc.d/arla_mount.sh:
Code:
#!/bin/sh
#
# PROVIDE: arla_mount
# REQUIRE: arlad NETWORKING
# KEYWORD: FreeBSD
#
# DO NOT CHANGE THESE DEFAULT VALUES HERE
arla_mount_enable="NO"

. /etc/rc.subr

name="arla_mount"
rcvar=`set_rcvar`

start_cmd="arla_mount_start_cmd"
stop_cmd="arla_mount_stop_cmd"

required_files="/dev/nnpfs0"
required_dirs="/afs"

arla_mount_start_cmd()
{
        echo -n "mounting AFS "
        /usr/home/ianus/arla/arla-0.40/nnpfs/bsd/bin/mount_nnpfs /dev/nnpfs0 /afs
}

arla_mount_stop_cmd()
{
        echo -n "unmounting AFS."
        /usr/home/ianus/arla/arla-0.40/nnpfs/bsd/bin/umount_nnpfs /afs
}

load_rc_config $name
run_rc_command "$1"

Nach meinem bisherigen Verstaendnis von dem rc.d System sollte also das arlad.sh Skript vor dem arla_mount.sh Skript ausgefuerhrt werden. Aber grade das geschient nicht.

Code:
Local package initialization:
mounting AFS mount_nnpfs: mount: No such file or directory
Starting arla: nnpfs: cdev: 128, syscall: 339

Es soll natuerlich erst das arla-Kernelmodul geladen und arlad gestartet werden und danach gemountet werden.

Mein Frage ist nun, was ist an den beiden oebn angefuehrten Skripten feherhaft, so dass die von mir beabsichtigte Reihenfolge offensichtlich nicht beachtet wird?

Da ich noch nicht so viel erfahrung mit den rc.d System habe ist eine weitere Frage noch, ob das so alles in ordnung ist? Wenn das totaler Quatsch ist, sagt es mir, ich bin ja schliesslich auch daran interessiert, dass das am Ende gut aussieht.



teuk
 
Last edited:
teuk said:
Da ich noch nicht so viel erfahrung mit den rc.d System habe ist eine weitere Frage noch, ob das so alles in ordnung ist? Wenn das totaler Quatsch ist, sagt es mir, ich bin ja schliesslich auch daran interessiert, dass das am Ende gut aussieht.
zum eigentlichen problem kann ich nicht viel sagen. nur am rande: imho ist es unnoetig, die abhaengigkeit zwischen arla_mount und arlad zweimal anzugeben. das "# BEFORE: arla_mount" in arlad kann demnach weg, und "# REQUIRE: arlad NETWORKING" in arla_mount kann auf "# REQUIRE: arlad" verkuerzt werden. strenggenommen braucht arla_mount das NETWORKING nur indirekt, und wenn du sagst, "B braucht A" und "C braucht B", dann ist die angabe "C braucht A" redundant. dein dependency-graph sieht im prinzip grade so aus:
Code:
A: NETWORKING
B: arlad
C: arla_mount

A <- B <-> C
^----------´
wobei er so aussehen sollte:
Code:
A <- B <- C
 
Gut, klar die Redundanz kann natuerlich raus. Ich hatte das "BEFORE: arla_mount" auch nur in der Hoffnung eingefuegt, dass dann evtl. die Ausfuehrreihenfolge so ist wie ich das gern haette, dem war aber nicht so.
Nur wie du schon sagtest und wie es die Natur von Redundanz ist, bleibt das Problem bestehen. Aber dennoch danke.


teuk
 
Dann les Dir nochmals "man rc.d" durch:
[...]
The scripts within each directory are executed in lexicographical
order. If a specific order is required, numbers may be used as a
prefix to the existing filenames, so for example 100.foo would be
executed before 200.bar; without the numeric prefixes the opposite
would be true.
[...]
 
Naja das Zitat bezieht sich doch aber auf das alte System, oder?

The following key points apply to old-style scripts in
/usr/local/etc/rc.d/:

[...]

The scripts within each directory are executed in lexicographical
order. If a specific order is required, numbers may be used as a
prefix to the existing filenames, so for example 100.foo would be
executed before 200.bar; without the numeric prefixes the opposite
would be true.

Oder sollte ich mir besser ne Merkbefreiung fuer heute holen?


teuk
 
Steht denn "arlad_enable="YES" in der /etc/rc.conf vor "arla_mount_enable="YES"?
 
So wie ich das verstehe steht da "old-style" weil sich die folgenden Punkte auf die Vorgehensweise beziehen wenn rcorder (wovon ja davor die Rede ist) nicht im Spiel ist. Oldstyle, weil rcorder halt noch nicht so lange an Bord ist. ;)

Gruß
 
@asg
ja, arlad_enable="YES" steht vor arla_mount_enable="YES" in der /etc/rc.conf, aber muesste das mit rcorder nicht egal sein?


teuk
 
Ich hatte zwar vorhin gedacht, das ich das Problem geloest haette, aber ich habe mich zu frueh gefreut.
Ich hatte ueberall "arla_mount" zu "arlamount" geaendert, also auch im Datei nahmen, was dazu gefuert hat das arlad.sh lexikographisch vor arlamount.sh auftaucht. Und anscheinend werden die Skripte auch in der Reihenfolge ausgefuert. Wenn das aber so ist wozu gibt es dann rcorder(8) ueberhaupt? Irgendwo muss ich da noch einen Feher haben oder muss man rcorder irgendwo explizit aktivieren?

Ein rcorder /etc/rc.d/* /usr/local/etc/rc.d/* liefert uebrigens die richtige Reihenfolge, also
erst /usr/local/etc/rc.d/arlad.sh und danach /usr/local/etc/rc.d/arla_mount.sh.


Edit:
Ich habe es eben noch mal mit NetBSD probiert und da funktioniert es wie es REQUIRE etc. vorschreiben unabhaengig vom Dateinamen. Aber unter FreeBSD bislang nicht.

teuk
 
Last edited:
hi,

danke fuer die Links juedan. Der erste davon ist ganz interessant: "/usr/local may not be mounted when rcorder is first run". Daran scheint es wohl in meinem Fall zu liegen, denn wenn ich die Skripte als arlad und aral_mount nach /etc/rc.d kopiere, dann geht es wunderbar. Und das mein manuelles rcorder nach dem Booten funktioniert hat wuerde das auch erklaeren. Bei meinem NetBSD Versuch oben lagen die Skripte uebrigens auch in /etc/rc.d.
Naja, in /etc/rc.d will ich die Skripte bei FreeBSD aber nicht haben. Deswegen werden sie wohl vorerst als arlad.sh und arlamount.sh in /usr/local/etc/rc.d bleiben.

Nebenbei bemerkt scheint es arlad nicht besonders zu moegen wenn man nnpfs.ko entlaed ohne arlad vorher zu beenden. Nur falls jemand die obigen Skripte in irgendeiner Weise verwenden sollte und nicht grade einen Fetisch fuer panics hat.



teuk
 
Last edited:
Hallo teuk,

freut mich, wenn helfen konnte.
Du verwendest AFS? Gibt es da mittlerweile auch einen Daemon/Server-Prozess für FreeBSD?

Grüße

Jürgen
 
hi,

Wie aus den obigen scripten hervorgeht, verwende ich arla nur als AFS-Client. Da der arla Port fuer FreeBSD immer noch broken ist, habe ich arla auch nur so halb installiert (s.o.).
Das laueft auch soweit alles ganz gut. Ich habe eben mal die test suite fuer den Client laufen lassen und bis auf ein paar Tests laueft die durch, bei den uebrigen muss ich noch mal sehen woran das liegt.
Das arla packet von Stacken[0] beinhaltet auch einen AFS-Server (milko), aber der gilt laut README noch als experimentell.
AFS selber nutze ich sonst auch nur in Rolle als Client (bzw. plane es zu nutzen), weil es im Vergleich zu scp doch etwas angenehmer ist und das meine beiden alternativen sind.
Eine weiterentwicklung von AFS ist auch den Ports: /usr/ports/net/coda*. Aber das habe ich mir noch nicht weiter angesehen.




teuk


[0] http://www.stacken.kth.se/projekt/arla/
 
Last edited:
Ich meine nun herausgefunden zu haben, was fuer die Ausfuehrung der Skripte in alphabetischer statt der von rcorder vorgegebenen Reihenfolge verantwortlich ist:

Per /etc/rc werden alle Skripte in /etc/rc.d/* in rcorder-Reihenfolge ausgefuert:
Code:
files=`rcorder ${skip} /etc/rc.d/* 2>/dev/null`
Dabei wird auch /etc/rc.d/localpkg ausgefuert welches mit
Code:
for dir in ${local_startup}; do
    if [ -d "${dir}" ]; then
        for script in ${dir}/*.sh; do
            slist="${slist}${script_name_sep}${script}"
        done
    fi
done
nun dafuer sorgt dass alles, was in der rc.conf in local_startup angegeben wurde (per default sind das: /usr/local/etc/rc.d und /usr/X11R6/etc/rc.d) in alphabetischer Reihenfolge ausgefuerht wird.

Nun habe ich aber noch nicht genug Erfahrung, um zu entscheiden wie man nun sinnvoll weiter vorgeht. Ich werde demnaechst mal folgendes probieren:

Da /etc/rc.d/localpkg im Rahmen von /etc/rc aufgerufen wird und dabei selbst nichts weiter mountet kann man wohl davon ausgehen, dass /usr zu diesem Zeitpunkt bereits gemountet ist. Danach muss man in /usr/rc.d/localpkg lediglich "rcorder -s nostart /etc/rc.d/* /usr/local/etc/rc.d/* /usr/X11R6/etc/rc.d/*" oder was auch immer ${local_startup} vorgegeben hat aufrufen und "rcorder -s nostart /etc/rc.d/*" davon wieder abziehen.

Das grosse Problem da bei ist allerdings folgendes. Das obige Vorgehen sorgt zwar dafuer, dass die Skripte in ${local_startup} in der richtigen Reihenfolge ausgefuert werden, jedoch erst nachdem alle /etc/rc.d Skripte ausgefuert worden sind, was wiederum bedeutet, dass die Reihenfolge, die per rcorder-Anweisungen in den ${local_startup}-Skripten angegeben wurde, in gewissen Faellen nicht den gewunschten Effekt zur Folge hat. Beispielsweise BEFORE: NETWORKING oder aehmliches.

Weiss jemand von euch, ob es da schon bessere Loesungen gibt?



teuk

edit:
Ich habe grade mal hackers@ durchstoebert und eine Mail von Brooks Davis impliziert dass es evtl. Support fuer lokale Skripte in FreeBSD 7.x geben wird:
Code:
[...] in 7.0 if we end up supporting ordering of local scripts.
Dann lasse ich meine Fummelei mal lieber bleiben.
 
Last edited:
Gibt sowieso nur ärger wenn man updated.

Interessante einsichten. So lange kannst du ja mit ein paar zeilen zusätzlichen codes die richtige Reihenfolge in deinen rc.d Skripten selbst sicherstellen.

Code:
#
# ensure that arlad is running
#
arlad=$(cat /var/run/arlad.pid 2> /dev/null)
if [ $? -eq 1 ]; then
    # arlad is not active - start it
    /usr/local/etc/rc.d/arlad.sh start
else
   # check weather arlad process is found running
   ps $arlad > /dev/null 2> /dev/null
   if [ $? -eq 1 ]; then
       # arlad is not active - start it
       /usr/local/etc/rc.d/arlad.sh start
   fi
fi
 
hi,

erst mal danke fuer deine Antwort, sieht ja so weit ganz gut aus und tut auch was es soll. Ich habe es etwas abgeaendert, aber es aendert an der Funktionsweise ja nichts:
Code:
if [ ! -f /var/run/arlad.pid ]; then
        /usr/local/etc/rc.d/arlad.sh forcestart
else
        ps `cat /var/run/arlad.pid` > /dev/null 2> /dev/null
        if [ ! $? -eq 0 ]; then
                /usr/local/etc/rc.d/arlad.sh forcestart
        fi
fi
Das funktioniert zwar alles nur solange arlad seine PID in /var/run/arlad.pid ableget, sonst muss man eben auf andere Art und Weise feststellen, ob arlad laeuft, aber da arlad anscheinend keinen Schalter fuer die PID hat sollte das erstmal kein Problem sein.

Danke.


teuk
 
Last edited:
Es geht auch mit.
Code:
# Search the process table for an active arlad binary.
ps -ax | grep "/usr/local/sbin/arlad" > /dev/null 2> /dev/null"
if [ $? -eq 1 ]; then
    # arlad is not active
    ...
fi
Ich weiß nicht ob meine Pfadangabe stimmt, aber ansonsten sollte es funktionieren.
 
Das Problem dabei ist allerdings, dass sich grep bisweilen selbst in der "ps -ax"-Ausgabe findet. Deshalb belasse ich es vorerst bei der PID-File.



teuk
 
teuk said:
Das Problem dabei ist allerdings, dass sich grep bisweilen selbst in der "ps -ax"-Ausgabe findet. Deshalb belasse ich es vorerst bei der PID-File.
dann gebe Ihm noch ein grep mit und gut ist:

Code:
ps -ax | grep "/usr/local/sbin/arlad" | grep -v grep > /dev/null 2> /dev/null"
Gruß
paefchen
 
teuk said:
Das Problem dabei ist allerdings, dass sich grep bisweilen selbst in der "ps -ax"-Ausgabe findet. Deshalb belasse ich es vorerst bei der PID-File.
Stimmt, passiert bei mir in ca. einem von vier Fällen.

Aber wie paefchen demonstriert, gibt es kein Problem mit grep, das nicht mit grep gelöst werden kann. :)
 
hi,

die Idee mit grep -v "grep" hatte ich auch schon gehabt. Allerdings gibt es bei der ganzen "greperei" ein essentielles Problem, weswegen ich mich fuer die PID-Variante entschieden habe:
Wenn es fuer ps keinen Schalter gibt, der den vollen Pfad der Programme anzeigt, dann ist nicht sicher gestellt, dass arlad nur bei Vorhandensein von "/usr/arla/bin/arlad" in der ps-Ausgabe laeuft. Wenn ich arlad von /usr/arla/bin aus starte, dann muss ich nach "arlad" grepen. Das wiederum hat zur folge, dass arald.sh sich selbst findet, was dazu fuehren kann, dass arlad nicht gestartet wird.
Natuerlich koennte ich dann das "Selberfinden" wieder per "basename $0" ausschliessen, das aendert aber nichts an dem grundsaetzlichen Problem.

Oder habe ich wieder etwas uebersehen, was mein Problem auf einfache Weise loesen kann?



teuk
 
Last edited:
Aus Sicherheitsgründen solltest du es natürlich immer über das Skript starten. Dann wird arlad natürlich auch mit Pfad von ps angezeigt.
Du kannst ja bei negativem Ergebniss noch sicherheitshalber ein
killall arlad 2> /dev/null > /dev/null
vor den Aufruf von
/usr/local/etc/rc.d/arlad.sh
setzen.
 
Bei jedem Test eine evlt. laufende arlad Instanz abzuschiessen ist aber auch nicht grade die feine Art *g*, zumal dann AFS-technisch erst mal nichts geht bis arlad wieder laeuft. Ich lasse es erstmal bei den PIDs.



teuk
 
ich verstehe das Problem nicht. OK mit PidFile ist in ordnung hat aber auch seine nachteile.
Wenn Du das Programm aber aus dem Skript starten willst, solltest Du es mit absoluten Pfadangaben tuen, somit weist Du den Pfad im Skript auch und kannst danach grepen und mit -v grep selber ausschliessen.

Gruß paefchen
der Pidfiles meist für überflüssig hält
 
Mir sind beide Lösungsansätze recht. Wenn ein Programm einen .pid anlegt würde ich den auch verwenden. Der vorteil der 2. Lösung ist halt das sie auch bei Programmen, die das nicht tun angewendet wird.

Wenn du ohne Pfad nach arlad greppen willst, geht das so natürlich auch.

ps -ax | grep arlad | grep -v grep | grep -v .sh > /dev/null 2> /dev/null"

oder mit

ps -ax | grep arlad | grep -v grep | grep -v rc.d > /dev/null 2> /dev/null"

...
eigentlich gibt es endlose Möglichkeiten.
 
Back
Top