Cover V14, i08

Article

aug2005.tar

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.