Blog O' Matty


Optimizing Perl code (localtime)

This article was posted by Matty on 2005-09-23 20:51:00 -0400 -0400

While updating some Perl code I wrote quite some time back, I came across the following:

my ($sec, $min, $hour, $day, $month, $year, $wd, $day, $dst) = localtime(time); print $year + 1900 . " “;

This code is rather wasteful, especially when the program only needs the year. A much simpler solution is to put the localtime() result into array context, and index into it:

$ year = (localtime)[5] + 1900;
print “$year “;

I am currently reading two Perl books, and it amazes me just how versatile Perl is!

Reattaching to failed devices with Veritas Volume Manager

This article was posted by Matty on 2005-09-21 15:21:00 -0400 -0400

When Veritas loses contact (e.g., if a fiber cable is removed between a server and a storage array) with an active device, Veritas will place the device in the failed state, which will be reported as “failed was: cXtXdX” in the vxdisk(1m) output:

$ vxdisk list

DEVICE TYPE DISK GROUP STATUS
c0t0d0s2 auto:none - - online invalid
c0t1d0s2 auto:none - - online invalid
c1t1d0s2 auto:cdsdisk c1t1d0 oradg online
c1t2d0s2 auto:cdsdisk - - online
c1t3d0s2 auto:cdsdisk - - online
c1t4d0s2 auto:cdsdisk - - online
c1t5d0s2 auto:cdsdisk - - online
c1t6d0s2 auto:cdsdisk - - online
- - c1t2d0 oradg failed was:c1t2d0s2
- - c1t3d0 oradg failed was:c1t3d0s2
- - c1t4d0 oradg failed was:c1t4d0s2
- - c1t5d0 oradg failed was:c1t5d0s2
- - c1t6d0 oradg failed was:c1t6d0s2

When situations like this arise, the vxreattach(1m) utility can be used to reconnect Veritas to lost devices:

$ vxreattach

$ vxdisk list

DEVICE TYPE DISK GROUP STATUS
c0t0d0s2 auto:none - - online invalid
c0t1d0s2 auto:none - - online invalid
c1t1d0s2 auto:cdsdisk c1t1d0 oradg online
c1t2d0s2 auto:cdsdisk c1t2d0 oradg online
c1t3d0s2 auto:cdsdisk c1t3d0 oradg online
c1t4d0s2 auto:cdsdisk c1t4d0 oradg online
c1t5d0s2 auto:cdsdisk c1t5d0 oradg online
c1t6d0s2 auto:cdsdisk c1t6d0 oradg online

Prior to running vxreattach(1m), the problem that caused Veritas to lose contact with the devices should be corrected (e.g., the fiber cable should be reconnected to the server), or vxreattach(1m) should be invoked with the “-c” (check if a reattach is possible) option to see if a reattach is possible. vxreattach(1m) is a cool utility, and should go into every storage adminstrators utility belt.

OpenBSD port FLAVORS

This article was posted by Matty on 2005-09-21 00:04:00 -0400 -0400

The OpenBSD ports tree comes with 1000s of packages in source form, and allows each port to be compiled and installed by executing “make install” in the application port directory (e.g., /usr/ports/net/mtr ) . Since individual ports can be built different ways, OpenBSD provides different “FLAVORS” to control the package build process. To view the FLAVORS offered by a specific port, the make utility can be invoked with the ‘show’ option:

$ cd xmms

$ make show=FLAVORS
no_esd no_vorbis no_mikmod no_mp3

To build a package with a specific FLAVOR, the FLAVOR environment variable can be set prior to building the package:

$ export FLAVOR="no_esd"

$ make install

Now if they only offered 21 flavors of ice cream (as my friend Clay once said)!

Displaying Veritas controller information

This article was posted by Matty on 2005-09-19 22:01:00 -0400 -0400

When utilizing Veritas’s DMP utilities, a controller, enclosure or DMP nodename is required when performing most actions. To list the controllers on a server, the vxdmpadm(1m) utility can be invoked with the “listctlr” option:

$ vxdmpadm listctlr all

CTLR-NAME ENCLR-TYPE STATE ENCLR-NAME
=====================================================
c3 EMC ENABLED EMC0
c2 EMC ENABLED EMC0
c0 Disk ENABLED Disk

The vxdmpadm(1m) utility also has a “getctlr” option to display the physical device path associated with a controller:

$ vxdmpadm getctlr c2

LNAME PNAME
===============
c2 /pci@80,2000/lpfc@1

Perl and greediness

This article was posted by Matty on 2005-09-19 21:49:00 -0400 -0400

When a regular expression uses the ‘*’ wild card operator to match text, the regular expression will attempt to match as much as possible when applying the regular expression. Given the the following Perl code with the regular expression “(Some.*text)":

$ cat test.pl

#!/usr/bin/perl

my $string = "Some chunk of text that has text";

$string =~ /(Some.text)(.)/;`   
print "One: $1nTwo: $2n";

We see that by default Perl will match from the word “Some” to the right-most word “text.":

$ test.pl
One: Some chunk of text that has text Two:

In regular expression parlance, this is considered a “greedy” regular expression since it attempts to match as much as possible. This is not ideal in most situations, and is easily fixed with Perl’s ‘?’ operator:

$ cat test.pl

#!/usr/bin/perl

my $string = "Some chunk of text that has text";

$string =~ /(Some.?text)(.)/;`   
print "One: $1nTwo: $2n";

$ test.pl
One: Some chunk of text Two: that has text

In this example Perl will no longer become greedy when evaluating the expression, and will attempt to match up to the left-most occurence of the string element prefaced by ‘?'. Regular expressions are amazingly cool, but sometimes it feels like witchcraft when developing the right regex incantation to solve complex problems.