877.503.9800
Contact Us

 

Jan
25
2012

Renumbering device instances

With really large disk arrays, you can find instance numbers piling up very quickly, and worse, they can make path managers such as DynaPath, Power Path and Secure Path exceed their limits. This is especially true if you are deleting and re-adding devices. Fortunately, there is a relatively easy way to accomplish this task.

 

Instance numbers are simply an index or ID within the driver for that device. The driver creates an instance number for each hardware path where the device is found, for instance disks or LUNs. If there are 10 disks, then the instance numbers will start at 0 and increment as each new disk is discovered. Depending on the version and patches for HP-UX, missing numbers or gaps can start showing up. The good news is that the instances for a specific device type (disk, tape, lan, ext_bus, etc) can be renumbered with the only restriction that there can be no duplicates for a given device class. Note that for disks, the legacy names (called CTD names) use the “c” portion of the name to correspond to the ext_bus number.

 

It turns out that the instance number is only used by the driver and insf, and reported by ioscan. Therefore, you can edit the list of instance numbers and change them to different values, as long as there are no duplicates for a given device type. Here is the command to generate an ioinit listing:

 

# ioscan -f | \

grep -e INTERFACE -e DEVICE | \

grep -v target | \

awk ‘{print $3, $1, $2}’ > /infile

 

The output look like this:

 

0/0/0/0 lan 0

0/0/1/0 ext_bus 0

0/0/1/0.7.0 ctl 3

0/0/1/1 ext_bus 1

0/0/1/1.0.0 disk 0

0/0/1/1.2.0 disk 1

0/0/1/1.7.0 ctl 0

0/0/2/0 ext_bus 2

0/0/2/0.0.0 disk 28

0/0/2/0.2.0 disk 2

0/0/2/0.7.0 ctl 1

0/0/2/1 ext_bus 3

0/0/2/1.2.0 disk 3

0/0/2/1.7.0 ctl 2

 

 

So the fields are: hardware path, device class name and instance. To isolate all the disks:

 

# grep disk /infile

0/0/1/1.0.0 disk 0

0/0/1/1.2.0 disk 1

0/0/2/0.0.0 disk 28

0/0/2/0.2.0 disk 2

0/0/2/1.2.0 disk 3

 

And as you can see, disk 28 is out of sequence. You must retain the entire file and just edit the disk lines.

nes renumbered:

 

# grep disk /infile

0/0/1/1.0.0 disk 0

0/0/1/1.2.0 disk 1

0/0/2/0.0.0 disk 2

0/0/2/0.2.0 disk 3

0/0/2/1.2.0 disk 4

 

Important: the file (infile) must be stored in / or /etc as it may be needed when no filesystems are mounted.

To apply these changes (requires a reboot), use ioinit like this:

 

# /sbin/ioinit -f /infile -r

 

Ignore the lines which state that “Input is identical to kernel”. The system will reboot and instance numbers reported by ioscan will be the new values. NOTE: changing disk instance numbers will not change the device file connections so existing LUNS and volume groups should remain unaffected.

 

If you have problems with the ioinit command reporting errors, you can use the two step approach. The first step is to rename the current ioconfig files (there are two: /stand/ioconfig and /etc/ioconfig) to something like ioconfig.sav and reboot:

 

# mv /stand/ioconfig /stand/ioconfig.sav

# mv /etc/ioconfig /etc/ioconfig.sav

# shutdown -ry 0

 

and the system will automatically stop after booting part way up at the ioinitrc stage. Type the two commands:

 

(in ioinitrc)# /sbin/ioinit -c

(in ioinitrc)# /sbin/ioinit -f /infile -r

 

The -c option initializes the ioconfig file and will remove any conflicts or problems when running the ioinit command previously. Then the new infile is merged into the ioconfig file and the system reboots. Note that this applies to HP-UX 11.23 and earlier. For 11.31, there are online procedures to renumber instances.

Jan
25
2012

GZIP/GUNZIP with no extra storage

When you gzip (or compress) a file, the original plus the compressed copy will exist in the same filesystem until the compression is complete. Then the old file is removed, leaving the compressed version. The worst case for an uncompressible file is that twice the amount of space will be needed temporarily. For very large files such as a tar file of multiple directories and files will not be compressible in the current filesystem. From the man pages for gzip and compress, you will see that the target file is optional — which means that the program is also a filter and can be used with pipes and redirection. So the resultant gzipped (or gunzipped) file can be in another filesystem. Here is an example:

 

