tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Notification of RAIDframe failures



> You can put the following script into your crontab at the frequency
> you feel comfortable with.  [...]

Or, if you prefer a short summary for humans, here's a script I wrote
which is designed for that.  It produces one line per configured RF
unit.  Sample output (this comes from a real live system - raid4 and
raid7 are the ones which actually get used in this case):

raid0: L1 /dev/sd0e /dev/sd1e
raid1: L1 /dev/sd0h /dev/sd1h
raid2: L1 /dev/sd2h /dev/sd3h
raid3: L1 /dev/sd4h /dev/sd5h
raid4: L0 /dev/raid1d /dev/raid2d /dev/raid3d
raid5: L1 /dev/sd2e /dev/sd3e
raid6: L1 /dev/sd4e /dev/sd5e
raid7: L0 /dev/raid5d /dev/raid6d

It still requires polling, and for automated error notification it
needs to be wrapped in a "get current status, compare with previous,
gripe on differences" wrapper.  But it may be a useful ingredient,
either as-is or with some hackery.

The strings were written for 4.0.1's raidctl -s output.  They may need
fixing if yours looks different.

/~\ The ASCII                             Mouse
\ / Ribbon Campaign
 X  Against HTML                mouse%rodents-montreal.org@localhost
/ \ Email!           7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B

#! /bin/sh
# Public domain.
sysctl -n hw.disknames |
  tr \  \\n |
  egrep \^raid |
  sort +0.4n |
  while read r
  do
        echo -n $r":"
        raidctl -s $r |
          awk 'BEGIN {
                        in_disks = 0;
                        in_spares = 0;
                        nd = 0;
                        havelevel[""] = 0;
                        delete havelevel[""];
                }
                /^Components:/ { in_disks = 1; next; }
                /^Spares:/ { in_spares = 1; in_disks = 0; next; }
                /^No spares/ { in_spares = 0; in_disks = 0; next; }
                /^Component label for / {
                        in_disks = 0;
                        in_spares = 0;
                        curdisk = substr($4,1,length($4)-1);
                        next;
                }
                /^   RAID Level:/ {
                        raidlevel[curdisk] = $3;
                        havelevel[$3] = 1;
                        next;
                }
                /^Parity status:/ { parstat = $3; next; }
                /^Reconstruction is/ { recon = $3; next; }
                /^Parity Re-write/ { rewrite = $4; next; }
                /^Copyback is/ { cback = $3; next; }
                in_disks || in_spares {
                        d = substr($1,1,length($1)-1);
                        disks[nd] = d;
                        $1 = "";
                        diskstate[d] = substr($0,2,length($0)-1);
                        havestate[diskstate[d]] = 1;
                        nd ++;
                }
                END {
                        nlev = 0;
                        for (x in havelevel) { nlev ++; lev = x; }
                        if (nlev == 1) { printf(" L%s",lev); }
                        for (i=0;i<nd;i++) {
                                d = disks[i];
                                if ((d ~ /^component[0-9]*$/) && (diskstate[d] 
== "failed")) { continue; }
                                printf(" %s",d);
                                if (nlev != 1) printf("(L%s)",raidlevel[d]);
                                if (diskstate[d] == "optimal") {
                                } else if (diskstate[d] == "reconstructing") {
                                        if ("used_spare" in havestate) {
                                                printf("[failed-spared]");
                                        } else {
                                                printf("[recon:%s]",recon);
                                        }
                                } else if (diskstate[d] == "used_spare") {
                                        if ("reconstructing" in havestate) {
                                                printf("[spare:%s]",recon);
                                        } else {
                                                printf("[%s]",diskstate[d]);
                                        }
                                } else {
                                        printf("[%s]",diskstate[d]);
                                }
                        }
                        if ((recon != "100%") && !("reconstructing" in 
havestate)) {
                                printf(" (recon %s)",recon);
                        }
                        if (rewrite != "100%") {
                                printf(" (rewrite %s)",rewrite);
                        }
                        if (cback != "100%") {
                                printf(" (copyback %s)",cback);
                        }
                        if ((parstat != "clean") && !((nd == 2) && ("1" in 
havelevel) && ((disks[0] ~ /^component[0-9]*$/) || (disks[1] ~ 
/^component[0-9]*$/)))) {
                                printf(" (%s parity)",parstat);
                        }
                        printf("\n");
                }'
  done


Home | Main Index | Thread Index | Old Index