Journal De la façon dont un problème de boot est résolu sous FreeBSD

Posté par  (site web personnel) . Licence CC By‑SA.
Étiquettes :
42
27
juil.
2012

Sommaire

En ces temps troublés par l'arrivée de systemd dans ArchLinux et les histoires de SecureBoot et de grub2 je trouve intéressant de faire un petit journal pour raconter un peu ce qui se passe ailleurs.

Lancer init

FreeBSD par défaut utilise son propre boot loader appelé boot. Il se décompose en trois phases boot0, boot1 et boot2. Ces programmes n'ont rien de folichon, sinon qu'ils permettent éventuellement de choisir un disque et un noyau pour booter. Ils finissent normalement par lancer un programme un peut plus évolué (loader) qui présente un menu avec différentes options de maintenance (single user …) et un petit shell avec quelques commandes essentielles : charger décharger un noyau et des modules, lister des fichiers et des périphériques, placer des variables d'environnement.

loader, comme son nom l'indique fini par charger un noyau et l’exécuter. Lorsqu'il a terminé de se lancer, ce dernier passe la main à init qui exécute le script /etc/rc.

/etc/rc

Ce script commence par sourcer quelques fichiers afin d'avoir ses fonctions et sa configuration puis lance rcorder pour déterminer l'ordre d’exécution des scripts. On peut connaitre cet ordre en utilisant la commande

