Dank der RHEL-Unterstützung wurde die klare Lösung gefunden. Es basiert auf der Verwendung des Systemtap-Kernelmoduls. Zitiert von hier , um Link Rot zu vermeiden. Und nochmals vielen Dank für all Ihre Ratschläge :)
Ich konnte mir nicht einmal vorstellen, dass systemtap noch vor dem Init-Skript starten und den Bootvorgang verfolgen kann. Ich schätze den Red Hat Support und persönlich Pushpendra Chavan sehr für die Hilfe bei diesem perfekten Tool (leider weiß ich nicht, zu welchen Entwicklern diese Methode gehört - sonst würde ich sie überhaupt gutschreiben).
Wir müssen also zwei einfache Skripte erstellen:
bootinit.sh
::
#!/bin/sh
# Use tmpfs to collect data
/bin/echo "Mounting tmpfs to /tmp/stap/data"
/bin/mount -n -t tmpfs -o size=40M none /tmp/stap/data
# Start systemtap daemon & probe
/bin/echo "Loading bootprobe2.ko in the background. Pid is :"
/usr/bin/staprun \
/root/bootprobe2.ko \
-o /root/bootprobe2.log -D
# Give daemon time to start collecting...
/bin/echo "Sleeping a bit.."
sleep 5
# Hand off to real init
/bin/echo "Starting."
exec /sbin/init 3
und bootprobe2.1.stp
in eingebetteter Systemtap-Skriptsprache geschrieben:
global ident
function get_usertime:long() {
return task_utime() + @cast(task_current(), "task_struct", "kernel<linux/sched.h>")->signal->utime;
}
function get_systime:long() {
return task_stime() + @cast(task_current(), "task_struct", "kernel<linux/sched.h>")->signal->stime;
}
function timestamp() {
return sprintf("%d %s", gettimeofday_s(), ident[pid()])
}
function proc() {
return sprintf("%d \(%s\)", pid(), execname())
}
function push(pid, ppid) {
ident[ppid] = indent(1)
ident[pid] = sprintf("%s", ident[ppid])
}
function pop(pid) {
delete ident[pid]
}
probe syscall.fork.return {
ret = $return
printf("%s %s forks %d \n", timestamp(), proc(), ret)
push(ret, pid())
}
probe syscall.execve {
printf("%s %s execs %s \n", timestamp(), proc(), filename)
}
probe syscall.open {
if ($flags & 1) {
printf("%s %s writes %s \n", timestamp(), proc(), filename)
} else {
printf("%s %s reads %s \n", timestamp(), proc(), filename)
}
}
probe syscall.exit {
printf("%s %s exit with user %d sys %d \n", timestamp(), proc(), get_usertime(), get_systime())
pop(pid())
}
<linux sched.h=""><linux sched.h="">
</linux></linux>
Um die Liste der Dateien zu erhalten, auf die während des Startvorgangs im Systemtap-Protokollformat zugegriffen wird, sollten Sie Folgendes implementieren:
Herunterladen und Installieren der RICHTIG genannten Versionen systemtap
und kernel debuginfo
Pakete (ich habe gegeben worden auf diesen Link , aber Sie würden besser nutzen diese , wenn Sie auf CentOS sind);
Erstellen /tmp/stap
und/tmp/stap/data
mkdir -p /tmp/stap/data
Platziere bootprobe2.1.stp
und bootinit.sh
in /root
und mache sie ausführbar: chmod + x / root / boot *
Bearbeiten bootinit.sh
und ändern Sie 'exec / sbin / init 3' in 'exec / sbin / init 5', wenn 5 Ihr Standard-Runlevel ist.
Erstellen Sie das .ko-Modul aus bootprobe2.stp
cd /root
stap bootprobe2.1.stp -m bootprobe2 -p4
Starten Sie neu.
Halten Sie an grub
(drücken Sie Esc oder Shift) und drücken Sie 'a' auf dem Standardkernel. Geben Sie am Ende der Kernelzeile Folgendes ein und drücken Sie die Eingabetaste:
init=/root/bootinit.sh,
Der normale Startvorgang wird fortgesetzt. Kopieren Sie nach dem Anmelden kill
den stapio
Vorgang bootprobe2.log
aus dem tmpfs
/tmp/stap/data
Verzeichnis und heben Sie die Bereitstellung auf.
killall stapio
cp /tmp/stap/data/bootprobe2.log /tmp/stap/
umount /tmp/stap/data
Überprüfen Sie nun die Datei /tmp/stap/bootprobe2.log
auf die Liste aller Dateien, die beim Booten gelesen werden.