Bugfix -> un chomp de merde et 1 heure de perdue :( Le fichier de conf
authorJulien Lerouge <julien.lerouge@m4x.org>
Fri, 22 Nov 2002 21:20:04 +0000 (21:20 +0000)
committerJulien Lerouge <julien.lerouge@m4x.org>
Fri, 22 Nov 2002 21:20:04 +0000 (21:20 +0000)
    contient une doc sommaire, vous pouvez jouer avec ! Le démon a tourné
    chez moi en route pendant plus de 4 jours sans pbm...

muxdaemon/muxdaemon.conf
muxdaemon/muxdaemon.pl

index e9d73e2..b1c7b84 100644 (file)
@@ -1,31 +1,67 @@
+#Fichier de conf du muxdaemon
+#
+#Ce démon permet de gérer plusieurs programmes clients (comme des parseurs de
+#mail, de log), en les lançant au moment opportun. Il permet de plus de
+#s'affranchir de certains problèmes de sécu, pour les mails notamment, car le
+#programme client peut tourner en n'importe quel utilisateur, les mails lui
+#étant pipés par ce démon (qui par conséquent doit tourner en mode privilégié
+#Le lancement des différents clients se fait selon plusieurs critères :
+#              - charge de la machine
+#              - "réentrance" du client (peut-on en avoir plusieurs instances en cours d'éxécution ?)
+#              - priorité de 1 à 100, le démon essai de lancer le client de
+#                priorité 100 cent fois plus souvent que celui de priorité 1
+#              - temps minium entre deux éxécutions d'un client
+#
+
+#Le fonctionnement du démon est le suivant :
+#toutes les active_poll secondes, le démon filtre la liste des clients de
+#manière à ne conserver que les runnables.  Si la charge est trop élevé pour
+#tous les clients, le démon attand sleep_poll secondes avant de repasser en
+#active_poll.
+#
+
+#Scheduler :
+#Il est ultra basique.Il essaie de respecter les priorités, mais si un programme
+#X de haute priorité est lancé, qu'il dure plus longtemps qu'un client Y de
+#faible priorité, et que la charge et le nombre total de clients autorisés sont
+#tels que Y peut être lancé, alors il l'est. Si le processus se répète, Y
+#peut-être lancé beaucoup plus souvent que X. Mais dès que X est runnable, il
+#est lancé. Les schedule consiste donc à maximiser le nombre de clients en cours
+#d'éxécution, tout en respectant les priorités.
+#
+
+#Pour les boites maildir :
+#actuellement, les fichier sont lus dans le répertoire new/ pipés vers le
+#client, puis déplacés dans cur/
+
+
 #Cette commande doit renvoyer la charge
 ldcmd = "cat /proc/loadavg | sed 's/^\([^ ]* \).*$/\1/'"
 
-#error_log
+#Fichier de log
 error_log = "/home/julien/toto"
 
-#Poll every 60 seconds
-#Active poll : Time to wait between 2 launches in sec
+#Active poll : Temps d'attente entre deux lancements en mode actif
 active_poll = 0
 
 #Time to wait when load is too high for any client in sec
-sleep_poll = 60
+sleep_poll = 10
 
-#Nombre max de client à ne pas dépasser simultanément
-max_client = 1
+#Nombre total de clients à ne pas dépasser simultanément
+max_client = 15
 
 <client erreurs>
        #Charge au dessus de laquelle ce programme ne doit plus être lancé
-       max_load=0.3
+       max_load=0.4
        #Mbox
        #Si mbox existe, des lots de nb_mails y sont lus et pipés dans command
        #si mbox termine par un "/", c'est une boite maildir
-       #Pas encore implémenté
+       #Implémenté pour les boites maildir uniquement
        mbox=/var/mail/xorg-errors/
-       #nombre de mails à traité ((1 command executée par mail)
-       nb_mails=50
-       #Command to launch (datas are piped in it if mbox defined)
-       command="cat"
+       #nombre de mails à traité ((1 commande executée par mail)
+       nb_mails=5
+       #Command to launch (datas are piped in it if maildir mbox defined)
+       command="cat >/dev/null"
        #Peut-on lancer plusieurs instances de ce prog simultanément ? yes or no
        allow_many=no
        #Priority relative aux autres de 1 à 100
@@ -35,31 +71,31 @@ max_client = 1
        #Lancer le prog en tant que :
        run_as_user=julien
        run_as_group=julien
-       #Temps minimum entre deux lancements d'un client en sec
+       #Temps minimum entre deux lancements de ce client en sec
        min_schedule=0
 </client>
 
 
 <client toto>
-       max_load=0.3
+       max_load=0.5
        command="/bin/sleep 1"
-       allow_many=no
+       allow_many=yes
        priority=99
 </client>
 
 <client titi>
-       max_load=0.3
+       max_load=0.5
        command="/bin/sleep 3"
-       allow_many=no
+       allow_many=yes
        priority=57
        run_as_user=jb
        run_as_group=jb
 </client>
 
 <client tutu>
-       max_load=0.3
+       max_load=0.5
        command="/bin/sleep 2"
-       allow_many=no
+       allow_many=yes
        priority=69
 </client>
 
index 875aff0..6d5c4cc 100755 (executable)
@@ -26,7 +26,6 @@ my %uid;
 my %launches;
 my %ratio_launch_prio;
 my %last_schedule;
-my $priority_ref = "";
 
 ###############
 ## Functions ##
@@ -50,10 +49,8 @@ sub read_conf {
 
 
 sub debug_msg(#){
-   my $msg=shift;
-   if ($debug == 1){
-      print STDERR $msg;
-   }
+   my $text=shift;
+   print STDERR $text unless ($debug == 0);
 }
    
 
@@ -99,23 +96,25 @@ sub init {
    }
 
    if ($opts{'d'}){
+      print STDERR "Running in debug mode ...\n";
       $debug = 1;
    }else{
       $debug = 0;
    }
-
 }
 
-sub init_launches(){
-   my $min_priority=100;
+#init useful variables for scheduler
+sub init_sched(){
    foreach my $arg (keys %{$conf{'client'}}){
       $launches{"$arg"}=0;
       $ratio_launch_prio{"$arg"}=0;
+      $last_schedule{"$arg"}=0;
    }
 }
 
-
-sub check_conf(){
+#check configuration file 
+sub check_conf{
+   &debug_msg("Salut\n");
    print STDERR "Checking configuration file for wrong user/groups, schedules, ....\n";
    foreach my $arg (keys %{$conf{'client'}}){
       #La conf du client courant
@@ -145,7 +144,8 @@ sub check_conf(){
    }
 }
 
-   
+
+#make the program run in daemon mode
 sub daemonize {
    print STDERR "Forking ... \n";
    chdir '/' or die "Can't chdir to /: $!";
@@ -159,30 +159,28 @@ sub daemonize {
    defined(my $pid = fork) or die "Can't fork: $!";
    exit if $pid;
    setsid or die "Can't start a new session: $!";
-   umask 0;
+   #umask 0;
    &debug_msg("Daemon started\n");
 }
 
+
+#returns current load or any good value
 sub get_load {
    my $load = `$conf{"ldcmd"}`;
-   chop($load);
-   #&debug_msg("$load\n");
+   chomp($load);
    return $load;
 }
 
 #Return the list of client for which max_load is => ld
+#param : load
 sub get_possible_client(#){
    my $ld=shift;
    my @list=();
-   #&debug_msg("get_possible_client, load = $ld\n");
+   
    foreach my $arg (keys %{$conf{'client'}}){
-      #&debug_msg("get_possible_client : Trying client $arg :");
       my $hash = ${$conf{'client'}}{$arg};
       if (${$hash}{'max_load'} >= $ld){
-        #&debug_msg("max_load = ".${$hash}{'max_load'}." => in\n");
         push(@list,$arg);
-      }else{
-        #&debug_msg("max_load = ".${$hash}{'max_load'}." => out\n");
       }
    }
    return \@list;
@@ -266,34 +264,41 @@ sub change_uid_gid(#){
 
 #Sends mail on the input of the command (pipe)
 sub send_data(#){
-   my $client=shift;
-   if (${${$conf{'client'}}{$client}}{'mbox'} =~ /\/$/){
-      &debug_msg("Sending datas for ${${$conf{'client'}}{$client}}{'mbox'}\n");
-      my @list=`ls -1 ${${$conf{'client'}}{$client}}{'mbox'}/new | head -n ${${$conf{'client'}}{$client}}{'nb_mails'}`;
+   my $client = shift;
+   my $hash = ${$conf{'client'}}{$client};
+   if (${$hash}{'mbox'} =~ /\/$/){ #ok, maildir format
+      my $path = "${$hash}{'mbox'}";
+      $path =~ s/\/$//igo;
+      &debug_msg("Sending datas for ${$hash}{'mbox'}\n");
+      my @list=`ls -1 $path/new | head -n ${$hash}{'nb_mails'}`;
       if ($#list >= 0){
         #Send files, one by one
         foreach my $fich (@list){
+           chomp($fich);
            &debug_msg("File : $fich\n");
            if (my $pid = open(CHILD, "|-")) {
               CHILD->autoflush(1);
-              &debug_msg("Parent Pid $$\n");
-              if (open(DATA,"<${${$conf{'client'}}{$client}}{'mbox'}/new/$fich")){
+              if (open(DATA,"<$path/new/$fich")){
                  while (my $line=<DATA>){
                     print CHILD "$line";
-                    #&debug_msg("Sending : $line");
                  }
                  close(DATA);
+                 &debug_msg("$path/new/$fich -> $path/cur/$fich ... ");
+                 if (rename("$path/new/$fich","$path/cur/$fich")){
+                    &debug_msg("ok\n");
+                 }else{
+                    print STDERR "Error moving $path/new/$fich, keeped : $!\n";
+                 }
               }else{
-                 &debug_msg("Error opening ${${$conf{'client'}}{$client}}{'mbox'}/new/$fich : $!\n");
+                 print STDERR "Error opening $path/new/$fich : $!\n";
                  exit(1);
               }
               close(CHILD);
-              #unlink("${${$conf{'client'}}{$client}}{'mbox'}/new/$fich");
            } else {
               die "cannot fork: $!" unless defined $pid;
               &change_uid_gid("$client");
-              &debug_msg("Executing ${${$conf{'client'}}{$client}}{'command'} .... \n");
-              exec("${${$conf{'client'}}{$client}}{'command'}");
+              &debug_msg("Executing ${$hash}{'command'} .... \n");
+              exec("${$hash}{'command'}");
            }
         }
       }else{
@@ -336,7 +341,7 @@ sub main_loop {
         &debug_msg("done\n");
         &debug_msg("  Restarting                     ...");
         &init;
-        &init_launches;
+        &init_sched;
         &debug_msg("done\n");
       }
         
@@ -409,8 +414,8 @@ sub main_loop {
 
 $SIG{HUP}=\&sigHUP_handler;
 &init();
-&init_launches();
 &check_conf();
+&init_sched();
 &daemonize();
 &main_loop();