Reconciling block devices by major number / minor number
Posted 03-30-2012 at 05:20 PM by anomie
Background
I had a task earlier this week to reconcile block devices between two directories. Simple - one can do so by reviewing major number / minor number, and then noting the match. Thus:
... represents a match. (See the 253, and 267 in the fifth and sixth columns, respectively? Column five is the "major number", and column six is the "minor number". Together, those uniquely identify the block device as it is known to the Linux kernel on a particular system.)
For more on the topic of major and minor device numbers, read:
As an anecdotal example, on a system where DM-Multipath is enabled, one will see differently named block devices (with identical major and minor numbers) in the /dev and /dev/mapper directories. (The reason for this is beyond the scope of this essay.)
-------
Problem solution
Anyway, back to my task. I've got two different directories, and I want to match major and minor numbers between block devices in them. And I want a pretty report that tells me block device filenames when matches are located.
Simple problem to solve with just a few device files, but each directory contained hundreds of devices in my case. Enter my old friend Perl:
A couple things to note about this script:
That's it. Save yourself some busywork, and let Perl reconcile block devices for you.
I had a task earlier this week to reconcile block devices between two directories. Simple - one can do so by reviewing major number / minor number, and then noting the match. Thus:
Code:
$ ls -l /dev/oracleasm/disks/ASMDISK2 brw-rw---- 1 oracle dba 253, 267 Mar 21 13:58 /dev/oracleasm/disks/ASMDISK2 $ ls -l /dev/mapper/lun0015p1 brw-rw---- 1 oracle dba 253, 267 Mar 21 13:52 /dev/mapper/lun0015p1
For more on the topic of major and minor device numbers, read:
As an anecdotal example, on a system where DM-Multipath is enabled, one will see differently named block devices (with identical major and minor numbers) in the /dev and /dev/mapper directories. (The reason for this is beyond the scope of this essay.)
-------
Problem solution
Anyway, back to my task. I've got two different directories, and I want to match major and minor numbers between block devices in them. And I want a pretty report that tells me block device filenames when matches are located.
Simple problem to solve with just a few device files, but each directory contained hundreds of devices in my case. Enter my old friend Perl:
Code:
#!/usr/bin/perl # This program takes two directories, looks for block devices in each, # and reconciles major/minor numbers between them. If it finds matches, # it prints the file names and major/minor numbers. use warnings ; use strict ; ################################################################# # Variable assignments ################################################################# my $directory1 = '/dev/oracleasm/disks' ; my $directory2 = '/dev/mapper' ; ################################################################# # Functions ################################################################# sub parse_long_listing { my %result ; foreach (@_) { # Only process block devices next unless (/^b/) ; chomp ; # Long listing is: mode (0), links (1), user (2), group (3), # major (4), minor (5), month (6), day (7), # time (8), filename (9) # my @splitlist = split() ; my $maj_min = $splitlist[4] . $splitlist[5] ; my $filename = $splitlist[9] ; # Quick key check, just to be safe if (exists $result{$maj_min}) { print "** Warning: more than one match for major,minor " ; print "file number $maj_min\n" ; } # Add a hash element, with 'major,minor' number as the key # $result{$maj_min} = $filename ; } return %result ; } ################################################################# # Main logic ################################################################# my @filelist1 = qx[ls -l $directory1] ; my @filelist2 = qx[ls -l $directory2] ; my %hash1 = &parse_long_listing(@filelist1) ; my %hash2 = &parse_long_listing(@filelist2) ; foreach (keys %hash1) { # Print details if we find major,minor number matches # if (exists $hash2{$_}) { print qq[$hash2{$_} $hash1{$_} $_\n] ; } }
- It would be simple to parameterize the directory arguments (rather than using hardcoding).
- Character devices could also be included in the search by changing the loop control line to Code:
next unless (/^[bc]/) ;
That's it. Save yourself some busywork, and let Perl reconcile block devices for you.