Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 07/12/2009, à 17:35

coethium

Upstart (aide à l'analyse)

J'ai voulu me pencher un peu sur upstart, et pour mieux comprendre je me suis fait un script (pas très propre !) qui décortique les interactions entre les jobs.

Nécessite graphviz

#!/bin/sh

TMP_FILE=`tempfile`

LINE=""
ON_LEFT=""
ON_RIGHT=""

_shift() {
	N=$1
	shift
	while [ $N -ne 0 ]; do
		shift
		N=$((N-1))
	done
	LINE=$*
}

_group() {
	while true; do
		WORD=`echo $LINE | sed s/' .*'/''/`
		if [ -z "`echo $WORD | grep '='`" ]; then
			case $WORD in
				and) _shift 1 $LINE
					_starton $LINE
					_shift $? $LINE
					;;
				or) _shift 1 $LINE
					_starton $LINE
					_shift $? $LINE
					;;
				\() _shift 1 $LINE
					_group
					;;
				\)) return;;
				*) _starton $LINE
					_shift $? $LINE
					;;
			esac
		else
			_shift 1 $LINE
		fi
		if [ -z "$LINE" ]; then
			read LINE
			LINE=`echo $LINE | sed s/'-'/'_'/g | sed s/'('/' ( '/g | sed s/')'/' ) '/g`
		fi
	done
}

_runlevel() {
	NUMS=`echo $1 | sed s/'\(.\)'/'\1 '/g | tr '[' ' ' | tr ']' ' '`
	for i in $NUMS; do
		echo "runlevel_$i>$NAME" | sed s/'-'/'_'/g | sed s/'>'/'->'/ >> $TMP_FILE
		ON_LEFT="$ON_LEFT runlevel_$i rc_sysinit"
		ON_RIGHT="$ON_RIGHT $NAME runlevel_$i"
	done
}

_starton() {
	case $1 in
		started) echo "$2>$NAME [color=green]" | sed s/'-'/'_'/g | sed s/'>'/'->'/ >> $TMP_FILE
			ON_LEFT="$ON_LEFT $2"
			ON_RIGHT="$ON_RIGHT $NAME"
			return 2;;
		starting) echo "$2>$NAME [color=green]" | sed s/'-'/'_'/g | sed s/'>'/'->'/ >> $TMP_FILE
			ON_LEFT="$ON_LEFT $2"
			ON_RIGHT="$ON_RIGHT $NAME"
			return 2;;
		stopping) echo "$2>$NAME [color=red]" | sed s/'-'/'_'/g | sed s/'>'/'->'/ >> $TMP_FILE
			ON_LEFT="$ON_LEFT $2"
			ON_RIGHT="$ON_RIGHT $NAME"
			return 2;;
		stopped) echo "$2>$NAME [color=red]" | sed s/'-'/'_'/g | sed s/'>'/'->'/ >> $TMP_FILE
			ON_LEFT="$ON_LEFT $2"
			ON_RIGHT="$ON_RIGHT $NAME"
			return 2;;
		runlevel) _runlevel $2
			return 2;;
		\() LINE=$*
			_group
			;;
		*) 	echo "$1>$NAME" | sed s/'-'/'_'/g | sed s/'>'/'->'/ >> $TMP_FILE
			ON_LEFT="$ON_LEFT $1"
			ON_RIGHT="$ON_RIGHT $NAME"
			return 1;;
	esac
}

_parse() {
	case $1 in
		start) shift 2
			LINE=`echo $* | sed s/'('/' ( '/g | sed s/')'/' ) '/g`
			_starton $LINE
			;;
		emits) shift
			echo "$NAME>$1" | sed s/'-'/'_'/g | sed s/'>'/'->'/ >> $TMP_FILE
			ON_LEFT="$ON_LEFT $NAME"
			ON_RIGHT="$ON_RIGHT $1"
			;;
	esac
}

echo > ./upchart.dot