cat myBigFile | gzip >/var/tmp/mySmallerFile.gz

or

gzip < mtBigFile > /var/tmp/mySmallerFile.gz

 

Both examples take stdin, compress the stream of data and write the result to stdout. No additional disk storage is required as all conversion takes place in the stream through memory.

 

Another use of streaming gzip is copying a large directory using tar or fbackup, compressing the result and sending it over the network to another system. Here’s an example:

 

 

Breaking down each section, the tar output (-f) is missing which means stdout is the output and that is piped to gzip. From gzip, stdout is then piped to ssh (could also be remsh or rexec) where cat is used to read the stdin sent to ssh and stdout becomes the remote file. The remote file is named .tgz signifying a tar file that has been gzipped.

 

    cd /mydata

tar -cv * | gzip | ssh cat > /var/tmp/mydata.tgz

 

Assuming that the directories and files are compressible, the transfer over the network will be much quicker than with the uncompressed data.

Jan
25
2012

Say Yes? Say No? Say what?

Anyone who has written an interactive script has had to ask a yes or no question. And then script gets changed to handle UPPERCASE and lowercase. And modified again to check for just 1 letter such as y or n… And pretty soon, the code looks fairly convoluted. Here’s a simple way to handle all 3 conditions (yes, no and other):

# Ask question:

echo “Is this correct (y/n)? \c”

read ANSWER
case ANSWER in

[Yy] | [Yy][Ee][Ss] )    echo “ANS is yes”

                ;;

[Nn] | [Nn][Oo] )     echo “Ans is no”

                ;;

            * )    echo “ANS is not yes or no”

                ;;

esac

 

So the code recognizes single letters y/n or Y/N, as well as the full word.

Now, the opposite of asking the yes or no question is to supply the answer. What? How do you automatically answer a question? The answer is yes. That’s right. yes is the answer. Check out: man yes This is a program to endlessly supply “y” or any string you need to give to a program that runs in cron or batch mode and there is no one to answer the question. The yes program runs forever (ctrl-c to terminate):

yes | head -3

y

y

y

 

yes no | head -3

no

no

no

 

An example for batch usage is fbackup. If fbackup encounters an error condition, it will hang forever waiting for the answer (do you want to continue, do you want to save…). Since the backup is unattended, answering no is very useful. So here is the technique:

yes no | fbackup -f /dev/rmt/0mm -i /

In this case, when fbackup encounters an error, all questions will be answered with “no“.

Jan
14
2012

Forcing Speed and Duplex of on-board network interface e1000g on T2000, T5120, and T5220 with ndd

By default the e1000g network interface is set to auto-negotiation enabled, 1Gbps full-duplex.

# ndd -set /dev/e1000g<instance> adv_autoneg_cap 0
# ndd -set /dev/e1000g<instance> force_speed_duplex <value>

Value

Setting Result

1

10Mb/s, half-duplex

2

10Mb/s, full-duplex

3

100Mb/s, half-duplex

4

100Mb/s, full-duplex

I found this while reading the hardware platform guide for T5120. “force_speed_duplex” is not available for other types of network interfaces.

Dec
16
2011

Mounting an ISO image in HP-UX

Some applications are supplying ISO images rather than actual CDs or DVDs for installation. An example is Data Protector from HP.

If this image is burned on a PC to a CD or DVD, the CD software may
translate the image into Joliet or otherwise modify the image. The
resultant CD/DVD will have filename problems on HP-UX such as 8.3 names
with duplicate names given numbers: README_NOW.txt becomes rea_0004.txt

You can try various mount options on HP-UX:

-F cdfs
-o rr
-o rr,ro

to see if the names are proper. Otherwise, try using options in the PC
application to prevent image translation. The ISO should be ISO-9660 with
RockRidge Extensions. It may also be known as POSIX filenames.

(public)     If burning the CD/DVD with different settings and trying different mount
options does not work, this should work:

1. Copy the ISO image in binary to the HP-UX system (need up to 700MB free
to hold the ISO image).

