Questions
and Answers
Amy Rich
In the July 2005 issue, I answered a question dealing with sudo
and shell redirection. I thank John Rouillard for submitting another
solution to the same issue using the tee command. He says:
You rightly mention that redirection is done by the shell without
the privileges to write to the file, but a sudo idiom using tee
can get around this. Replace:
sudo command > /tmp/foo
or:
sudo command >> /tmp/foo
with:
sudo command | sudo /usr/bin/tee /tmp/foo > /dev/null
or:
sudo command | sudo /usr/bin/tee -a /tmp/foo > /dev/null
Now, since it's not a good idea to give just anybody access to tee,
as they can now overwrite any file on the system, you can define the
allowed arguments to tee as well. So to allow the use of tee
to append to the file /tmp/foo, you would put (something like):
allowed_user HOST = NOPASSWORD: /usr/bin/tee -a /tmp/foo, \
PASSWORD: /other/commands
Q We just installed Solaris
9 on a new Sun Fire V440 with an attached D1000 JBOD array. After
mirroring all of the disks, we rebooted the machine and some of the
database replicas were tagged as invalid. The error message says I
need to run "metadevadm -u c2t1d0" to fix it. I tried running this
and rebooted and still had the same issue. To make sure, we went through
this again, and the exact same thing happened. What happened to the
replicas, and how do we get them to stay current so that the machine
doesn't continually have issues upon reboot?
A I'm guessing that you've used
raidctl to configure an internal RAID device and then put
you metadb replicas on it? This is not supported by Sun and will
result in the behavior you describe. From:
http://sunsolve.sun.com/search/document.do?assetkey=1-9-77518-1
When probed by the operating system upon reboot, the internally mirrored
device on the Sun Fire 440 server does not report a consistent device
identity. For this reason, the metadbs previously created on this
device are no longer valid.
The following is an example of the console output, which appears
in /var/adm/messages:
Jun 25 10:15:02 hostname metadevadm: Invalid device relocation
information detected in Solaris Volume Manager
Jun 25 10:15:02 hostname metadevadm: Please check the status of the following disk(s):
Jun 25 10:15:02 hostname metadevadm: c#t#d#
The metadevadm command can be used to determine if the information
for device paths has changed. The -n option emulates the update,
so any changes are not implemented. For example:
hostname# metadevadm -n -u c#t#d#
Updating Solaris Volume Manager device relocation information for c#t#d#
Old device reloc information:
id1,sd@#############################
New device reloc information:
id1,sd@#############################
This preceding output shows that that either of the following conditions
has occurred:
- The pathname stored in the metastate database no longer correctly
addresses the device.
- The device ID for a disk drive has changed.
Without the -n flag, the metadevadm command updates
the device information. The update, however, does not resolve the
problem, and the metadbs will still be invalid.
The metadb output will also show an unknown block count. For example:
hostname# metadb -i
flags first blk block count
M p 20 unknown /dev/dsk/c#t#d#s7
M p 7110 unknown /dev/dsk/c#t#d#s7
M p 15612 unknown /dev/dsk/c#t#d#s7
Q We're setting up two SPARC
machines as part of a Sun Cluster. Because of hardware limitations,
we're using the onboard ce interfaces and a qfe quad
card in each machine. For redundancy's sake, we do not want to put
all the private interconnects on the qfe card; however, the
documentation I've read says that all the private cluster interconnects
must be running at the same speed/duplex. Is this true, or can we
use one of the ce interfaces as a private cluster interconnect,
too?
A You've read the documentation
correctly; all cluster private interconnects must be running at
the same speed/duplex. I'm assuming that you're running one of the
two ce interfaces at gigabit speeds and that you're doing
point-to-point connections for the cluster private interconnects
and/or auto-negotiation isn't going to work. If so, you can still
individually set the other interface (the one you'd like to use
as a cluster private interconnect) to 100FDX by using ndd.
To have the modification persist through reboots, add an init file
such as the following:
#!/sbin/sh
#
# Kernel/device tuning script
#
case "$1" in
'start')
echo "Setting ce1 to 100FDX"
ndd -set /dev/ce instance 1
ndd -set /dev/ce adv_1000fdx_cap 0
ndd -set /dev/ce adv_1000hdx_cap 0
ndd -set /dev/ce adv_100fdx_cap 1
ndd -set /dev/ce adv_100hdx_cap 0
ndd -set /dev/ce adv_10fdx_cap 0
ndd -set /dev/ce adv_10hdx_cap 0
ndd -set /dev/ce adv_autoneg_cap 0
;;
'stop')
;;
*)
echo "Usage $0 start"
exit 1
;;
esac
exit 0
If you call this script, say, /etc/init.d/kernelmods, then
you'd also want to link /etc/rc2.d/S69kernelmods (or earlier)
to it so that it gets run before most of the multiuser network services.
Q Is there a program similar to
split that will work on regular expressions instead of a fixed number
of lines? We have one file full of three different kinds of data,
but each type of data is separated by an identifiable expression.
Here's a sample data set:
xxx1
aaa,bbb,ccc,ddd
aba,bab,cdc,dcd
xxx2
eee,fff,ggg
xxx3
hhh,iii
xxx2
eef,ffg,gge,fff
The separators are the xxx{num} tokens, where {num}
is 1, 2, or 3 (depending on the kind of data). I want to end up with
three separate files containing the different kinds of records.
A One portable shell solution is
to use the csplit program. First, split on your record separator
(I've made this match any number after xxx, just in case
you never need more than three types of data):
#!/bin/sh
recsep='xxx[0-9]*'
numrecs=`grep -c "^${recsep}" $1`
if [ ${numrecs} -le 1 ]; then
echo "Only one type of record, not splitting file."
exit 0
elif [ ${numrecs} -eq 2 ]; then
csplit -skf data $1 "%^${recsep}%" "/^${recsep}[0-9]*/"
else
splitcount=`expr ${numrecs} - 2`
csplit -skf data $1 "%^${recsep}%" "/^${recsep}/" \{${splitcount}\}
fi
This will leave you with some number of files that each contains one
type of record. Second, you can recombine all of the records into
files matching the record type and remove the unnecessary record separators:
for ifile in `ls data*`; do
ofile=`head -1 ${ifile}`
grep -v ${ofile} ${ifile} >> ${ofile}
done
Now you'll have the following files and output, given your sample
data:
xxx1:
aaa,bbb,ccc,ddd
aba,bab,cdc,dcd
xxx2:
eee,fff,ggg
eef,ffg,gge,fff
xxx3:
hhh,iii
Other solutions to your problem include writing an awk script and
modifying FS and RS, or using some other language (Perl,
Python, C, whatever) to print out the data between record separators.
Q I just purchased a used Sun box
from eBay for a project we're doing at work. This project requires
that we mirror the disks under SVM, and we have seven partitions
available for data. This means I'm one partition short unless I
use the backup partition, slice 2, for real data. I know that in
the past this was not recommended, but is this true anymore? Can
I just use slice 2 for data?
A As a general rule, you can repartition
the disk and use slice 2 for data instead of the backup partition,
but it's not conventional and will cause issues with some utilities.
Unfortunately for you, one of the things that requires slice 2 to
be the whole disk is SVM. Other commands that traditionally expect
slice 2 to be the backup partition are prtvtoc and format.
If you've already modified slice 2, you can change it back by running
format and configuring slice 2 as follows:
Enter partition id tag[backup]:
Enter partition permission flags[wm]:
Enter new starting cyl[0]:
Enter partition size[35368272b, 7506c, 17269.66mb, 16.86gb]: 7506c
The above partition size should be the whole disk (you can specify
cylinders, blocks, whatever).
There may be a solution to your problem, though. Depending on
what kind of data you're putting on these partitions (OS data or
non-OS data), you may be able to use soft partitions to create the
extra space you need. Take a look at the docs.sun.com page on soft
partitions to see whether it will meet your needs:
http://docs.sun.com/app/docs/doc/817-5776/6ml784a4c?a=view
If you set aside slice 6 on your two mirror disks for the non-OS data,
you would create two soft partitions as follows:
metainit d81 -p c0t0d0s6 4g
metainit d82 -p c0t1d0s6 4g
metainit d91 -p c0t0d0s6 8g
metainit d92 -p c0t1d0s6 8g
Now you can mirror those metadevices like you would any others:
metainit d80 -m d81
metattach d80 d82
metainit d90 -m d91
metattach d90 d92
Q I'm trying to write a
Jumpstart post script to put some disks into metasets. There are two
issues to worry about. If disk has no label, one needs to be written
out. If the machine already has a valid UFS partition on slice 0,
then we don't want to modify the disk at all. I know how to do this
by hand with format, but there doesn't seem to be a good, non-interactive
way to accomplish this in a script.
A Let's assume that you're feeding
your script the disk device but without the slice number, for example,
c1t1d0. To begin, define a diskset name, get the path to the disk
device, and write out a command file for format:
diskset='svmdisk'
diskdev="/dev/rdsk/$1"
echo "label" >> ${B}/tmp/formatcmds.$$
Next, determine whether the disk has a UFS partition on slice 0, and
if not, label the disk:
diskstat=`fstyp "${diskdev}s0"`
if [ "X${diskstat}" = "Xufs" ]; then
# the filesystem has already been initialized
echo "Not modifying disk: ${diskdev}"
exit 0
else
# add a label to the disk
echo "Labeling disk: ${diskdev}"
format -d ${diskdev} -f ${B}/tmp/formatcmds.$$
fi
Double-check that you've successfully labeled the disk before you
go any further:
if [ "X`prtvtoc -f ${diskdev}s0`" = "X" ]; then
# the initialization did not work
echo "ERROR: Initialization of ${diskdev} failed, exiting."
exit 1
fi
At this point, you either should have bailed out of the script because
the initialization failed or because you already had a valid UFS filesystem
or you should now have a freshly labeled disk. From this point, you
can add the host to the metaset and then add your disks:
metaset -s ${diskset} -a -h `hostname`
metaset -s ${diskset} -a ${diskdev}
You can use ${SI_HOSTNAME} in place of "hostname" if you've defined
the hostname in your rules file, but if you're doing a generic rule
to match many hosts, SI_HOSTNAME won't be set.
Amy Rich has more than a decade of Unix systems administration
experience in various types of environments. Her current roles include
that of Senior Systems Administrator for the University Systems
Group at Tufts University, Unix systems administration consultant,
and author. She can be reached at: qna@oceanwave.com. |