rcorder /etc/rc.d/*

On constate alors plusieurs choses.

## Déterminer si un script doit être exécuté ou pas ##

Tous les scripts présent dans /etc/rc.d/ seront exécutés. C'est le script lui même qui détermine s'il doit faire quelque chose. Prenons l'exemple de ssh. Dans /etc/default/rc.conf on a :

sshd_enable="NO"                # Enable sshd
sshd_program="/usr/sbin/sshd"   # path to sshd, if you want a different one.
sshd_flags=""                   # Additional flags for sshd.

Dans /etc/rc.conf :

sshd_enable="YES"

Dans /etc/rc.d/sshd

...
name="sshd"
rcvar="sshd_enable"
...

load_rc_config $name
run_rc_command "$1"

load_rc_config source différents fichiers susceptible de contenir une directive déterminant si sshd doit être lancé ou pas. Ensuite run_rc_command appelle la fonction checkyesno qui évalue la valeur de rcvar

checkyesno()
{                      
        eval _value=\$${1}
        debug "checkyesno: $1 is set to $_value."
        case $_value in

                #       "yes", "true", "on", or "1"
        [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
                return 0
                ;;

                #       "no", "false", "off", or "0"
        [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
                return 1
                ;;
        *)      
                warn "\$${1} is not set properly - see ${rcvar_manpage}."
                return 1
                ;;
        esac
}

Dans notre cas ssh sera lancé mais ce n'est pas le cas dans une installation par défaut.

Gestion des dépendances

Il existe quelques pseudo scripts marquant des étapes importantes du démarrage. Dans l'ordre :

...
/etc/rc.d/FILESYSTEMS
...
/etc/rc.d/NETWORKING
...
/etc/rc.d/SERVERS
...
/etc/rc.d/DAEMON
...
/etc/rc.d/LOGIN

Ceux-ci permettent de déterminer à quel moment du boot nous en sommes et de gérer les dépendances. Si on reprend le cas de sshd.

Dans /etc/rc.d/sshd on a :

# PROVIDE: sshd
# REQUIRE: LOGIN cleanvar
# KEYWORD: shutdown

On sait donc que le script sshd doit être exécuté après le script cleanvar et le pseudo script LOGIN.

cat /etc/rc.d/LOGIN
#!/bin/sh
#
# $FreeBSD: src/etc/rc.d/LOGIN,v 1.6.2.1.8.1 2012/03/03 06:15:13 kensmith Exp $
#

# PROVIDE: LOGIN
# REQUIRE: DAEMON

#       This is a dummy dependency to ensure user services such as xdm,
#       inetd, cron and kerberos are started after everything else, in case
#       the administrator has increased the system security level and
#       wants to delay user logins until the system is (almost) fully
#       operational.

On sait aussi que chaque script déclarant REQUIRE: sshd doit être exécuté après celui-ci. Enfin KEYWORD: shutdown permet de déterminer qu'il sera nécessaire d’exécuter ce script lors de l’arrêt du système :

/etc/rc.d/sshd stop

Voila donc à peu près comment les choses se passent. Après /etc/rc.d, rc`` passe à/usr/local/etc/rc.dpuis à/etc/rc.local``` et le système a démarré.

L'affreux spanning tree

Spanning tree est un protocole bien sympa mais il pose au moins un problème. Suivant la configuration, le réseau peut être relativement lent à monter. L'interface et up mais le serveur reste inaccessible durant quelques secondes. Cela n'est pas très grave en soit si ce n'est que ntpd à besoin de pouvoir résoudre le nom des serveurs de temps pour démarrer. Sinon, il ne fait rien, il ne met pas le serveur à l'heure …

Pour résoudre se problème (et d'autres) un petit script de rc a été introduit :

#!/bin/sh

# $FreeBSD: src/etc/rc.d/netwait,v 1.2.2.3.2.1 2012/03/03 06:15:13 kensmith Exp $
#
# PROVIDE: netwait
# REQUIRE: NETWORKING
# KEYWORD: nojail
#
# The netwait script is intended to be used by systems which have
# statically-configured IP addresses in rc.conf(5).  If your system
# uses DHCP, you should use synchronous_dhclient="YES" in your
# /etc/rc.conf instead of using netwait.

. /etc/rc.subr

name="netwait"
rcvar="netwait_enable"

start_cmd="${name}_start"
stop_cmd=":"

netwait_start()
{
        local ip rc count output link

        if [ -z "${netwait_ip}" ]; then
                err 1 "You must define one or more IP addresses in netwait_ip"
        fi

        if [ ${netwait_timeout} -lt 1 ]; then
                err 1 "netwait_timeout must be >= 1"
        fi

        # Handle SIGINT (Ctrl-C); force abort of while() loop
        trap break SIGINT

        if [ -n "${netwait_if}" ]; then
                echo -n "Waiting for $netwait_if to have link"

                count=1
                while [ ${count} -le ${netwait_if_timeout} ]; do
                        if output=`/sbin/ifconfig ${netwait_if} 2>/dev/null`; then
                                link=`expr "${output}" : '.*[:blank](http://fr.wikipedia.org/wiki/:blank: "Définition Wikipédia")status: \(no carrier\)'`
                                if [ -z "${link}" ]; then
                                        echo '.'
                                        break
                                fi
                        else
                                echo ''
                                err 1 "ifconfig ${netwait_if} failed"
                        fi
                        sleep 1
                        count=$((count+1))
                done
                if [ -n "${link}" ]; then
                        # Restore default SIGINT handler
                        trap - SIGINT

                        echo ''
                        warn "Interface still has no link.  Continuing with startup, but"
                        warn "be aware you may not have a fully functional networking"
                        warn "layer at this point."
                        return
                fi
        fi

        # Handle SIGINT (Ctrl-C); force abort of while() loop
        trap break SIGINT

        for ip in ${netwait_ip}; do
                echo -n "Waiting for ${ip} to respond to ICMP"

                count=1
                while [ ${count} -le ${netwait_timeout} ]; do
                        /sbin/ping -t 1 -c 1 -o ${ip} >/dev/null 2>&1
                        rc=$?

                        if [ $rc -eq 0 ]; then
                                # Restore default SIGINT handler
                                trap - SIGINT

                                echo '.'
                                return
                        fi
                        count=$((count+1))
                done
                echo ': No response from host.'
        done

        # Restore default SIGINT handler
        trap - SIGINT

        warn "Exhausted IP list.  Continuing with startup, but be aware you may"
        warn "not have a fully functional networking layer at this point."
}

load_rc_config $name
run_rc_command "$1"

Du coup, si on ne souhaite pas que la machine continue son démarrage avant d'avoir réellement du réseau, il suffit donc de rajouter :

netwait_enable="YES" 
netwait_ip="XXX.XXX.XXX.XXX"

dans /etc/rc.conf

Conclusion

Aucune. C'était gratuit. Pour peut-être éclairer un peu le débat.

  • # Conclusion

    Posté par  (site web personnel) . Évalué à 9.

    La conclusion c'est que si systemd et les choses de ce genre vous fatiguent, FreeBSD vous tend les bras (voire OpenBSD pour les mangeurs d'enfants). C'est libre et gratuit…

    OpenBSD a abandonné y'a pas longtemps le vieux rc pour un truc qui ressemble au rc.d (mais perso je préfère rc-ng, pas vu comment faire un "onestart" sur un script rc dans Open et je ne trouve pas ça super-pratique).

    RC-ng a été développé par NetBSD puis intégré à FreeBSD >= 5.

    The Design and Implementation of the NetBSD rc.d system

    les pixels au peuple !

    • [^] # Re: Conclusion

      Posté par  (site web personnel) . Évalué à 5.

      Sinon, pour ceux qui veulent tout de même rester sur du GNU/Linux, il y a toujours Slackware (et peut-être ses dérivés, mais là je ne sais pas), qui utilise un init de type BSD (elle supporte aussi les scripts d’init System V pour ceux qui en auraient besoin, mais aucun des programmes fournis avec la Slack ne s’en sert).

      Après, pourra-t-elle se passer de systemd longtemps, ça c’est une autre histoire.

    • [^] # Re: Conclusion

      Posté par  . Évalué à 7.

      L'autre conclusion est que si ces scripts shells ne vous intéressent pas, alors systemd est mieux :-)

    • [^] # Re: Conclusion

      Posté par  (site web personnel) . Évalué à 3.

      "onestart" sous OpenBSD se fait de la manière suivante:
      /etc/rc.d/foobar -f start

      Comme indiqué dans man rc.d:
      -f Setting this option will force operations with the given action.
      If daemon_flags is set to ``NO'', execution will continue with
      the script's own defaults unless other flags are specified.

  • # C'est comme ça partout non ?

    Posté par  . Évalué à 6.

    Je me trompe peut-être, mais à quelques détails près c'est comme ça partout (partout où il n'y a pas systemd).
    Une Debian par exemple, c'est à 95% la même chose que la description faite ici.
    Un détail important m'a échappé ?

    • [^] # Re: C'est comme ça partout non ?

      Posté par  . Évalué à 7.

      C'est même pour éviter que chacun fasse ses scripts dans son coin ! coin ! que système est arrivé pour unifier de manière propre le genre de hack en tout genre tel que décrit dans le journal.

      « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

  • # Excusez moi mais…

    Posté par  . Évalué à 10.

    Vous trouvez ça KISS ?

    Que ça soit Archlinux ou FreeBSD, je trouve que le systéme de boot est un pur amas de hacks. Déjà, les scripts sont écrits dans un langage non typé, dont la grammaire fairait tomber en syncope un grammairien français (c'est dire !), et dont la sémantique est tout sauf simplement définie. Un truc qui fuit de partout en amassant des données n'importe ou là ou il ne devrait pas (environnement, tout ça). Bref, un truc écrit dans un langage bloat, pas safe, avec de la duplication de code (oui les scripts rc sont tous les mêmes), qui apporte quoi au final ?

    Et on appelle ça KISS ?

    Pour finir, une petite quote de l'installateur d'openBSD :

    OpenBSD installation script.
    In a perfect world, this would be a nice C program, with a reasonable
    user interface.

    • [^] # Re: Excusez moi mais…

      Posté par  (site web personnel) . Évalué à 5.

      Pour finir, une petite quote de l'installateur d'openBSD :
      > OpenBSD installation script.
      >In a perfect world, this would be a nice C program, with a reasonable
      >user interface.

      D'abord, je doute de la pertinence de vouloir comparer un programme d'installation avec un daemon d'init. Ce dernier tourne constamment et doit interagir avec l'utilisateur régulièrement. Un programme d'installation de système d'exploitation n'a pas du tout les mêmes contraintes.

      Bref, un truc écrit dans un langage bloat, pas safe, avec de la duplication de code (oui les scripts rc sont tous les mêmes), qui apporte quoi au final ?

      Je trouve que ta remarque ne manque pas de sel. Je cite:

      Systemd is bloated. It apparently attempts to take over the roles of init, cron, at, inet, ConsoleKit, sethostname, modprobe, mount -a, and probably others. The result is that you end up running 50000 lines of C code as PID 1, as compared to the 8000 lines of SV init or the 6000 lines of runit.

      Bizarrement, j'ai moins confiance dans 50 000 lignes de code C que dans des scripts shell pas safe. Tiens, d'ailleurs OpenBSD aussi utilise des scripts shell pour son démarrage. Il faudrait leur dire que ce n'est pas safe du tout, les pauvres.

      SkyNet Systemd init
      Testing for linux…
      Testing for RedHat materials…
      Erasing /etc/rc.d…
      malloc(10000000*sizeof(long long int);
      Laughing at portability (sleep 42)
      Painfully translate systemd config syntax to shell
      Launching services…
      PulseAu
      segfault

      • [^] # Re: Excusez moi mais…

        Posté par  . Évalué à 1.

        Sauf que ces lignes de code remplacent le code de pleins d'autres outils comme cron, at, inetd qui reimplementent tous la meme chose de facon legerement differente. Systemd permet de dedupliquer le code et gerer tout ca de facon plus unifiée.

        • [^] # Re: Excusez moi mais…

          Posté par  . Évalué à 10.

          Sauf que si :

          • J'ai pas besoin d'atd (d'ailleurs, à quoi ça sert ? il n'est même pas installé sur la plupart de mes systèmes, et quand il est installé, c'est parce que LSB en dépend),
          • J'ai pas besoin d'inet (c'est simple : au démarrage, soit je lance aucun service réseau, soit j'en lance plein),
          • J'ai pas besoin de sethostname (c'est pas comme si je changeait d'hostname tout les jours)
          • et j'ai pas besoin de consolekit…

          Alors systemd est un gros bloat qui implémente des fonctionnalités inutiles. Quel intérêt d'intégrer tout les inconvénients de tout les outils existants, quand la plupart ne sont pas installés/utiles par défaut ?

          • [^] # Re: Excusez moi mais…

            Posté par  . Évalué à -9.

            Ben c'est sur, si t'as besoin de rien faire sur ta machine, autant utiliser le systeme de boot le plus simple possible, reste sur slackware.

            • [^] # Re: Excusez moi mais…

              Posté par  . Évalué à 9.

              Ah ben voila, si on à pas besoin d'un gros merdier lourdingue plantogène, alors notre machine sert à rien … On dirait les windowsiens à venir dire que si ta machine n'est pas assez puissante pour faire tourner Windows, c'est que ta machine sert à rien.

              Madame michu n'a pas besoin d'atd, n'a pas besoin d'inetd, les seules choses qui pourraient servir, c'est sethostname et consolekit (sur un portable), et je vois pas pourquoi ça devrai être dans le processus critique PID 1.

              • [^] # Re: Excusez moi mais…

                Posté par  . Évalué à 3.

                c'est sethostname et consolekit (sur un portable), et je vois pas pourquoi ça devrai être dans le processus critique PID 1.

                Ben ça tombe bien, l'équivalent de consolekit (c'est à dire logind) est pas dans le PID 1 et est totalement optionnel.
                Quand à sethostname, heu, attends, tu vas leur reprocher d'appeler directement la fonction C pour définir le hostname plutôt que de fork+exec un binaire qui ne fait rien d'autre qu'appeler cette fonction ?

                • [^] # Re: Excusez moi mais…

                  Posté par  . Évalué à 3.

                  Justement, ils font plus que changer le hostname, ils gardent aussi une trace de cette modification pour le prochain redémarrage.

                  « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                  • [^] # Re: Excusez moi mais…

                    Posté par  . Évalué à 3.

                    Ah mais dans ce cas on parle du service dbus hostnamed, qui n'est donc pas dans le PID 1 (et est lui aussi optionnel)

                    • [^] # Re: Excusez moi mais…

                      Posté par  . Évalué à 3.

                      Oui, c'était uniquement parce que je sentais venir la remarque pour dire que systemd réinvente la roue.

                      « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

        • [^] # Re: Excusez moi mais…

          Posté par  (site web personnel) . Évalué à 8.

          pleins d'autres outils comme cron, at, inetd qui reimplementent tous la meme chose de facon legerement differente

          Quoi?

          In Unix-based computer operating systems, init (short for initialization) is the first process started during booting,

          cron enables users to schedule jobs (commands or shell scripts) to run periodically at certain times or dates

          In Unix-like computer operating systems, the at command is used to schedule commands to be executed once, at a particular time in the future.

          inetd (internet service daemon) is a super-server daemon on many Unix systems that manages Internet services

          gethostname, sethostname - get/set host name

          modprobe is a Linux program originally written by Rusty Russell and used to add a loadable kernel module (LKM) to the Linux kernel or to remove an LKM from the kernel

          The Unix command line utility mount instructs the operating system that a file system is ready to use, and associates it with a particular point in the system's file system hierarchy (its mount point)

          Je vois pas comment tu peux honnêtement dire que tous ces outils font tous la même chose. mount et atd sont peut-être semblables, mais l'un ne peut pas remplacer l'autre.

          xkcd

          • [^] # Re: Excusez moi mais…

            Posté par  . Évalué à 4. Dernière modification le 29 juillet 2012 à 11:52.

            mount et atd sont peut-être semblables, mais l'un ne peut pas remplacer l'autre.

            Tu dois commettre une erreur là. mount et atd ça n'a juste rien à voir… Déjà mount n'est pas un daemon.

            mount - mount a filesystem
            atd - run jobs queued for later execution
            
            

            Tu voulais peut-être parler de cron et atd mais là encore les deux sont complémentaires et ne font pas la même chose.

            Sinon excellent le xkcd :)

          • [^] # Re: Excusez moi mais…

            Posté par  . Évalué à 6.

            Il ne font pas 100% la meme chose évidemment, mais il y a une grosse partie commune: ils sont tous chargés de gérer le démarrage de processus. La seule chose qui diffère c'est l'événement qui doit déclencher le démarrage: au boot, à une horaire précise, à intervale régulier, lors d'une connection sur un socket, etc … Tout regrouper en un seul outil ca permet de simplifier en utilisant le meme code et en plus de profiter de toutes les fonctionnalités de systemd dans tous les cas, et évite de devoir gérer des locks à la main quand le processus peut etre lancé dans plusieurs cas différents.

            • [^] # Re: Excusez moi mais…

              Posté par  . Évalué à 1.

              Je comprends ton point de vue mais c'est contraire (à mon sens) à l'esprit Unix qui dit qu'un programme doit faire une chose et le faire bien. Comme ça a été dit plus haut, on peut vouloir utiliser cron sans atd ou vouloir ne pas utiliser inetd, etc… Tout regrouper simplement pour une question de performance (qui à l'air assez minime) et éviter la "complexité" de script shell d'init n'est pas forcément une bonne idée.

              Attendons de voir.

              • [^] # Re: Excusez moi mais…

                Posté par  . Évalué à 3.

                Ce n'est pas qu'une question de performance mais aussi éviter de dupliquer le code si j'ai bien compris. Atd et cron ont, au final, beaucoup d'opération en commun, dont certaines ne sont accessibles qu'au système d'init. Du coup, c'est plus propre de les embarqué que de jouer avec des hack, en double en plus.

                « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                • [^] # Re: Excusez moi mais…

                  Posté par  . Évalué à 2. Dernière modification le 30 juillet 2012 à 01:21.

                  M'est d'avis que si Lennart avait écrit un système d'init d'une part, et un remplaçant de atd & cron d'autre part beaucoup moins d'encre numérique aurait coulé… (si tu me dis que la duplication de code concerne atd et cron)

                  D'ailleurs il faudrait vraiment que je me renseigne sur systemd (enfin je suis pas pressé) car moi j'avais compris que c'était pour remplacer init, pas atd et cron. En fait systemd remplacerait cron et atd seulement pour les daemons système qui ont en besoin c'est ça ? Il resterait bien cron et atd pour les utilisateurs non ? Genre pour lancer un backup…

                  • [^] # Re: Excusez moi mais…

                    Posté par  . Évalué à 3.

                    J'avais compris qu'il remplaçait cron tout en restant compatible avec l'existant mais voulait proposer des fonctionnalités en plus (comme upstart voulais le faire) comme pouvoir dire "lancer ça 10 minutes après le démarrage" ou pouvoir dire "lancer ça toutes les 2h" en tenant compte de la veille et de l'heure de démarrage.

                    « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                    • [^] # Re: Excusez moi mais…

                      Posté par  . Évalué à 2. Dernière modification le 30 juillet 2012 à 01:55.

                      pouvoir dire "lancer ça toutes les 2h" en tenant compte de la veille et de l'heure de démarrage.

                      On peut pas déjà faire ça avec anacron ? Quoique non je ne crois pas, la granularité de anacron c'est le jour il me semble. Mais on aurait pu ajouter ça à anacron non ?

                      En gros tu voudrais "toutes les 2h" mais toujours pile 2h après le boot, puis 2h après, etc ?

                      Pour "lancer ça 10 minutes après le démarrage" il me semble justement que at (lancé par un script d'init) est tout indiqué non ?

                      • [^] # Re: Excusez moi mais…

                        Posté par  . Évalué à 3.

                        En gros tu voudrais "toutes les 2h" mais toujours pile 2h après le boot, puis 2h après, etc ?

                        Je ne voudrais pas, mais je crois que c'est ce qu'ils veulent offrir comme possibilités. Et tu parle d'anacron mais il me semble que ce dernier a(vait) du mal avec l'hibernation/mise en veille, justement parce qu'on ne peut pas lancer une commande toutes les 24h avec cron.

                        « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                        • [^] # Re: Excusez moi mais…

                          Posté par  . Évalué à 2.

                          anacron on peut le lancer (par cron) toute les 5 minutes si on veut. C'est pas un daemon. Il se lance, voit ce qu'il a à faire puis se termine s'il n'y a rien à faire. Donc que l'on ne puisse pas lancer une commande toute les 24h avec cron ne me semble pas un problème. Il faudrait par contre une granularité plus fine dans anacron.

                          • [^] # Re: Excusez moi mais…

                            Posté par  . Évalué à 3.

                            anacron on peut le lancer (par cron) toute les 5 minutes si on veut.

                            C'est ce que je dis, c'est loin d'être un comportement optimal.

                            « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                  • [^] # Re: Excusez moi mais…

                    Posté par  . Évalué à 2.

                    D'ailleurs il faudrait vraiment que je me renseigne sur systemd […]

                    Un bon point d'entrée :

                    https://linuxfr.org/news/%C3%A9volutions-techniques-de-systemd

                    Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

            • [^] # Re: Excusez moi mais…

              Posté par  (site web personnel) . Évalué à 4.

              Il y a deux façon de faire pour ne pas dupliquer du code :
              - soit tu rassembles le tout dans un seul programme qui fait tout … au risque de réécrire certaine partie avec l'évolution des usages. C'est en général ce que l'on appelle le bloatware,
              - soit tu rassembles le code à réutiliser dans une librairie pour que d'autres programmes puissent en profiter. L'avantage de cette solution est qu'elle apporte de la flexibilité.

              Et ceci est pareil en terme d'architecture logicielle :
              - soit tu rassembles tous tes blocs fonctionnels dans un seul bloc monolithique au risque de réécrire ou tout recompiler au moindre changement,
              - soit tu adoptes un socle modulaire (multi-services, multi-process, … les termes ne manquent pas pour désigner la même chose) reposant sur un bus de médiation.

              • [^] # Re: Excusez moi mais…

                Posté par  . Évalué à 2.

                Sauf que le code entre cron et init, c'est exactement la même chose sauf que le premier ne lance de processus au démarrage mais plus tard.

                « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                • [^] # Re: Excusez moi mais…

                  Posté par  (site web personnel) . Évalué à 2.

                  Non ce n'est pas exactement la même chose. Il ne faut pas confondre la conséquence, la finalité (lancer un processus) avec leur fonctionnalité principale : pour init c'est d'initialiser le système une fois le noyau démarré et parmi celle-ci on trouve le démarrage de services (daemons), pour cron c'est de planifier des tâches dans le temps. En terme de code, ce n'est pas exactement la même chose.

                  • [^] # Re: Excusez moi mais…

                    Posté par  . Évalué à 4.

                    Non ce n'est pas exactement la même chose.

                    Clairement.

                    • Init sait il setter un userid / groupe sur ce qu'il lance ?
                    • Init utilise-t-il /usr/bin/sendmail pour envoyer un mail quand le programme lancé émet quelque-chose sur sa sortie ?
                    • Init permet-il de lancer une tache régulière ?
                    • Cron sait il redémarrer un soft qui crash/termine pendant sa crontab ?
                    • Cron sait il lancer un truc selon le runlevel ? Quand une touche est pressée ? Quand un événement à lieu ?

                    On continue ? :)

                • [^] # Re: Excusez moi mais…

                  Posté par  . Évalué à 2.

                  Et bien tu sépare la fonctionnalité "lancer un processus" dans une bibliothèque/executable/autre bidule à part, et tu laisse init() et cron() utiliser cette fonctionnalité.

                  Et comme ça, tu pourra aussi permettre à d'autres logiciels de l'utiliser, du genre acpid ou mon logiciel buggé qui me rend bien des services mais que je n'ai pas publié.

                  C'est pourtant pas bien compliqué de faire du modulaire …

                  • [^] # Re: Excusez moi mais…

                    Posté par  . Évalué à 3.

                    Qu'est-ce qui te dit que ce ne sera pas implémenté de cette manière ?

                    « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                  • [^] # Re: Excusez moi mais…

                    Posté par  (site web personnel) . Évalué à 3.

                    Et bien tu sépare la fonctionnalité "lancer un processus"

                    man 3 exec

                    • [^] # Re: Excusez moi mais…

                      Posté par  . Évalué à 4.

                      Toi t'as tout compris.

                      exec ne lance pas de processus, il mute le processus courant vers un autre. C'est très bien expliqué dans la page de manuel que tu file.

                      Et sinon, exécuter un processus, ce n'est pas simplement définir les arguments et les variables d'environnements, c'est aussi définir à quoi est reliée son entrée standard, sa sortie standard et sa sortie d'erreur, et aussi éviter de leaker des fd du parent. C'est aussi définir l'utilisateur effectif/réel/fs, avec exceptionnellement des autorisations/capabilities supplémentaires. Sans parler de ceux qui veulent des cgroups/rlimits/netns/autres …

                      Enfin bref, pour lancer un processus qui va tourner en fond (ou pas), sous Debian, il y a déjà start-stop-daemon. Il suffirait juste de l'étendre un peu pour qu'il gère des paramètres en plus, et qu'il puisse prendre des options par programmes dans un fichier de configuration séparé, pour pouvoir définir des nouveaux paramètres par défaut et des options forcées pour certains programmes… et quasiment tout le système bénéficiera déjà des améliorations.

                      Mais bon, améliorer l'existant, c'est tellement pas drôle …

            • [^] # Re: Excusez moi mais…

              Posté par  . Évalué à 2.

              C'est pour ça qu'upstart me semblait génial.

              Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

      • [^] # Re: Excusez moi mais…

        Posté par  . Évalué à -5.

        Je n'ai pas parlé de systemd. Je parle de ce que certains semblent considérer comme le graal, les init BSD-like.

        Quelle est la différence entre un installateur et un init ? Dans les deux cas il y a une interaction utilisateur, ça t'arrive jamais de lancer un daemon ou de vérifier le status d'un autre ? Ou même de vouloir gére tes crgoups ? Le fait qu'init tourne constament est justement un argument de robustesse, donc, ce qui s'applique pour un installateur, qui est exécuté une seule fois, devrait s'appliquer a fortiori à un init.

        Je n'ai ni confiance en C, ni en POSIX shell.

      • [^] # Re: Excusez moi mais…

        Posté par  (site web personnel) . Évalué à 4.

        Bizarrement, j'ai moins confiance dans 50 000 lignes de code C que dans des scripts shell pas safe.

        Et ces scripts shell, ils reposent sur quoi ?

        • [^] # Re: Excusez moi mais…

          Posté par  . Évalué à 3.

          Sur dash (sous debian), qui ne prend (que) 12290 lignes de C (selon sloccount).

          ----> []

          • [^] # Re: Excusez moi mais…

            Posté par  (site web personnel) . Évalué à 4.

            Ça c’est pour le shell. Or là on reproche au bousin de remplacer :

            init, cron, at, inet, ConsoleKit, sethostname, modprobe, mount -a, and probably others

            Donc faudrait voir à ajouter les lignes de chacun de ces composants également.

    • [^] # Re: Excusez moi mais…

      Posté par  . Évalué à 10.

      dont la grammaire fairait tomber en syncope un grammairien français

      Boum.

    • [^] # Re: Excusez moi mais…

      Posté par  (site web personnel) . Évalué à 5.

      Que ça soit Archlinux ou FreeBSD, je trouve que le systéme de boot est un pur amas de hacks.

      Pas du tout, c'est un système bien documenté, facile à utiliser et à étendre, au comportement prévisible. Justifie un peu ton affirmation.

      Déjà, les scripts sont écrits dans un langage non typé, dont la grammaire fairait tomber en syncope un grammairien français (c'est dire !), et dont la sémantique est tout sauf simplement définie.

      Je vois, tu voudrais donc que le programme d'initialisation soit écrit dans un langage fonctionnel pur (les seuls dont la sémantique est facile à définir) fortement typé. Ce n'est pas que ça me déplaîrait, mais je le juge pour le moins irréaliste.

      Bref, un truc écrit dans un langage bloat,

      c'est quoi ta définition de bloat? Le shell est lent, arachaïque, mais certainement pas bloat!

      pas safe,

      Quel est ton exemple de programme shell dont la sémantique n'est pas définie?

      avec de la duplication de code

      Rigoureusement interdite dans d'autres langages! Cf. man rc.subr(8).

      • [^] # Re: Excusez moi mais…

        Posté par  . Évalué à 0.

        Bien documenté, j'aimerais bien voir la doc… Bien commenté certes, mais c'est la moindre des choses. POurquoi c'est un hack ? Incapable de s'éxécuter de manière efficace sur un processeur moderne avec SMP. Incapable de gérer les processus de manière moderne sous linux (crgoups, et compagnie). MAnque de souplesse au niveau de la gestion des niveaux d'éxécution. Impossible de modifier le processus de boot (enlever/ajouter des opérations) sans modifier un script shell monolithique.

        Sans aller jusqu'a un langage fonctionnel, il y a des langages simples avec une grammaire qui tient en 20 lignes : cf lua

        Software bloat is a process whereby successive versions of a computer program include an increasing proportion of unnecessary features that are not used by end users

        man bash
        
        

        je doute qu'on ai réellement besoin d'utiliser ${!prefix@} dans un init.

        Quel est ton exemple de programme shell dont la sémantique n'est pas définie?

        sans aller vers une sémantique non définie, le shell demande des précautions infinies d'échapements et de gestion de l'environnement pour s'éxécuter dans un environnement confiné en lisant des paramètres en shell quelque part…

        Cf. man rc.subr(8)

        je ne parle pas de ce code là. Je parle des scripts de lancement de daemons dans rc.d (c'est pire sous archlinux que sous FreeBSD là)

        • [^] # Commentaire supprimé

          Posté par  . Évalué à 2.

          Ce commentaire a été supprimé par l’équipe de modération.

          • [^] # Re: Excusez moi mais…

            Posté par  . Évalué à 2.

            Je suis d'accord que la doc sous FreeBSD est pas mal, mais sous linux, c'est loin d'être le cas, et comme tu peux le remarquer, je ne parlais pas de freeBSD en particulier.

            J'ai l'impression que & existe depuis la nuit des temps.

            j'ai l'impression que tu n'as pas compris le problème, parce que & ne permet pas de faire simplement des choses de manière asynchrones. D'ailleurs, tu peux lire les scripts, tu verras qu'il n'est pas utilisé souvent.

            Les cgroups cela se gère aussi facilement qu'un

            manque de pôt, c'est peut être facile, mais ce n'est pas fait. D'ailleurs, ce n'est pas aussi simple que ce que tu veux le faire croire. Si par exemple tu décides de lancer ttout les daemons réseaux dans un cgroup particulier tu aimerais bien que l'init le gére pour toi.

            De quels niveaux parles-tu ?

            J'en connais pas beaucoup… Les niveaux traditionnels sont "single user, stop, multi-user,etc" mais ça suffit pas. Souvent tu aimerais bien avoir des niveaux comme "connecté à internet, connecté localement, synchronisation, maintenance, whatever you want to do"

            J'aimerais bien avoir un init qui permet de gérer ça simplement sans avoir à bricoler mes scripts par dessus.

            Généralement, je fais ça en ajoutant/supprimant des liens symboliques à l'aide d'un outil très simple ou via un fichier de config. très simple.

            Encore une fois, c'est vrai pour FreeBSD dont l'init est très bien fait, parce qu'il fonctionne uniquement avec des scripts rc, mais pas pour tout les init BSD like. Tiens au passage, je me permet de faire remarquer que c'est exactement le fonctionnement de systemd.

            • [^] # Commentaire supprimé

              Posté par  . Évalué à 2.

              Ce commentaire a été supprimé par l’équipe de modération.

              • [^] # Re: Excusez moi mais…

                Posté par  . Évalué à 2.

                Tiens c'est nouveau, Ubuntu, Debian, RedHatn et les autres utilisent plu sdes init SystemV…

        • [^] # Re: Excusez moi mais…

          Posté par  (site web personnel) . Évalué à 2.

          Je viens de voir que tu parlais à la fois de FreeBSD et de Linux Arch. Je répondais pour FreeBSD, que visiblement tu ne connais pas du tout car aucun de tes arguments ne tient sauf peut-être à la rigueur celui sur les cgroups (mais vu que je ne sais pas ce que c'est, je ne peux pas te dire!).

          Bien documenté, j'aimerais bien voir la doc…

          Pas de problème, d'autes ont déjà répondu et j'avais déjà donné rc.subr avant que tu n'en parles.

          Manque de souplesse au niveau de la gestion des niveaux d'éxécution.

          N'existent pas dans FreeBSD.

          Impossible de modifier le processus de boot (enlever/ajouter des opérations) sans modifier un script shell monolithique.

          L'init de FreeBSD n'est pas monolithique. (man rc.d)

          man bash

          Le shell de FreeBSD est sh, pas bash.

          sans aller vers une sémantique non définie,

          C'est pourtant ce dont tu parlais.

          le shell demande des précautions infinies d'échapements et de gestion de l'environnement pour s'éxécuter dans un environnement confiné en lisant des paramètres en shell quelque part…

          Là tu manques trop de clarté pour que je puisse essayer de te répondre. Si tu as des problèmes d'échappement, c'est juste que tu ne sais pas bien programmer en shell! (P.ex. tu utilises echo alors qu'il faudrait utiliser printf.)

          Sans aller jusqu'a un langage fonctionnel, il y a des langages simples avec une grammaire qui tient en 20 lignes : cf lua

          Ça m'étonnerait que la grammaire du shell soit bien plus compliquée que celle de LUA! Dans le shell il y a les déclarations de fonctions, trois mots-clefs et demi (if, then, else, fi, for, while, do, done, case, esac et local, ce qui correspond au bloc stat dans la BNF de LUA). Les opérateurs de groupement {, } (. ) et |, les redirections < >, les ||, &&, le &, les règles de quote et de substitiution des variables. On doit arriver à un texte sensiblement de la même longueur.

          je ne parle pas de ce code là.

          Tu ne parles pas que de ce code là mais aussi de ce code là, car tu as écrit:

          Que ça soit Archlinux ou FreeBSD, je trouve que le systéme de boot est un pur amas de hacks.

          • [^] # Re: Excusez moi mais…

            Posté par  . Évalué à 2.

            Je connais bien FreeBSD ne t'en déplaise, enfin, surtout Dragonfly, mais je répondais surtout sur Arch, parce qu'en effet la majorité des arguments ne tiennent pas. Surtout pas le cgroups, parce qu'ils n'existent pas.
            Enfin, il y a les jails, mais c'est pas tout à fait pareil, c'est plus l'équivalent de LXC.

            Pas de problème, d'autes ont déjà répondu et j'avais déjà donné rc.subr avant que tu n'en parles.

            j'ai déjà répondu aussi.

            N'existent pas dans FreeBSD.

            Grande nouvelle, il n'y en a juste moins que dans system V.

            Le shell de FreeBSD est sh, pas bash.

            Perdu aussi, du moins si tu considères que sh est bourne shell. /bin/sh est juste un shell compatible posix shell. Même s'il y a beaucoup moins d'extensions que bash, il y en a.

            C'est pourtant ce dont tu parlais.

            Bon, puisque tu veux à tout pris un exemple, je ne pense pas qu'il soit spécifié quand est réalisée l’expansion dans des expressions complexes comme if.

            Là tu manques trop de clarté pour que je puisse essayer de te répondre. Si tu as des problèmes d'échappement, c'est juste que tu ne sais pas bien programmer en shell! (P.ex. tu utilises echo alors qu'il faudrait utiliser printf.)

            Redéfinition des fonctions/variables sans que ça râle, possibilité de changer les options du shell, j'en passe, ça demande plus de précautions pour coder

            Sinon la grammaire du bourne shell doit être équivalente, la grammaire de bash au moins 3 fois plus longue.

  • # Si tu reboot une fois par an ça va !

    Posté par  . Évalué à 4.

    Tous les scripts présent dans /etc/rc.d/ seront exécutés. C'est le script lui même qui détermine s'il doit faire quelque chose.

    Totalement sous-optimal tu va lancer un sous-shell juste pour développer sshd_enable="NO" et faire un test.

    Bon pour un serveur qui reboot tout les 36 du mois ça va, pour un desktop l'optimisation du boot reste cruciale.

    • [^] # Re: Si tu reboot une fois par an ça va !

      Posté par  (site web personnel) . Évalué à 4.

      Totalement sous-optimal tu va lancer un sous-shell juste pour développer sshd_enable="NO" et faire un test.

      Il ne sont pas éxécutés comme dans „éxécuter un programme“ ils sont éxécutés comme dans „éxécuter des instructions“: les fichiers sont sourcés (avec le .).

    • [^] # Re: Si tu reboot une fois par an ça va !

      Posté par  . Évalué à 3.

      Non, je bosse lorsque mon desktop est démarré. Je le démarre 1 fois par jour. S'il met 3 minutes à démarrer, j'en profite pour dire bonjour à mes collègues, me préparer un café etc …

      Non, la vitesse de démarrage n'est pas OBLIGATOIREMENT un élément crucial d'un desktop.
      Ce qui est crucial, c'est que lorsqu'il me dit "Ok je suis prêt à bosser" ce soit réellement le cas.

      • [^] # Re: Si tu reboot une fois par an ça va !

        Posté par  . Évalué à 7.

        Non, je bosse lorsque mon desktop est démarré. Je le démarre 1 fois par jour. S'il met 3 minutes à démarrer, j'en profite pour dire bonjour à mes collègues, me préparer un café etc …

        Donc tu es le seul cas d'usage qui existe ? Parce qu'il y en a plein pour lesquels avoir un boot rapide est pratique : par exemple, si je prend mon portable pour bosser dans le train, je préfère qu'il démarre vite, c'est du temps de batterie gagné et il n'y a pas de cafetière dans le train. On peut aussi imaginer un admin sys qui démarre ses serveurs en fonction de la demande (pour faire des économies d'énergie), si ça démarre vite, il peut le faire plus facilement.

        « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

    • [^] # Commentaire supprimé

      Posté par  . Évalué à 2.

      Ce commentaire a été supprimé par l’équipe de modération.

      • [^] # Re: Si tu reboot une fois par an ça va !

        Posté par  . Évalué à 2.

        Un SSD améliore très fortement une partie du boot en réglant le problème des IO (au boot on lit plein de petits fichiers), mais les systèmes de boot "à l’ancienne" comme tu dit, en shell posent un autre problème de performance : l'appel dans les scripts à de nombreux programmes externes (grep, sed, cut) met la pression sur les caches des processeurs et fait énormément chuter les performances.

        Je lis plus haut qu'on reproche à systemd d'être un bloatware parce qu'il est capable de remplacer un cron ou un atd, mais l'utilisation de fichiers de configuration et de "helpers" en C plutôt que de faire des scripts 300 lignes qui appellent moult programmes externes pour gérer le choses complexes le rendent systématiquement plus rapide que n'importe-quel système d'init que j'ai croisé.

        • [^] # Commentaire supprimé

          Posté par  . Évalué à 3.

          Ce commentaire a été supprimé par l’équipe de modération.

          • [^] # Re: Si tu reboot une fois par an ça va !

            Posté par  . Évalué à 2. Dernière modification le 31 juillet 2012 à 02:10.

            Ce qui prend le plus de temps c'est le BIOS maintenant.

            Et quant le BIOS/EFI/OpenBoot sera enfin de nouveau rapide ou se re-souciera de la performance du système d'init ?

            Combien de lignes en C (A comparer au shell) pour un non problème ?

            Et grep combien de lignes de C ?

            Si on en arrive à un script complexe à la place d'un truc avec trois fonctions (start/stop/reload) et juste deux appels à start-stop-daemon c'est bien qu'on as un "problème" à résoudre non ?

            La bonne pratique voudrait que tout les trucs plus complexes que le démarrage d'un service simple où l’exécution d'une configuration basique (l'init c'est pas que du lancement de service) soit placé dans un helper externe, peu importe le langage utilisé, mais vu que les systèmes d'init Unix interprètent le shell on s'est vite retrouvé avec par flemmardise du code bien gruik dans /etc/init.d, ici systemd ne fait qu'imposer une bonne pratique qui aurait dû être la norme bien avant son arrivé !

            • [^] # Re: Si tu reboot une fois par an ça va !

              Posté par  . Évalué à 3.

              Et quant le BIOS/EFI/OpenBoot sera enfin de nouveau rapide

              Continue de rêver …

            • [^] # Commentaire supprimé

              Posté par  . Évalué à 2.

              Ce commentaire a été supprimé par l’équipe de modération.

              • [^] # Re: Si tu reboot une fois par an ça va !

                Posté par  (site web personnel) . Évalué à 6.

                Average = 77.8594

                Ben ici Average = 40,7974 pour /etc/rc.d (FreeBSD 9.1)

                Bizarre comme question, vu que grep doit de toutes manières être dispo (systemd ou pas).

                grep ça devrait être dans le noyau, avec le serveur http.

                les pixels au peuple !

                • [^] # Re: Si tu reboot une fois par an ça va !

                  Posté par  . Évalué à 3.

                  Au début de chaque script Debian, il y a, par exemple :

                  #!/bin/sh -e
                  
                  ### BEGIN INIT INFO
                  # Provides:          openvpn
                  # Required-Start:    $network $remote_fs $syslog
                  # Required-Stop:     $network $remote_fs $syslog
                  # Should-Start:      network-manager
                  # Should-Stop:       network-manager
                  # X-Start-Before:    $x-display-manager gdm kdm xdm wdm ldm sdm nodm
                  # X-Interactive:     true
                  # Default-Start:     2 3 4 5
                  # Default-Stop:      0 1 6
                  # Short-Description: Openvpn VPN service
                  # Description: This script will start OpenVPN tunnels as specified
                  #              in /etc/default/openvpn and /etc/openvpn/*.conf
                  ### END INIT INFO
                  
                  # Original version by Robert Leslie
                  # <rob@mars.org>, edited by iwj and cs
                  # Modified for openvpn by Alberto Gonzalez Iniesta <agi@inittab.org>
                  # Modified for restarting / starting / stopping single tunnels by Richard Mueller <mueller@teamix.net>
                  
                  

                  Oui, ça fait 25 lignes. Il en manque 12 pour combler la moyenne …

                  grep ça devrait être dans le noyau, avec le serveur http.

                  Rigole pas trop, hein, y a un moteur d'expression rationnelle dans le noyau bidouillé d'OpenWRT…

                  • [^] # Re: Si tu reboot une fois par an ça va !

                    Posté par  (site web personnel) . Évalué à 3.

                    Rigole pas trop, hein, y a un moteur d'expression rationnelle dans le noyau bidouillé d'OpenWRT…

                    très utile pour du firewalling applicatif. Il existe même des moteurs de regex implémentés en hard dans certaines appliance proprio.

                    • [^] # Re: Si tu reboot une fois par an ça va !

                      Posté par  . Évalué à 3.

                      On peut déjà faire du firewall en espace utilisateur, donc du coup on peut utiliser un parseur natif plutôt que des regex, ça suffit largement pour des pauv' routeur Wifi. Mettre un moteur de regex dans le noyau, c'est vraiment overkill. Pourquoi ne pas y mettre le shell et grep, après tout ?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.