SUMMARY2: how to avoid a password with shutdown

From: Christophe DIARRA (
Date: Mon Jan 20 1997 - 06:22:57 CST


I have now found the way to use ufsdump from the crontab. Some people
from the net gave me the good solution. Four persons explained how
to do. Their mails are added to the end of this message and their
suggestions were to put the backup script in one of the /etc/rcX.d
directories and name it Sxxxx. The good answers begin after the line
"GOOD ANSWERS" in this message. I included too the files which were attached
to their mails.

I tried all the suggestions to shutdown the computer but finally it is
sure that no command under Solaris can bring the computer in single user
mode without the root password. 'init 6' or 'reboot' don't require a
password but were not helpfull in my case.

Raju Krishnamurthy <> tells that amanda can help for
this kind of problem ( amanda seems to be simple
to configure and allows ufsdumps in multi-user mode.

Since my first summary I received many mails from people giving
me suggestions and sharing with me their experiences.

Thanks to the following persons who replied (hope no one is forgotten).

Iván Villalobos Hernández <>
Kuldell <bf566z9@is000913.BELL-ATL.COM>
Raju Krishnamurthy <>
James Chapman <>
"Xu, Guo Miao (Hui, Kwok Miu)" <>
Ed Poorbaugh <>
Val Popa <>
Chris Marble <>
Ross Stocks <>
Jack Reiner <>
Rob Pieters <>
"Brian T. Wightman" <>
Dan Penrod <>
"Feeney, Tim" <Tim.Feeney@FMR.COM>
Karlheinz Pischke <>
Ravindra N Nemlekar <>
Kenn Owen <>
Scott McDermott <>
James Lin <>

My first summary was:

> Greetings,
> I have to 'ufsdump' disks in single user mode under Solaris 2.5. The backup
> script is executed from the crontab. The problem is that shutdown
> requires a password. Is it possible to shutdown a Solaris machine without
> giving a password ? This should be helpfull for me.
Maybe my explanations were not clear, and all the answers that I
received didn't solved my problem.
Under Solaris, if you run shutdown from the crontab (even from the root
crontab), you will be asked for the root password ('for system
maintenance'). The command I use (and which doesn't work from the crontab)
is: 'shutdown -y -g0'.
Untill I found a good solution, I will continue running my backup script
by hand.
Thanks for the people who replied:
Xu, Guo Miao (Hui, Kwok Miu) <>
Claude Charest <charest@chou.CANR.Hydro.Qc.Ca>
John Bradley <john.bradley@sunman>
Michael McGeown <>
Frank Pardo <>
Rob Pieters <>



Date: Thu, 16 Jan 1997 18:37:54 +1100 (EST)
From: Peter Marelas <>
To: Christophe DIARRA <>
Subject: Re: SUMMARY: how to avoid a password with shutdown
This script performs backups in single user mode.
Try it..
As for your shutdown password problem, has your shutdown command been modified?
Peter Marelas

Begin of the backup script (exadump)
# Level-n Dump of the local disk(s) of a Solaris-2.x workstation to an
# Exabyte drive at either the local host or a specified dumphost. The
# dump level defaults to 0 (full dump), for which single user mode is
# enforced unless the option -m (for multiuser) was given. (Multiuser
# mode for level 0 dumps is only recommended for inactive, e.g. read-
# only, filesystems.) The tape device defaults to /dev/rmt/0mn for
# dumps to a Solaris machine and to /dev/nrst1 for dumps to a SunOS 4
# machine.

# After a number of consistency checks, the user is asked if the dump is
# to be done now or later. In the latter case it is scheduled with "at"
# or "cron". A level 0 dump is done in a safe phase during a reboot.
# (Thanks to Everett Lipman <> for pointing
# out how to do this.) At the scheduled time the reboot is started,
# then the dump is done, and finally the machine is brought up to multi-
# user mode. Scripts for the reboot and dump are automatically
# installed. For incremental dumps (level > 0), which are done in
# multiuser mode, it does also make sense to be run during the night
# when the machine is not busy. (Do a crontab -l as root to find a time
# when the machine is least busy; here at KIS the best start time seems
# to be 3:45.)

# The file systems (raw partitions) to be dumped must be listed in a
# file. Its name can be specified with the option -f; if this is not
# done, it defaults to /etc/$prog.dat, where $prog is the basename of
# this program. In the data file, empty lines and comment lines
# starting with # are ignored. In each of the other lines, the first
# word is considered to be the full name of a raw disk partition to be
# dumped. The remainder of the line is again ignored and may be used for
# comments.

# For identification purposes, the contents of the data file and other
# relevant information are written to the tape as the first file (in tar
# format). Next follow the dumps of the various partitions in the order
# as listed in the data file. Finally a log file is appended to the
# tape (in tar format).

# The entire dump takes about 1 h per GB when dumping over the net;
# slightly less (45 min per GB) for a local tape drive.

# See Usage below.
# Examples: at KIS, we initiate dumps on the local Exabyte of our main
# server for
# 1. a level 0 dump of /home with
# cd /etc; ./exadump -f homedump.dat
# 2. a level 5 dump of /home with
# cd /etc; ./exadump -f5 homedump.dat
# 3. full level 0 dumps of the other local disks with
# cd /etc; ./exadump
# 4. a full level 0 dump for transport between our main site and our
# observatory on Tenerife, without updating /etc/dumpdates, so
# that the relationship between local full and incremental dump
# tapes stays intact:
# cd /etc; ./exadump -n

# (C) R. Hammer 1995 - 96
# May be redistributed and modified. No warranties; use at your own risk.
# Released: Fri Mar 31 20:47:09 1995
# Last change: Thu Aug 31 23:42:52 1995
# Fri Mar 1 20:07:18 1996 Vers 2.0
PATH=/sbin:/usr/bin:/usr/sbin; export PATH # set a safe PATH
umask 022
prog=`basename $0`

# Configuration section
# ---------------------

dftdata=/etc/${prog}.dat # default data file with list of partitions
                         # to be dumped
localpath=/opt/local/bin # path to editors which might be invoked by
                         # crontab -e below. Only used in interactive mode.
startdump=/etc/startdump # where to install help script for starting a
                         # level 0 dump from at/cron
dumpalert=/DUMP_ALERT # presence of this file warns users of a
                         # scheduled level 0 dump
prefix=S02 # for level 0 dumps, this script will be
                         # installed as /etc/rc2.d/${prefix}${prog}
# end configuration section

# Initialization
# --------------

# If we were called from /etc/rc2.d during boot up and there is no
# option file, we can exit immediately. If there is an option file,
# read it.
runlevel=`who -r | awk '{print $3}'`
nprog=`expr ${prog} : "${prefix}\(.*\)" \| ${prog}` # strip prefix
if [ "x${nprog}" != "x${prog}" ]; then
   [ ! -f /.${nprog} ] && exit 0
   set -- `cat /.${nprog}`
   # remove signal file immediately so that we reboot normally
   # when a problem with the Exabyte is encountered
   rm -f /.${nprog}
   grep periodic $dumpalert >/dev/null 2>&1
   [ $? != 0 ] && rm -f $dumpalert
   runlevel="after reboot, before 2"
   dftdata=`echo $dftdata | sed -e "s/$prog/$nprog/"`

# Some functions
# --------------

usage () {
   echo "
Usage: $prog [-<l>] [-n] [-m] [-f datafile] [dumphost [device]]

        ...where the dump level <l> defaults to 0 (full dump) and
        dumphost defaults to the local host. Device defaults to
        /dev/rmt/0mn for a Solaris-2 dumphost and to /dev/nrst1 for
        a SunOS-4 dumphost. Datafile lists the raw partitions to be
        dumped; it defaults to $dftdata if not specified.
        If -n is specified, don't update /etc/dumpdates. (This is
        useful for transporting dump tapes between sites without
        changing the relationship between full and incremental dumps.)
        If -m is given, run in multiuser mode even for a level 0 dump
        (not recommended except for tests and inactive partitions).
" 1>&2
   exit 1

panic () {
   echo "$1" 1>&2
   exit ${2:-1}

# Determine full command path of args or (if none are specified) the
# calling script. If the calling script changes PATH, it should first
# save it in the global variable oldpath so that we find the same
# versions of the commands as the user.
full_path () {
[ $# -eq 0 ] && set $0
for i in $*; do
   p=`basename $i`
   case $i in
    /*) f=$i ;;
   */*) a=`dirname $i`
        a=`sh -c "cd $a; pwd"`
     *) a=$PATH; PATH=${oldpath:=$PATH}; export PATH
        f=`type $i`
        PATH=$a; export PATH
        if [ $? -eq 0 ]; then
           case $f in
           *"not found") :;;
                      *) f=`echo $f | sed -e 's|[^(/.]*(*\(.*/[^)]*\))*|\1|'`
                         f=`full_path $f`;; # could be relative path...
   case $f in
   /*) : ;;
    *) echo "Can't find the full path name of command \"$p\"" 1>&2
       exit 2
   echo $f

install_scripts () {
# For scheduled level 0 dumps, we install ourselves in a place where we
# are found and run during reboot. This way we ensure to have the current
# version installed. We also install script $startdump, which is
# executed by at or cron to initiate the reboot.
rm -f /etc/rc2.d/${prefix}${prog}
cp -p ${fullpath} /etc/init.d
ln /etc/init.d/${prog} /etc/rc2.d/${prefix}${prog}
cat > $startdump << EOF
# Initiate a reboot during which a dump will be performed by script
# "$prog" at a run level equivalent to single user mode.
# Arguments are written to "/.$prog" where the dump script can find
# them. Should be called from at/cron as
# $startdump [-dumplevel] [-f datafile] [dumphost [device]]
# Datafile lists the raw partitions to be dumped. The at or cron job
# should be scheduled from within "$prog". This has the advantage that
# various sanity checks will be done.

# Released: Fri Mar 31 20:47:16 1995
# Last changes: Thu Aug 10 11:46:21 1995

echo "\$@" > /.$prog


echo "
        Please log off now!
" | /usr/sbin/wall
/usr/bin/sleep 120

cd /
/usr/sbin/shutdown -y -i6 > /dev/null

chmod +x $startdump

# Sanity checks
# -------------

case `uname -r` in
5.*) : ;;
  *) panic "Sorry - this version of $prog works only on hosts
running Solaris-2.x" 3 ;;

me=`uname -n`
id | grep 'uid=0(root)' >/dev/null || \
   panic "You must be root at $me to backup file systems." 4

# Command line arguments
# ----------------------

# The following parsing method is unconventional, but allows mixing of
# flags and nonflag arguments, even if the latter are not announced by
# flags; e.g. $prog -q5 host -f datafile device is legal.
dumphost=$me; remote=; dumplevel=0; cron=; expect=host
noenforce=; dev=; quiet=; data=$dftdata; update=u; fupdate=
for arg in $*
   case $arg in
       -*) OPTIND=1 # reset getopts since we may invoke it several times
           while getopts cfhmnq0123456789 c $arg 2>/dev/null
           do case $c in
               c) cron=-c;;
               f) oldexpect=$expect; expect=data;;
               h) usage;;
               m) noenforce=$c;;
               n) update=; fupdate=$c;;
               q) quiet=yes;;
               [0-9]) dumplevel=$c;;
               \?) echo "Sorry, can't deal with option $arg" 1>&2
        *) case $expect in
           data) data=$arg
           host) if [ "$arg" != "$me" ]; then
                      rsh ${dumphost} /usr/bin/date > /dev/null 2>&1 || panic \
                         "This machine is not allowed to access $dumphost as ro
You must add $me to /.rhosts at ${dumphost}." 5
                      grep $dumphost /etc/hosts >/dev/null || panic \
                         "Please add $dumphost to /etc/hosts at ${me}!" 6
                      remote="rsh $dumphost "
           device) dev=$arg ;;

if [ -z "$dev" ]; then
   # no tape device given; choose default according to OS release
   a=`eval $remote uname -r`
   case $a in
   4.*) dev=/dev/nrst1 ;;
     *) dev=/dev/rmt/0mn ;; # EXB-8500 mode, no rewind for multiple slices
[ -z "$remote" ] && dumpdev=$dev || dumpdev=${dumphost}:${dev}

# More sanity checks
# ------------------

# need full path of program and $data
case $data in
 /*) : ;;
*/*) f=`basename $data`
     a=`dirname $data`
     a=`sh -c "cd $a; pwd"`
  *) [ -f $data ] && data=`pwd`/${data} || data=/etc/$data
