> Здравейте, Драсти, > Искам първо да вметна, че не съм програмист и ползвам BASH от дъжд на > вятър, т.е. пълен лаик. > > Ето и какво ме накара да пиша тук: > Реших с помощта на rrdtool да чертая графика на прихванатите вируси от > антивирусната ми програма. За целта си направих един "прост" BASH скрипт, > който се изпълнява с помощта на procmail, когато се прихване вирус от > антивирусната програма, като целта му е да увеличава с единица стойността > на едно число - индекс: > > > #!/bin/bash > > virusvar=`/bin/cat /etc/rrdtool/mail/virus-count` > ((virusvar++)) > /bin/echo -n $virusvar > /etc/rrdtool/virus/virus-count > > > > Всичко си сработва много добре, но когато сървъра се натовари (т.к. си е > бая стар и е с много малко RAM памет) поредността на числото, което се > записва във virus-count се обърква. Прави ми впечатление, че това се > случва в момент, когато е натоварен и четенето/писането от и във > virus-count става в почти един и същи момент. > > Много съм любопитен да разбера защо се случва това?
Накратко, както обяси и Пенчев, твоя скрипт не е reentrant, т.е. не е здравословно за се влиза в него докато предното му изпълнение не е приключило защото има споделен ресурс, т.е. файла и цялата операция става неопределена. Ето ти още две решения: 1) брутално: procmail вика mktemp който създава празни файлове с уникални имена в дадена директория и ти ги бройкаш от време на време - нямам споделен ресурс, няма да хаби дисково пространство, и едва ли ше удариш лимита по брой файлове на файловата система ;-) 2) чрез signal handlers (фнимателно със signal handlers, да са много леки) http://www.gnu.org/software/libc/manual/html_node/Nonreentrancy.html#Nonreentrancy компилираш следната програмка: #include <stdio.h> #include <stdlib.h> #include <signal.h> /* This variable is set by the SIGALRM signal handler. */ volatile sig_atomic_t flag = 0; /* Ugly global counter */ volatile long c = 0; void print_event() { fprintf(stdout, "%ld\n", c); }; void register_event() { ++c; }; int main (void) { signal(SIGALRM, register_event); signal(SIGUSR1, print_event); sigset_t block_alarm; /* Initialize the signal mask. */ sigemptyset (&block_alarm); sigaddset (&block_alarm, SIGALRM); while (1) { /* Check if a signal has arrived; if so, reset the flag. */ sigprocmask (SIG_BLOCK, &block_alarm, NULL); if (flag) flag = 0; sigprocmask (SIG_UNBLOCK, &block_alarm, NULL); } } Казваш на procmail да й праща SIGALRM с kill -s когато дойде вирус (това е доста по-бързо от отваряне и писане във файл;-), а ти можеш да я тестваш за дуракоустойчивост така, ако приемем, че се казва a.out: пращаш бройка сигнали (все едно пратени от procmail): for a in `seq 1 100`; do kill -s SIGALRM `pidof a.out`; done питаш я колко са получени: kill -s SIGUSR1 `pidof a.out` (трябва да е стартирана разбира се и пише на stdout) -- pub 4096R/0E4BD0AB <people.fccf.net/danchev/key pgp.mit.edu>
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Lug-bg mailing list [email protected] http://linux-bulgaria.org/mailman/listinfo/lug-bg
