#! /usr/bin/perl
# copyright Thomas Lange 2001-2010, lange@debian.org
# copyright Michael Goetze 2011, mgoetze@mgoetze.net
# map "normal" device notation to grub notation

# TODO: read from stdin if no parameter given

use strict;

use Cwd 'abs_path';

my $grubdevice;
my %map;

my $device=shift;
my $devicemap = `mktemp`;
chomp $devicemap;
my $devbyid = "/dev/disk/by-id";

system("/usr/sbin/grub-mkdevicemap", "-m", "$devicemap") == 0 or die "Could not run grub-mkdevicemap\n";

open (DEVICEMAP,"<$devicemap") || die "Can't open device map $devicemap\n";
while (<DEVICEMAP>) {
  my ($grubdevice,$olddevice) = split;
  $map{$olddevice} = $grubdevice;
}

$device=~ m#^(/dev/(?:[shv]d\D|i2o/hd\D|ida/c\d*d\d*|cciss/c\d*d\d*))p*(\d*)$# || die "Can't match device: $device\n";
my ($disk,$partition) = ($1,$2);

if ($map{$disk}) {
  $grubdevice=$map{$disk};
} else {
    opendir (my $dh, $devbyid) || die "Can't open /dev/disk/by-id\n";
    while (my $diskid = readdir $dh) {
	next if ($diskid =~ /[.].*/);

	$diskid = $devbyid . "/" . $diskid;

	my $shortdev = abs_path($diskid);

	if (($shortdev eq $disk) && $map{$diskid}) {
	    $grubdevice = $map{$diskid};
	    last;
	}
    }
    closedir $dh;

    die "No match in $devicemap for $disk\n" unless $grubdevice;
}

if ($partition) {
  $partition--;
  $grubdevice=~s/\)/,$partition\)/;
}

print "$grubdevice\n";
unlink("$devicemap");
exit 0;