[ ! -f $data ] && \
   panic "The partitions to be dumped must be listed in \"${data}\",
which does not exist!" 7

dumplist=`awk 'NF>0 && $1 !~/^#/ {print $1}' $data`
[ -z "$dumplist" ] && \
   panic "No partitions listed in ${data}!" 8

if eval $remote /usr/bin/mt -f ${dev} stat 2>&1 |\
   grep "No such" >/dev/null 2>&1; then
      panic "Device $dumpdev does not exist." 9

# Interactive section
# -------------------

if [ -z "$quiet" ]; then
   until [ -n "$when" ]; do
      echo "
Do you want to run the backup
   1) now?
   2) at a later time with \"at\"?
   3) periodically with \"cron\"?
Type number of choice: \c" 1>&2
      read when
      case $when in
      1|2|3) : ;;
          *) when=; echo "\nInvalid choice!" 1>&2 ;;
   case $when in
   2) echo "at what time (current time is `date +%T`; default 03:45)? \c" 1>&2
      read time
      [ -z "$time" ] && time="03:45"
      cd /
   3) echo "editing crontab file... " 1>&2
      echo "e.g. to dump every Fri morning at 3:45, add a line like " 1>&2
      PATH=$PATH:$localpath; export PATH
   arg="-q${dumplevel}${noenforce}${fupdate} $cron -f $data $dumphost $dev"
   if [ $dumplevel -eq 0 -a -z "$noenforce" ]; then
      if [ x$when = x1 ]; then
         time="now + 2 minutes"
         echo "
