5 votes

Linux : Déclenchement d'une alarme en temps réel en cas de manque d'espace disque

Je veux abonner un démon, de type inotify, pour recevoir une notification lorsque l'espace libre sur un système de fichiers donné passe en dessous d'un certain pourcentage. Est-ce possible ?

0 votes

Il n'existe pas d'interface dans les noyaux par défaut pour générer des événements qui font cela. Le mieux que vous puissiez faire est d'interroger un fichier fréquemment.

0 votes

Il pourrait y avoir une nouvelle façon de faire cet événement je mettrai à jour avec une réponse si je peux faire une preuve de concept.

0 votes

Qui fera ce que vous voulez mais vous devrez ajouter un effort supplémentaire de votre part pour que inotify fasse <tout ce que vous voulez> lorsque l'événement se réalise.

4voto

ewwhite Points 193555

Vous pouvez utiliser le Utilitaire de surveillance pour ça. Vous pouvez définir l'intervalle de vérification, mais 60 secondes est la norme pour les sondages.

La configuration pour la surveillance du système de fichiers ressemblera à ceci :

check device root with path /
    if SPACE usage > 80% then alert

check device var with path /var
    if SPACE usage > 80% then alert

1 votes

Merci, mais je cherche une solution qui m'informe de ce problème en temps réel, afin que je puisse prendre des mesures avant que les processus ne rencontrent une condition hors de l'espace. Les solutions d'interrogation/récurrence sont insuffisantes.

0 votes

Vous pouvez réduire l'intervalle d'interrogation. Une meilleure solution à long terme est quelque chose comme OpenNMS, qui a des alertes à seuil croissant qui sont déclenchées par un certain taux d'augmentation par rapport à une limite stricte.

4voto

Matthew Ife Points 22370

Il s'agit d'un mécanisme basé sur les événements. Je ne l'ai pas utilisé pendant de longues périodes et ne peux donc pas garantir sa stabilité.

Cela utilise une API d'appel système très récente appelée fanotify. Vous aurez probablement besoin d'un noyau 2.6.37 ou plus pour l'exécuter (donc EL5 est hors de question, par exemple). Si vous obtenez des plaintes qu'il ne compile pas, c'est probablement que le noyau est trop ancien.

Il compile avec :

gcc -o notifier notifier.c

Le mode de fonctionnement est le suivant:-

./notifier /home/file /dev/shm/monit 10

Les arguments sont les suivants :

  1. Un fichier sur le système de fichiers que vous voulez surveiller.
  2. Un chemin vers un fichier qui sera créé si vous dépassez le seuil (et sera supprimé si vous êtes en dessous).
  3. Un pourcentage d'espace libre qui devrait être disponible pour être sous le seuil.

Ceci va configurer le moniteur. Chaque handle de fichier fermé sur le système de fichiers qui avait un drapeau d'écriture ouvert initie la vérification de l'événement.

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <linux/fanotify.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <fcntl.h>

int main(const int argc, const char **argv) {
    if (argc < 4) {
        fprintf(stderr, "Supply a path to a file on the mountpoint to listen to, a monitor file and a free %% threshold..\n");
        exit(1);
    }

    if (access(argv[1], R_OK) < 0) {
        fprintf(stderr, "Unable to read file: %s\n", strerror(errno));
        exit(1);
    }

    int len, rc;
    unsigned char donestat = 0,  alerted = 0;
        const char *path = argv[1];
    const char *monpath = argv[2];
    int threshold = atoi(argv[3]);
    char buf[4096];
    struct fanotify_event_metadata *fem = NULL;
    int fan_fd = -1;
    uint64_t mask = FAN_CLOSE_WRITE;
    struct statvfs sfs;
    float bfree;

    memset(&sfs, 0, sizeof(sfs));
    unlink(monpath);

    if (threshold <= 0 || threshold >= 100) {
        fprintf(stderr, "Incorrect threshold provided");
        rc = 1;
        goto end;
    }

    fan_fd = fanotify_init(FAN_CLASS_NOTIF, FAN_CLOEXEC);
    if (fan_fd < 0) {
        perror("fanotify_init");
        rc = 1;
        goto end;
    }

    rc = fanotify_mark(fan_fd, FAN_MARK_ADD|FAN_MARK_MOUNT, mask, AT_FDCWD, path);
    if (rc < 0) {
        perror("fanotify_mark");
        rc = 1;
        goto end;
    }

    while ((len = read(fan_fd, buf, sizeof(buf))) > 0) {
        fem = (void *)buf;
        donestat = 0;

        while (FAN_EVENT_OK(fem, len)) {
            if (fem->vers < 2) {
                fprintf(stderr, "fanotify is too old\n");
                goto end;
            }

            if (!donestat) {
                rc = fstatvfs(fem->fd, &sfs);
                if (rc < 0) {
                    perror("fstatvfs");
                    rc = 1;
                    goto end;
                }
                bfree = 100 - (((float)(sfs.f_blocks - ((sfs.f_blocks - sfs.f_bfree))) / (float)(sfs.f_blocks)) * 100);
                if ((bfree < (float)threshold)) {
                    if (!alerted) {
                        creat(monpath, S_IRUSR|S_IWUSR);
                        alerted = 1;
                    }
                }
                else {
                    if (alerted) {
                        unlink(monpath);
                        alerted = 0;
                    }
                }
            }
            donestat = 1;
            close(fem->fd);
            fem = FAN_EVENT_NEXT(fem, len);
        }
    }
    if (len < 0) {
        perror("Read fan_fd");
        rc = 1;
        goto end;
    }

end:
    close(fan_fd);
    exit(rc);
}

À partir de là, vous pouvez utiliser inotify pour surveiller la création/suppression du fichier et connaître le résultat.

Pour le tester, fixez le seuil à une valeur que vous savez dépassée, puis touchez un fichier sur le système de fichiers concerné. Vous devriez obtenir la création de votre fichier de surveillance.

De toute évidence, il est préférable de placer le fichier de surveillance à un endroit qui n'est pas sur le même système de fichiers (/dev/shm est un bon endroit).

0 votes

Merci beaucoup de vous être penché sur la question ! Je vais essayer et faire un rapport...

1 votes

Si cela se déclenche sur l'événement de fermeture du fichier, cela ne permettra pas de détecter un événement où un fichier journal s'agrandit et remplit le disque sans jamais être fermé.

0 votes

@matthew-ife la ligne 76 devrait être bfree = (((float)(sfs.f_bfree) / (float)(sfs.f_blocks)) * 100); Parce que maintenant la fonction est inversée. Par exemple, le fichier est supprimé lorsque l'espace est épuisé et la limite est le % d'utilisation et non le % libre.

1voto

arnabmitra Points 133

Comme il y aura plus de choses que vous voudrez surveiller, vous voudrez peut-être passer un peu de temps à apprendre nagios. Il semble que vous ayez eu un cas où vous avez manqué d'espace, et vous ne voulez pas que cette défaillance particulière se reproduise. Mais les systèmes peuvent tomber en panne de manière inattendue, et tous les services doivent être surveillés.

En cas de besoin, vous pouvez simplement utiliser les plugins. Ils sont faciles à installer, et font ce qu'ils disent (check_disk vérifie l'espace disque). Ils retournent "not 0" en cas d'échec. L'échec peut être un avertissement, critique ou inconnu.

apt-get install nagios-plugins

Ajouter quelque chose comme ceci à la crontab déclenchera $send_error en cas d'échec. Il sera déclenché si > 50% de la partition "/" est utilisée.

send_error="command you want to run on failure"
*/5 * * * *  /usr/lib/nagios/plugins/check_disk -w 50% -c 25% -p / || $send_error

0 votes

Merci, mais je cherche une solution qui m'informe de ce problème en temps réel, afin que je puisse prendre des mesures avant que les processus ne rencontrent une condition hors de l'espace. Les solutions d'interrogation/récurrence sont insuffisantes.

1 votes

Définissez donc un intervalle d'interrogation très court pour les alertes auxquelles vous êtes si attentif. Je suis sûr que vous pouvez surveiller l'espace disque à intervalles d'une seconde sur une seule machine sans aucun problème de performance. Puisque les êtres humains ne peuvent pas réagir beaucoup plus vite que cela de toute façon, la "différence" fastidieuse entre "polling" et "notification" n'est pas pertinente.

1 votes

Cela dit, je suis très sceptique quant au fait que vous ayez vraiment besoin de savoir en une seconde, à moins d'avoir une charge de travail assez inhabituelle. Même dans des situations professionnelles, en surveillant des systèmes critiques/impactant les revenus, je n'ai jamais vu un intervalle de surveillance inférieur à une minute. Dans la vie réelle, cela ne fait tout simplement pas une différence suffisante pour en valoir le coût. Ceci dit, comme je l'ai dit, vous ne surveillez qu'une seule machine, pas 10.000, alors faites-vous plaisir et définissez des seuils d'une seconde dans Nagios ! C'est du gaspillage de tout réécrire soi-même (sauf si vous le faites pour apprendre ou vous amuser bien sûr).

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X