Questions
and Answers
Amy Rich
Q We've just set up a JumpStart
installation for our Solaris 9 machines. Part of the draw to move
to Solaris 9 from Solaris 8 was that all of the disksuite (or SVM,
as it's called these days) steps would be done by JumpStart as part
of the profile. After installing a number of machines, we discovered
that the mirror for / never had the second half attached. I tried
to do it manually but received an error. Here's the disk section
of the profile:
partitioning explicit
filesys mirror c0t0d0s0 c0t1d0s0 2048 / logging
filesys mirror c0t0d0s1 c0t1d0s1 2048 swap
filesys mirror c0t0d0s3 c0t1d0s3 2048 /var logging
filesys mirror c0t0d0s4 c0t1d0s4 27648 /local logging
metadb c0t0d0s7
metadb c0t1d0s7
The metastat output for d0 shows the following (note
the missing second submirror):
d0: Mirror
Submirror 0: d1
State: Okay
Pass: 1
Read option: roundrobin (default)
Write option: parallel (default)
Size: 4192512 blocks (2.0 GB)
d1: Submirror of d0
State: Okay
Size: 4192512 blocks (2.0 GB)
Stripe 0:
Device Start Block Dbase State Reloc Hot Spare
c0t0d0s0 0 No Okay Yes
The d2 metadevice does get created, though:
d2: Concat/Stripe
Size: 4202688 blocks (2.0 GB)
Stripe 0:
Device Start Block Dbase Reloc
c0t1d0s0 0 No Yes
I tried to manually metattach the submirror to the mirror with
this command:
metattach d0 d2
But then I got the following error:
metattach: host.my.domain: d2: can't attach labeled submirror to an
unlabeled mirror
As far as I can tell, I've configured everything correctly, and even
after that, the manual metattach command seems fairly straightforward.
I still can't get d2 to attach to d0, though. Do you
have any suggestions? I would try migrating to Solaris 10, but we
can't because Sun Cluster is not yet certified on 10. Thanks for any
help you can offer.
A According to your profile, you've
configured / on slice 0 and swap on slice 1. Although this should
work just fine, there is an issue in Solaris 9 with the location
of the swap filesystem. By default, Solaris 9 installations put
the swap filesystem on cylinder 0 at the beginning of the disk.
Ideally, JumpStart would be smart enough to configure swap and /
on the same cylinders on both disks, but this isn't the case. This
is mentioned in the Sunsolve document number 4686530, available
to customers with support contracts as:
http://sunsolve.sun.com/search/document.do?assetkey=1-25-76254-1
This is also listed as bugid 4686530:
http://sunsolve.sun.com/search/document.do?assetkey=urn:cds:docid:1-1-4686530-1
On the initial boot disk, c0t0d0 in your case, JumpStart configures
swap starting at cylinder 0. On the secondary disk, c0t1d0,
it looks at your profile and assumes that you want / starting on cylinder
0 because you have specified slice 0. If you look at the output of
prtvtoc or the partition table under format, you'll see that
slice 0 and slice 1 are different on the two disks.
As a result of this faulty partitioning, you're trying to attach
one submirror to d0 that starts at slice 0 and one submirror
that doesn't. SVM is only able to configure a mirror where all submirrors
either contain or don't contain cylinder 0 according to its documentation.
There's another hint that things are not configured correctly
if you compare the sizes of d1 and d2 and the sizes
of d11 and d12. The sizes of d1 and d11
are the same, and the sizes of d2 and d12 are the
same.
The easiest fix is to reinstall your Solaris 9 machines, putting
swap on slice 0 and / on slice 1. You could also tell JumpStart
to use specific cylinders during the install, but you could wind
up making a number of very specific profiles if you have a number
of different kinds of boot disks throughout your infrastructure.
To tell Jumpstart to use specific cylinders, 0-411 in this example,
specify them as follows in the profile:
filesys mirror c0t0d0s0 c0t1d0s0 0:411 / logging
If you have existing machines with this partitioning problem and do
not want to reinstall them, you can break the mirrors on the second
disk, clear them, remove the metadb on that disk, and then reformat
to match the initial disk and manually re-add all of the mirrors.
First, break the second sub-mirror off of the metamirror and clear
it:
metaclear d2
metadetach d10 d12
metaclear d12
metadetach d30 d32
metaclear d32
metadetach d40 d42
metaclear d42
Next delete the replica database from the second disk:
metadb -r c0t1d0s7
Then reformat the secondary disk to match the initial disk:
prtvtoc /dev/rdsk/c0t0d0s2 | fmthard -s - /dev/rdsk/c0t1d0s2
Now re-add the replica database:
metadb -a -c 3 -f /dev/rdsk/c0t1d0s7
And, finally, recreate all of the sub-mirrors and reattach them:
metainit d2 1 1 c0t1d0s0
metattach d0 d2
metainit d12 1 1 c0t1d0s1
metattach d10 d12
metainit d32 1 1 c0t1d0s3
metattach d30 d32
metainit d42 1 1 c0t1d0s4
metattach d40 d42
" Q We've been running versions
of OpenSSL 0.9.6 for ages, and we finally want to upgrade to the OpenSSL
0.9.7 series. Unfortunately, 0.9.7 is not backward-compatible with
0.9.6, so we need to rebuild all of the software dynamically linked
against libssl. We've compiled a lot of software over the years,
though, and we have no idea which packages are linked against the
OpenSSL library. Is there an easy way to tell?
A You don't mention which OS you're
running or how you've built the software you've installed. If you're
using something like BSD ports or Linux RPMs, dependencies are often
defined as part of the package and you could tell by checking the
package information. If you've just built things by hand and done
a make install, then you'll have to examine each binary to tell
whether it's linked against either library. The specifics of how
you determine whether or not to look at a file and possibly which
tool you use to examine the linked libraries will depend on your
OS.
Here's a script I wrote for Solaris a while back that runs a find
in /opt and runs ldd against any ELF files to find
things dynamically linked against libcrypto or libssl, the
two OpenSSL libraries. It then looks for that file in /var/sadm/install/contents
to try to determine whether it belongs to an installed package.
The output from the resulting mail can then be later massaged to
produce various types of reports:
!/bin/sh
# set up some initial variables
outfile="/tmp/output.$$"
rm -f ${outfile} && touch ${outfile} || exit $?
hostname='hostname'
startdir='/opt'
# find all of the ELF files within the startdir
for file in 'find ${startdir} -type f \
-exec file {} \; | awk -F: '/ELF/ {print $1}''; do
# initialize pkgname and pkgversion
pkgname='none'
pkgversion='none'
# run ldd on the ELF binaries to determine what they link against
libssl='ldd ${file} | awk '/libssl/ {print $3}''
libcrypto='ldd ${file} | awk '/libcrypto/ '{print $3}''
#if we got the message (file not found), replace it
if [ "X${libssl}" = 'X(file' ]; then
libssl='missinglib'
fi
if [ "X${libcrypto}" = 'X(file' ]; then
libcrypto='missinglib'
fi
# if we found a link against either libssl or libcrypto, try and
# determine the package name and version from
# /var/sadm/install/contents
if [ "X${libssl}" != 'X' ] || [ "X${libcrypto}" != 'X' ]; then
pkgname='awk -v file="${file} " '($0 ~ file) \
{print $NF}' /var/sadm/install/contents'
if [ "${pkgname}" != 'none' ]; then
pkgversion='pkginfo -l ${pkgname} |awk '/VERSION:/ {print $2}''
fi
fi
# if we have a match, print it to a file
if [ "X${libssl}" != 'X' ]; then
echo "${hostname} ${pkgname} ${pkgversion} \
requires ${libssl} for ${file}" >> ${outfile}
fi
if [ "X${libcrypto}" != 'X' ]; then
echo "${hostname} ${pkgname} ${pkgversion} \
requires ${libcrypto} for ${file}" >> ${outfile}
fi
done
# if we have data in our output file, mail it off
if [ -s ${outfile} ]; then
mailx -s "openssl checking output from ${hostname}" \
me@my.email.address < ${outfile}
fi
# clean up our output file
rm -f ${outfile}
Q I'm in the process of installing a
new BIND 9 nameserver on a Solaris 8 machine. For security purposes,
I want to run BIND as a user other than root, and I want to chroot
it to its own directory. Can you give me a quick step-by-step process
to get this working, or is it really complicated?
A Chrooting BIND 9 under Solaris
(or most other operating systems) is fairly simple. Unlike with
BIND 8, you don't need any of the shared libraries or the BIND executables
in the jail directory. The first step is to get BIND working without
the modifications, just so you know you aren't having issues with
your configuration or your zones to begin with.
You can choose to install the BIND software in the default of
/usr/local, or you can try and overwrite the files that come
with the Solaris 8 distribution. To minimize confusion, I tend to
do the latter, being careful to not install any named patches
after the software installation. I place named in /usr/sbin,
the configuration file in /etc/named.conf, and the zone files
in /etc/named. If you prefer a different layout, just modify
the paths below.
Once you have a working configuration, create a bind user and
group. I generally pick UID and GID 53 to correspond with named's
port number:
groupadd -g 53 bind
useradd -c "BIND user" -d /var/bind -g 53 -u 53 -s /bin/false bind
Create the home and skeleton directory for the daemon and set the
ownerships and permissions:
mkdir -p /var/bind
cd /var/bind
mkdir -p dev etc/named lib usr/sbin \
var/run usr/share/lib/zoneinfo var/log
chown -R root:bind /var/bind
chown bind:bind etc/named var/run var/log
Now create the devnull device and copy in the zoneinfo file
for your timezone:
mknod dev/null c 1 3
cp /usr/share/lib/zoneinfo/EST5EDT usr/share/lib/zoneinfo
Copy your configuration file and your zone records into etc and etc/named,
respectively (assuming that your configuration file lists the zone
directory as /etc/named):
mv /etc/named.conf etc
mv /etc/named/* /etc/named/.??* etc/named
Lastly, modify your init script to run named with the -u
and -t flags so that named runs as a non-root user and
in the chrooted environment. You can modify /etc/init.d/inetsvc,
or you can comment out the named information of that file and
create a separate init script. A separate script would look something
like the following:
#!/bin/sh
case $1 in
'start' )
if [ -x /usr/sbin/named -a -f /var/bind/etc/named.conf ]; then
echo 'starting internet domain name server.'
/usr/sbin/named -u 53 -t /var/bind &
else
echo "Missing an executable /usr/sbin/named or the config file"
echo " /var/bind/etc/named.conf"
exit 1
fi
;;
'stop' )
/usr/sbin/rndc stop
;;
*)
echo "usage: $0 {start|stop}"
exit 1
;;
esac
Q I've built
gcc 3.4.3 on Solaris 8. Everything seemed to go fine, but when
I try to build new packages with this version of gcc, I get
the following error:
configure:8874: ./conftest
ld.so.1: ./conftest: fatal: libgcc_s.so.1: \
open failed: No such file or directory
killed
I've checked my configure options and the steps I did to install gcc,
and everything seems to be in order:
./configure --prefix=/usr/local --enable-languages=c,c++
make bootstrap
make
make install
Do you have any ideas why gcc builds and installs just fine,
but subsequent software compilations fail? I'm hoping not to need
to set LD_LIBRARY_PATH for everything or use crle to include
/usr/local/lib. There should be a way to make gcc do
the right thing.
A When you build gcc, it's
not compiling /usr/local/lib as a runtime directory for libgcc.
To correct this, you can specify the LDFLAGS when you make
the bootstrap compiler:
make LDFLAGS="-R/usr/local/lib" \
BOOT_LDFLAGS="-R/usr/local/lib" bootstrap
Now when the bootstrap compiler builds the second stage compiler,
the runtime path will be built in.
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. |