If (or as soon as) a tape has been loaded into drive $dev at $dumphost,
hit RETURN:\n" 1>&2
         read yn
      case $when in
      1|2) echo "$startdump $arg" | at $time
           echo "Caution: $me will go down for disk backups at $time." \
> $dumpalert
        3) echo "45 3 * * 5 $startdump $arg" 1>&2
           crontab -e
           entry=`crontab -l | grep $startdump`
           if [ -n "$entry" ]; then
              echo "Caution: periodic disk backups in single user mode have bee
         scheduled for $me, with the following crontab entry
         (Format: min hour day-of-month month day-of-week command):
\n$entry\n" > $dumpalert
           else exit 0
      case $when in
      2) echo "$fullpath $arg" | at $time ;;
      3) echo "45 3 * * 5 $fullpath $arg" 1>&2
         crontab -e ;;
   case $when in
     1) [ $dumplevel -eq 0 -a -z "$noenforce" ] && exit 0
   2|3) echo "\nDon't forget to load a tape in drive $dev at $dumphost.\n" 1>&2
        exit 0

# Dump section
# ------------

DUMP="ufsdump ${dumplevel}fbsd${update} ${dumpdev} 126 13500 54000"

# For a 5GB Exabyte (8500), "man ufsdump" mentions 13000 nominal feet.
# Hamilton recommends even 15000 feet for a 112 m tape. As a
# compromise, I took 13500. This value is not very important (but
# should not be too small) since ufsdump under Solaris 2.x detects
# EOT. For a 2.3 GB Exabyte (8200), we can only use nominal 6000 feet.
# Usenet articles recommend NOT to use compression mode for dumps.