2. lvcreate -n isoimage -L 750 /dev/vgWHATEVER (for CD)
lvcreate -n isoimage -L 2500 /dev/vgWHATEVER (for DVD)

3. dd if=/var/tmp/isofile of=/dev/vg00/risoimage bs=1024k

4. mount /dev/vgWHATEVER/isoimage /cdrom

That should do it. The downside is that you need the space for the ISO
image and the same amount for the mounted image.

Nov
30
2011

LAN speed test with no disk I/O

Q: I need a way to test LAN performance but I don’t want disk I/O to slow things down.

A: ftp can be used to exercise a network, probably the fastest handshake method without specialized programs. Here is a little known technique: Use the put command with dd and send the file to /dev/null on the remote end.

# ftp remoteSystemName
    (user, password)
    binary
    put “| dd if=/dev/zero bs=32k count=10000″ /dev/null
    bye

What this code performs is to create a data stream using dd, then send the stream of zeros to the remote file /dev/null. This works between Unix systems where /dev/null is the bit bucket.

Nov
30
2011

Using Julian days for calendar calculations

Q: I need to determine days between arbitrary dates. I’ve seen epoch seconds as a possible way but this is limited 1970 through 2038 and converting between MDY forms and epoch seconds is fairly tricky.

A: If all you need are the number of days, the simple way is to use the Julian calendar. Note that Julian term is often confused with day of the year (1-365) but in astronomy, the Julian calendar starts Jan 1, 4713 BC. The definition of the calendar includes fractional values to indicate time of day, but for your requirement, just the integer value (days) is sufficient.

Here’s a calculator from the US Naval Observatory with a background on how to convert between Gregorian calendars and Julian calendars.

http://www.usno.navy.mil/USNO/astronomical-applications/data-services/cal-to-jd-conv

But for your requirement, there is a math procedure to convert in either direction. Here is a reference to the actual math:

http://pmyers.pcug.org.au/General/JulianDates.htm#G2J

But the two functions listed below will accomplish the math for you. They both assume the US calendar date format: MM DD YYYY. Jdate accepts a 3 character month name (Jan-Dec, upper or lower or mixed case) and Jmdy has an option (-m) to display the month name rather than the number.

Jdate is useful in decoding dates (like syslog.log) which are typically in this format:

Nov 30 08:59:09

So to determine the days between two dates:

J1=$(Jdate Nov 30 2011)
J2=$(Jdate Dec 26 2010)
DAYS=$(($J1 – $J2))
or
DAYS=$(($(Jdate Nov 30 2011) – $(Jdate Dec 26 2010)))

(ans: 339)

Here are the two routines. You can paste them into your scripts or use them from a function library by exporting FPPATH=/yourFunctionDirectory

 

 

###########

# Jdate #

###########

 

 

function Jdate