echo "ifup [shape=diamond]" >> $TMP_FILE
echo "networking->ifup->net_device_up" >> $TMP_FILE
echo "network_interface->ifup" >> $TMP_FILE
echo "rc_sysinit->{runlevel_S runlevel_0 runlevel_1 runlevel_2 runlevel_3 runlevel_4 runlevel_5 runlevel_6}" >> $TMP_FILE
ON_LEFT="$ON_LEFT networking ifup network_interface"
ON_RIGHT="$ON_RIGHT ifup net_device_up"

for FILE in `ls /etc/init`; do
	NAME=`echo $FILE | tr '-' '_' | sed s/'\.conf$'/''/`
	echo "$NAME [shape=box]" >> $TMP_FILE
	echo $NAME
	while read LINE; do
		LINE=`echo $LINE | sed s/'#.*'/''/`
		_parse $LINE
	done < /etc/init/$FILE
done

ON_LEFT=`echo $ON_LEFT | tr '-' '_' | tr ' ' '\n' | sort | uniq`
ON_RIGHT=`echo $ON_RIGHT | tr '-' '_' | tr ' ' '\n' | sort | uniq`

for i in $ON_LEFT; do
	if [ "$i" != "startup" ]; then
		echo ---$i---
		echo $ON_RIGHT | grep -q $i || echo "NO_PARENT->$i" >> $TMP_FILE
	fi
done

TMP2=`tempfile`
cat $TMP_FILE | sort > $TMP2
echo 'digraph upchart {
ratio=0.56
subgraph clusterlegend {
	label="legend"
	event
	".conf" [shape=box]
	event->".conf" [color=green label=start fontcolor=green]
	".conf"->event [color=red label=stop fontcolor=red]
	color=black
}
startup->NO_PARENT' > $TMP_FILE
cat $TMP2 >> $TMP_FILE
echo "}" >> $TMP_FILE

dot -Tsvg -o /tmp/upchart.svg $TMP_FILE
eog /tmp/upchart.svg

Et voici le résultat chez moi :
http://ww1.nolipro.com:8002/servimages/ … v0mpxb.png

Là on commence à voir la complexité du truc ! Et encore j'ai supprimé certains détails afin de ne voir apparaître que la notion de hiérarchie (pas de différence entre OU et ET ; pas de différence entre event-ING ou event-ED)

J'estime qu'upstart propose une alternative très intéressante en remplacement de systemV, justement car basé sur des évènements ! Mais c'est là aussi sa faille quand on veut le comprendre.

Vous verrez sur le graphe un évènement NO_PARENT : ses enfants sortent d'on ne sait où.
Dans le cas de xdm ou kdm, c'est normal puisque j'ai gdm chez moi, une solution serait de fusionner ces trois jobs sur le graphe.
Mais dans le cas de net_device_added, tty_device_added ou graphics_device_added bah franchement je ne sais pas qui envoie ces évènements. et comme n'importe qui peut générer un évènement (avec initctl my_event) ça va devenir bien complexe de tout dépétrer quand chaque développeur y sera allé de son propre évènement.

Alors sur le wiki d'upstart ils recommandent de créer une man page de chaque nouvel évènement. Très bien, sauf qu'ils ne suivent même pas leur propre recommandation, aucune man page pour [net|tty|graphics]-device-[added|removed]. Et même si on comprend bien leur sens, QUI le émets et QUAND sont-ils émits ? intuitivement je suppose que c'est quelques part entre hal ou udev, mais mes recherches n'ont rien données.

net-device-added était dans le même cas, mais j'ai fini par trouver qu'il est émit par le script lancé par ifup donc je l'ai codé en dur dans le script que je vous donne.

Grace à cette notion d'évènements, ils comptent remplacer cron, anacron et atd. Ce qui me chagrine c'est qu'ainsi on va s'éloigner du concept "un programme pour une fonctionnalité", et je crains qu'upstart n'en vienne à trainer derrière lui une usine à gaz de jobs et d'évènements peu ou non documentés.

Bref je ne crache pas sur la bête, mais l'utilisation qui pourrait en être faite. A noter que le graph actuellement généré ne prend en compte que les jobs de /etc/init ; or de nombreux services n'ont pas encore été convertis à upstart et sont donc toujours en sysV, lancé par le job rc, et non visibles sur ce graph...

En attendant toute info sur les évènements sans parent m'intéresse wink

Hors ligne