tmp=/tmp/dumplog.$$ # temporary log file
log=${nprog}log.${dumplevel} # final log file
contents=/tmp/CONTENTS # contents, will become first file on tape
touch $tmp

echo "\nGoing to dump local disks to ${dumpdev}..."
echo "Wait... checking disks and constructing header file... \c"
cat > $contents << !EOF

                              * DUMP TAPE *

 produced on: $date (start time)
 for host: $me
 run level: $runlevel
 dump level: $dumplevel
 dump command: $DUMP

 The dump was controlled by the following data file,

cat $data >> $contents
cat >> $contents << !EOF

 The first file on this tape, "CONTENTS", is the file you are currently
 reading. Then follow the dumps of the partitions listed above (in lines
 that are not commented out). The last file on the tape, "$log",
 is the log file containing the output of the dump commands.

   file number contains size/kB mount point

       1 CONTENTS

n=2; total=0
for slice in $dumplist; do
   mountpoint=`grep $slice /etc/vfstab | awk '{print $3}'`
   s=`echo $slice | sed -e 's/rdsk/dsk/'`
   size=`df -k $s | tail -1 | awk '{printf "%8d", $3}'`
   total=`expr $total + $size`
   echo " $n $s $size $mountpoint" >> $contents
   n=`expr $n + 1`
total=`expr $total / 1024`

cat >> $contents << !EOF
       $n $log

 Total size of all partitions: $total MBytes.

if [ "$dumplevel" != "0" ]; then
   cat >> $contents << !EOF
 (This amount would be written to tape in a level 0 dump. In
 incremental dumps the total amount of data written to tape is
 usually much smaller; see the dump log at the end of the tape.)

cat >> $contents << !EOF

 As of the time of this dump, the complete list of local disk partitions,
 sorted according to their currently used size in kbytes, is


df -k | head -1 >> $contents
df -k `awk 'NF>3 && $1 !~/^#/ && $4 == "ufs" {print $1}' /etc/vfstab` \
   | tail +2 | sort +2 >> $contents

cat >> $contents << !EOF

                   How to restore data from this tape:

 If the tape is in a drive on the local machine and positioned at the
 start of the tape, you can restore data from e.g. the second dumped
 partition (the third file on this tape) with

   ufsrestore <options>fs $dev 3

 Or if the tape is in the first drive on SunOS-4 host dewey, you type

   ufsrestore <options>fs dewey:/dev/nrst1 3

 Example: assume that /opt of host donald were dumped as sixth partition
 and therefore located in file number 7 on this tape, and that the tape
 were in drive 1 on dewey. To extract interactively file
 /opt/local/bin/MakeTeXPK you would type

   donald# ufsrestore -ifs dewey:/dev/nrst1 7
   ufsrestore > cd local/bin
   ufsrestore > ls
   ufsrestore > add MakeTeXPK
   ufsrestore > extract
   You have not read any volumes yet.
   Unless you know which volume your file(s) are on you should start
   with the last volume and work towards the first.
   Specify next volume #: 1
   set owner/mode for '.'? [yn] y
   ufsrestore > quit

 If the tape were in the first local drive, you would type
   donald# ufsrestore -ifs /dev/rmt/0n 7
 and then proceed as above.


echo "Done."

#echo "JUST KIDDING... DUMP=$DUMP"; exit 0 # uncomment while testing

#echo "WAIT ...checking file systems"; fsck -F ufs -o p # currently disabled
if [ -z "$quiet" ]; then
 echo "If Exabyte tape is inserted in drive $dev on host $dumphost,"
 echo "confirm with RETURN:"; read y
 sleep 40 # give a local Exabyte drive time to initialize after reboot
 echo "\nWriting header file to tape..."
 out=`eval $remote /usr/bin/mt -f ${dev} rew 2>&1`
 if echo $out | grep "no tape loaded" >/dev/null; then
# [ -z "$cron" ] && rm -f $remove
    echo "Dump failed since no tape loaded or tape drive offline!" |\
       mailx -s "Dump failed" root
    exit 1
 (cd `dirname $contents`;
  tar cf - ./CONTENTS | eval $remote /usr/bin/dd of=$dev) > /dev/null

echo "The header file \"CONTENTS\" has been written to the tape as the
first file. It can be retrieved with \"tar xvf <tape_device>\"."

(for slice in $dumplist; do
    $DUMP $slice
) 2>&1 | tee $tmp
mv $tmp /etc/$log
echo "\nAppending the log file to the end of the tape..."
(cd /etc; tar cf - ./${log} | eval $remote /usr/bin/dd of=$dev)
eval $remote /usr/bin/mt -f ${dev} rewoffl
#eval $remote /usr/bin/mt -f ${dev} rew # for testing

