Last active
August 29, 2015 14:19
-
-
Save wyoung/7c94967bb635de48d058 to your computer and use it in GitHub Desktop.
Calculator for fsck combinations, giving the chance of two or more volumes needing to be checked at the same time
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
use warnings FATAL => qw(all); | |
use Getopt::Std; | |
sub commafy { # from perlfaq5, since Number::Format is non-core | |
local $_ = shift; | |
1 while s/^([-+]?\d+)(\d{3})/$1,$2/; | |
return $_; | |
} | |
my $syears = 5; | |
my $freq = 30; | |
my %opts; | |
if (!getopts('vy:f:', \%opts) or @ARGV < 2) { | |
print <<USAGE; | |
usage: $0 [-v] [-y years] [-f frequency] <mounts> | |
This program models a multi-volume Linux computer running ext[234] | |
with the max-mount-counts for each volume set (tune2fs -c) to one of | |
the values passed. Pass four values for a 4-volume system, for | |
example; you must give at least two. The values needn't be unique | |
or sorted, but the program expects them to be positive integers. | |
It works through all of the possibilities given the reboot schedule | |
over the machine's service life, modified by -y and -f, defaulting | |
to $syears years and $freq days between reboots. You may give decimal -f | |
values for multiple reboots per day; e.g. 0.25 for 4 reboots per day. | |
It reports the percentage of reboots that two or more volumes on the | |
system will have to be checked. The point is to help you work out | |
which values to use here which will minimize the chance of a | |
multi-volume fsck on reboot without requiring values that are too | |
high. You will find that if you use prime numbers or /relatively/ | |
prime numbers (http://goo.gl/bQbu5Z) that you will get the lowest | |
chances of a multi-volume fsck. You do not have to pass unique | |
values; you can pass "20 20 20" to see what would happen on a | |
3-volume system with all three set to be checked every 20 mounts. | |
Give -v to get a visual analog of the fsck schedule as output. It | |
shows a . for reboots that don't cause an fsck, * for single-volume | |
fsck reboots, and a list of the passed mount counts that triggered | |
a multi-volume fsck. | |
USAGE | |
exit 1; | |
} | |
my $verbose = $opts{v}; | |
$freq = $opts{f} if exists $opts{f}; | |
$syears = $opts{y} if exists $opts{y}; | |
my $sdays = int($syears * 365.24 + 0.5); | |
my @vals = map { int($_) } @ARGV; | |
my $max = int($sdays / $freq + 0.5); | |
my @buckets; | |
for (my $i = 0; $i <= (@ARGV - 2); ++$i) { $buckets[$i] = 0; } | |
my $prevpctreport = 0; | |
my $start = time; | |
for (my $i = 1; $i <= $max; ++$i) { | |
my @divs = grep { $i % $_ == 0 } @vals; | |
++$buckets[@divs - 2] if @divs >= 2; | |
# Write out a visual analog of the simulation results if -v. | |
if ($verbose) { | |
print '.' if @divs == 0; # no fsck this time | |
print '*' if @divs == 1; # one volume fscks this time | |
print '[', join(',', @divs), ']' if @divs > 1; | |
} | |
} | |
print "\n\n" if $verbose; | |
my $total = 0; | |
print "Results:\n\n"; | |
print " svc years: ", $syears, "\n"; | |
print " frequency: $freq days between reboots\n" if $freq >= 1; | |
print " frequency: ", int(1/$freq+0.5), " reboots / day\n" if $freq < 1; | |
print " reboots: ", commafy($max), "\n"; | |
for (my $i = 2; $i <= @vals; ++$i) { | |
my $mvf = $buckets[$i - 2]; | |
if ($mvf > 0) { | |
my $pct = $mvf / $max * 100.0; | |
printf " $i-volume: $mvf incidents total, %.2f%%\n", $pct; | |
$total += $pct; | |
} | |
else { | |
printf " $i-volume: never happens\n"; | |
} | |
} | |
printf " total: %.1f%% chance of a multi-volume fsck\n\n", $total; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment