Re: [Lug-bg] Bash gimnastiki
- Subject: Re: [Lug-bg] Bash gimnastiki
- From: "Martin Kolev" <martin@xxxxxxxxxx>
- Date: Mon, 26 Oct 2009 09:36:57 +0200
|> Здравейте,
|
|Драсти,
|
|> Искам първо да вметна, че не съм програмист и ползвам 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>
Много Ви благодаря за подробните разяснения.
Реших да ползвам mktemp и в момента всичко си сработва.
Поздрави и лека работа!
Мартин Колев
_______________________________________________
Lug-bg mailing list
Lug-bg@xxxxxxxxxxxxxxxxxx
http://linux-bulgaria.org/mailman/listinfo/lug-bg
|