cat >> $contents << !EOF

Contents of the log file "${log}" (last file on tape):

cat /etc/$log >> $contents
mv $contents /etc/$log
#[ -z "$cron" -a -n "$remove" ] && rm -f $remove

if [ -z "$quiet" ]; then
   n=`expr $n - 1`
   echo "The log file \"${log}\" has been appended to the tape as the
last file. It can be retrieved with
   mt -f <tape_device> rew
   mt -f <tape_device> $n
   tar xvf <tape_device>
   mt -f <tape_device> rew
The combined contents and log file has also been saved as /etc/${log}.\n"

   if [ "x$runlevel" != x3 ]; then
      echo "Type CTRL-D to start multi user mode (run level 3)"
      exit 0
else echo "Dump is done.\n"

File exadump.dat
 # DONALD: Full Dump Solaris-2.3

 # Thu Nov 23 12:09:18 1995
 # raw device mount point max. MB
 /dev/rdsk/c1t1d0s0 /root2 46
 /dev/rdsk/c0t3d0s0 / 31
 /dev/rdsk/c1t1d0s3 /usr2 260
 /dev/rdsk/c0t3d0s5 /usr 270
 /dev/rdsk/c0t3d0s3 /var 316
 /dev/rdsk/c1t1d0s4 /export 482
 /dev/rdsk/c1t1d0s5 /opt 1734
 /dev/rdsk/c1t3d0s7 /opt/local/data 1387
 /dev/rdsk/c1t3d0s6 /opt/local/src 1611

#/dev/rdsk/c1t3d0s3 /home 5347 # see homedump.dat
#/dev/rdsk/c1t1d0s7 /export/dat/donald_1 1493 # /dat/* not dumped
#/dev/rdsk/c0t3d0s6 /obsolete/opt/SUNWspro 348 # obsolete
#/dev/rdsk/c0t3d0s7 /obsolete/w 71 # obsolete

Date: Wed, 15 Jan 1997 20:36:33 +0100
From: Rob Pieters <>
To: Christophe DIARRA <>
Subject: Re: How to avoid a password with shutdown


Some tips :
This is a line from my crontab :
        0 1 * * 0 /usr/sbin/shutdown -i6 -g0 -y 2>&1
Doing so, the system reboots and goes back to multiuser.
(I'm sure this works)
The problem is of course that you are no longer in single user mode.
But when the system reboots, all the scripts in /etc/rc2.d will be
executed. Place your script in this directory and name it S00xxxxx, so
it will be executed before all the other startup scripts.
Of course, you have to build in some test to make sure no dump will
start in case of a normal system boot.
(I never tried this , but I think it will work)

Date: Wed, 15 Jan 1997 13:30:26 -0600
From: "Brian T. Wightman" <>
To: Christophe DIARRA <>
Subject: Re: SUMMARY: how to avoid a password with shutdown

A little late on my end, but...
If I understand you correctly, you want to
        1) take the machine down to single user mode
        2) Run backups
        3) Bring the machine back up to multiuser mode
all without operator intervention.
Why not try something along these lines.....

from root's crontab script (pseudocode)
        touch /etc/.DOBACKUPS
        shutdown -g0 -y -i6
This would cause a reboot
Then in /etc/init.d/backups
        if [ -f /etc/.DOBACKUPS ]; then
                /bin/rm -f /etc/.DOBACKUPS

and link that into /etc/rcS.d/S99backups (you may need to play with
this a little bit to make sure the sequence number is right (all
needed filesystems available but non-essential programs not running)).
This will run the backup script from the system startup script only if
the file /etc/.DOBACKUPS exists. This way, you have a quiet system,
no users, and it proceeds directly into multi-user mode when it is
finished with the backups.
Hope this helps,

From: Ravindra N Nemlekar <>
To: Christophe DIARRA <>
Subject: Re: SUMMARY: how to avoid a password with shutdown
You can get around the password by executing
scripts from /etc/rc1.d and then in /etc/rcS.d
This way, you don't have to give the password also...

This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:11:43 CDT