Linux-Bulgaria.ORG
навигация

 

начало

пощенски списък

архив на групата

семинари ...

документи

как да ...

 

 

Предишно писмо Следващо писмо Предишно по тема Следващо по тема По Дата По тема (thread)

Re: [Lug-bg] Bash gimnastiki


  • Subject: Re: [Lug-bg] Bash gimnastiki
  • From: George Danchev <danchev@xxxxxxxxx>
  • Date: Sat, 24 Oct 2009 20:41:40 +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>

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
Lug-bg mailing list
Lug-bg@xxxxxxxxxxxxxxxxxx
http://linux-bulgaria.org/mailman/listinfo/lug-bg


 

наши приятели

 

линукс за българи
http://linux-bg.org

FSA-BG
http://fsa-bg.org

OpenFest
http://openfest.org

FreeBSD BG
http://bg-freebsd.org

KDE-BG
http://kde.fsa-bg.org/

Gnome-BG
http://gnome.cult.bg/

проект OpenFMI
http://openfmi.net

NetField Forum
http://netField.ludost.net/forum/

 

 

Linux-Bulgaria.ORG

Mailing list messages are © Copyright their authors.