#!/usr/bin/perl =head1 NAME blink - blink disks in a disk enclosure =head1 SYNOPSIS B [-n|--on|-f|--off|-t|--toggle] [I|--all|-d|--all-detected|-s|--all-slots] B I I =head1 DESCRIPTION B blinks a device in a harddisk enclosure. If no I is given the blinking be will toggled. If no I is given all detected disks in enclosures will be used. If no I and no I is given all detected harddisks will be off and all empty slots or slots with non-detected harddisks in enclosures will blink. These slots should be safe to remove. =head1 OPTIONS =over 9 =item I What action to do. One of B<-n>, B<--on>, B<-f>, B<--off>, B<-t>, B<--toggle>. Default is B<--toggle>. =item I What slots to perform the action on. One of B<-d>, B<--all>, B<--all-detected>, B<-s>, B<--all-slots>, I. Default is B<--all-detected>. =item I The disk device to blink. Either as I or as I. =item B<--all-detected> =item B<--all> =item B<-d> Select all the detected devices. =item B<--all-slots> =item B<-s> Select all slots in the enclosures. =item B<--on> =item B<-n> Turn the blink on. =item B<--off> =item B<-f> Turn the blink off. =item B<--toggle> =item B<-t> Toggle the blink. =back =head1 EXAMPLE: Blink harddisk /dev/sdf To blink /dev/sdf B =head1 EXAMPLE: Blink all undetected slots It will be safe to remove disk from all the blinking slots as the slots are either empty or not detected. B =head1 EXAMPLE: Turn off blinking of all slots Turn off the blinking. B =head1 EXIT STATUS Always returns true. =head1 REPORTING BUGS Contact Ole Tange . =head1 AUTHOR Copyright (C) 2012 Ole Tange . =head1 LICENSE Copyright (C) 2012 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or at your option any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . =head1 DEPENDENCIES B uses Perl and GNU Parallel. =head1 SEE ALSO B(1), B(1). =cut use Getopt::Long; GetOptions( "n|on" => \$::opt_on, "f|off" => \$::opt_off, "t|toggle" => \$::opt_toggle, "d|all|all-detected|alldetected" => \$::opt_alldetected, "s|all-slots|allslots" => \$::opt_allslots, ); my @more_args = (); if(@ARGV) { for(@ARGV) { s{/dev/}{}g; if(/^md/) { # RAID device. Try to find the matching physical devices my $md = $_; for my $line (grep /^$md :/, `cat /proc/mdstat`) { # md1 : active raid6 sdat[14](S) sdx[13] sds[12](S) sdc[6](S) sdb[0] sdm[9] sdk[7] sdaa[10] sdi[5] sdh[4] while($line =~ s/(\S+)\[//) { push @more_args, $1; } } } } } push @ARGV,@more_args; if(not ($::opt_on or $::opt_off or $::opt_toggle or $::opt_alldetected or $::opt_allslots or @ARGV)) { # Default: # Turn on all # Turn off all-detected $locate = "/sys/class/enclosure/*/*/locate"; on($locate); $locate = "/sys/class/enclosure/*/*/device/enclosure*/locate"; off($locate); exit; } if($::opt_alldetected) { $locate = "/sys/class/enclosure/*/*/device/enclosure*/locate"; } elsif($::opt_allslots) { $locate = "/sys/class/enclosure/*/*/locate"; } else { if($#ARGV == 0) { $dev = shift; } else { local($"=","); $dev = @ARGV ? "{@ARGV}" : "*"; } $locate = "/sys/class/enclosure/*/*/device/block/$dev/../../enclosure*/locate"; } if($::opt_on) { on($locate); } elsif($::opt_off) { off($locate); } else { toggle($locate); } sub on { my $locate = shift; print(q{bash -c 'parallel -j1 echo 1 \\> {} ::: }. $locate."'\n"); system(q{bash -c 'parallel -j1 echo 1 \\> {} ::: }. $locate."'\n"); } sub off { my $locate = shift; print(q{bash -c 'parallel -j1 echo 0 \\> {} ::: }. $locate."'\n"); system(q{bash -c 'parallel -j1 echo 0 \\> {} ::: }. $locate."'\n"); } sub toggle { my $locate = shift; # If the file 'locate' contains 1 it should be put to 0. print(q{bash -c 'parallel -j1 grep -q 1 {} \; echo \$? \\> {} ::: }. $locate."'\n"); system(q{bash -c 'parallel -j1 grep -q 1 {} \; echo \$? \\> {} ::: }. $locate."'\n"); }