{

# Usage: Jdate <month_name> <day> <yearYYYY>

# where month is the 3-char month name or 1-12 month number,

# day and year are integers, year is 4 digits.

 

# Calculate Julian day from MONTH_NAME DAY YEARYYYY

# It is the number of days since 4713 BC

# The Julian date is the ideal way to compute day differences given calendar dates

# The exact Julian day technically starts at 0.5 Universal Time (noon)

# but this calculation is all integers and computes from 0.0 UT.

 

# See http://www.usno.navy.mil/USNO/astronomical-applications/data-services/cal-to-jd-conv

 

set -u

TRACEME=${TRACEME:-false} # TRACEME non-null = trace on

[ $TRACEME != false ] && set -x && PS4=’[$LINENO]: ‘

 

MONRAW=$1

DAY=$2

YEAR=$3

 

# Convert month to number

# To allow for UPPER or MiXeD case, store in lowercase

# ZerO is a placeholder for the zero-th array element so

# that jan is element 1 in the array.

 

if [[ $(print -n "$MONRAW" | tr -d "[[:digit:]]” | wc -c) -ne 0 ]]

then

typeset -l MONTHNAME=$1 # convert month name to lowercase

set -A MON ZerO jan feb mar apr may jun jul aug sep oct nov dec

MONTH=1

while [[ $MONTH -le 12 ]]

do

[[ "$MONTHNAME" = "${MON[$MONTH]}” ]] && break

MONTH=$(($MONTH+1))

done

else

MONTH=$1

fi

 

# If we get here with MONTH=13, then the month name was not found

# or the month number was not 1-12

 

if [[ $MONTH -gt 12 || $MONTH -lt 1 ]]

then

echo “Month: \”$MONRAW\” not valid”

exit 1

fi

 

# perform conversion

######################################################

 

if [[ $MONTH -gt 2 ]] ; then

MONTH=$(($MONTH – 3))

else

MONTH=$(($MONTH + 9))

YEAR=$(($YEAR – 1))

fi

CENTURY=$(($YEAR / 100))

CENT2=$(($YEAR % 100))

JULIAN=$(((146097 * $CENTURY) / 4 \

+ (1461 * $CENT2) / 4 \

+ (153 * $MONTH + 2) / 5 \

+ $DAY + 1721119))

echo $JULIAN

return

}

 

##########

# Jmdy #

##########

 

function Jmdy

{

 

# Usage: Jmdy [-m] <Julian day number>

 

# where -m will return 3-char Month Name, otherwise month=1-12

# JulianDayNumber to be converted to Month Day Year

 

# Calculate MONTH_NAME DAY YEARYYYY from JulianDayNumber

 

# JulianDayNumber is the number of days since 4713 BC

# This is the ideal way to compute date differences given calendar dates

# The exact Julian day technically starts at 0.5 Universal Time (noon)

# but this calculation is all integers and computes from 0.0 UT.

 

# See http://www.usno.navy.mil/USNO/astronomical-applications/data-services/cal-to-jd-conv

 

set -u

TRACEME=${TRACEME:-false} # TRACEME non-null = trace on

[ $TRACEME != false ] && set -x && PS4=’[$LINENO]: ‘

 

set -A MONTH3 ZerO Jan Feb Mar Apr May Jun Jul Aug Sep Oce Nov Dec

 

MONTHNAME=false

while getopts “:m” OPTCHR

do

case $OPTCHR in

m) MONTHNAME=true

;;

*) eval “ERROPT=\$$(($OPTIND-1))”

echo “function Jmdy invalid option: $ERROPT”

return 1

;;

esac

done

shift $(($OPTIND -1))

 

 

# Do all the calculations – all integer math

 

JULIANDATE=$1

JULIANDATE=$((JULIANDATE – 1721119))

YEAR=$(((4 * JULIANDATE – 1) / 146097))

JULIANDATE=$((4 * JULIANDATE – 1 – 146097 * YEAR))

DAY=$((JULIANDATE / 4))

JULIANDATE=$(((4 * DAY + 3) / 1461))

DAY=$((4 * DAY + 3 – 1461 * JULIANDATE))

DAY=$(((DAY + 4) / 4))

MONTH=$(((5 * DAY – 3) / 153))

DAY=$((5 * DAY – 3 – 153 * MONTH))

DAY=$(((DAY + 5) / 5))

YEAR=$((100 * YEAR + JULIANDATE))

if [[ $MONTH -lt 10 ]]

then

MONTH=$((MONTH + 3))

else

MONTH=$((MONTH – 9))

YEAR=$((YEAR + 1))

fi

 

[[ "$MONTHNAME" = "true" ]] && MONTH=${MONTH3[$MONTH]}

echo “$MONTH $DAY, $YEAR”

return

}

Nov
30
2011

Extracting products from a large depot

 

When working with large, multi-product depots such as the Internet Express collection, it is often desirable to extract a single product or small group of products to create a small depot. The technique is quite simple. Here are two examples:

# swcopy -x enforce_dependencies=false -s /var/tmp/iExpress-1of3 ProFTPD @ /tmp/prod1

# swcopy -x enforce_dependencies=false -s /var/tmp/iExpress-1of3 Sudo Tripwire @ /tmp/prod2

 

In each case, the source (-s) is the Internet Express CD or a copy on disk. The name of the product (or products) is given and the @ directive points to a directory where the new depot is to be created. If the directory does not exist, it will be created. If it already contains a depot setup, the new products(s) will be added. You can check the result with:

# swlist -l product -s /tmp/prod1

# Initializing…

# Contacting target “atl1″…

#

# Target: atl1:/tmp/prod3

#

 

ProFTPD A.10.00-1.3.1 FTP Server

Wireshark A.10.00-0.99.6 Protocol Analyzer

 

…which shows the products in the depot directory. swcopy automatically registers the depot so it can be used by any HP-UX server on the network. To copy the depot to another system, just use tar to save the depot directory and untar it at the destination.

Oct
25
2011

Problem with filenames

I am getting: PuTTYPuTTY everytime I list a particular directory with ls or ll. It does not happen in any other directory and I can’t see anything unusual in the directory so what is the problem?

For most terminal emulators, there is an AnswerBack feature, something that was implemented more than 40 years ago during the days of teletypewriters (Teletypes and other hardcopy communication machines). The ASCII character \005 or 0×05 is called the ENQ character and does not show on the screen or paper. Instead, when received, it triggers a response from the terminal to identify itself, to “Answer Back”. Most modern hardware terminals will answer with their model number such as vt100 or hp2392a, but for emulators, they can be programmed for any string. For the PuTTY terminal emulator, the default is “PuTTY“.

So the problem is being triggered by the text sent back by HP-UX, namely, the filenames. Normally, this requires a lot of trial and error to locate but there is a little known but very useful option for ls: the -b option to list non-printing characters. By using -b with ls, you will see the non-printing characters in their octal form:

ls -b
file1 file2 w25\005\004 \005\230\005\330\004\354

In this case, two files have special characters in the name, \005 being the ENQ character. Each ENQ character sent to PuTTY triggers the response. They were very likely generated accidentally, possibly by processing a directory instead of a file in a script. The first file can be removed with this command:

rm -I w25*

and answering yes when the correct file is displayed.

The second file is more problematic as there are no displayable characters in the filename. Since the file is exactly 5 characters, you can use the ? character to identify the 5 characters:

rm -i ?????
file1 : ? (y/n) n
file2 : ? (y/n) n
Øì: ? (y/n) y

Oct
25
2011

Show elapsed time for startup tasks

When HP-UX boots up, more than two dozen startup scripts are run to initialize and start services and daemons. Most complete immediately, but some take a long time to complete. There is no timestamp recorded in /etc/rc.log
(where the startup scripts record their activity) so other than manually writing down the script names when there are long pauses, you can add an elapsed time to each script.

Now, for long elapsed time startup scripts, you can examine the tasks in the script and determine:

Is the service or process needed?
If not, edit the corresponding config script in
/etc/rc.config.d.
If there is no config script (non-standard) then either remove the link in
/sbin/rc*.d, or (recommended method) rename the link without a leading “S” or “K“, like this:

mv /sbin/rc2.d/S522ppp /sbin/rc2.d/__S522ppp

Is the script taking too long?
If yes, look at the actual commands being run. For special networking and fibre attached SAN disks, misconfigurations may take dozens of seconds to complete.

 

Edit the file:
/sbin/rc.utils

(about line 615, insert SECONDS=0)

echo >> $LOGFILE
echo ${FUNCT_DESC[$I]} >> $LOGFILE
echo “Output from \”${FUNCT_NAME[$I]}\”:” >> $LOGFILE

SECONDS=0    
echo “—————————-” >> $LOGFILE

a few lines down:


eval “${FUNCT_NAME[$I]}” >> $LOGFILE 2>&1 < /dev/null

result=$?

add this echo line:

echo “${FUNCT_NAME[$I]} — Elapsed time = $SECONDS sec” >> $LOGFILE

 

 

and in same file around line 760, insert SECONDS=0:

echo ${FUNCT_DESC[$INDEX]} >> $LOGFILE
echo “Output from \”${FUNCT_NAME[$INDEX]}\”:” >> $LOGFILE

SECONDS=0
echo “—————————” >> $LOGFILE

edit this line:
echo “${FUNCT_NAME[$INDEX]} ” >> $LOGFILE


modified line:
echo “${FUNCT_NAME[$INDEX]} — Elapsed time = $SECONDS sec” >> $LOGFILE


The two modified lines with
$SECONDS inserted are almost identical except the first one is FUNCT_NAME[$I] and the other is FUNCT_NAME[$INDEX].

Now at the next reboot, the rc.log files (/etc/rc.log and /etc/rc.log.old) will have the elapsed seconds for each script.

To sort by the process start times:

grep Elapsed /etc/rc.log | sort -nk7

To sort by the process start and stop times, sort the rc.log.old file:

grep Elapsed /etc/rc.log.old | sort -nk7