source: src-sh/pc-sysinstall/backend/functions-zfsrestore.sh @ 8378d50

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3releng/10.1
Last change on this file since 8378d50 was 8378d50, checked in by Kris Moore <kris@…>, 17 months ago

Update pc-sysinstall to now allow doing restores from a replicated
ZFS dataset via life-preserver

  • Property mode set to 100755
File size: 5.5 KB
Line 
1#!/bin/sh
2#-
3# Copyright (c) 2013 iXsystems, Inc.  All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8# 1. Redistributions of source code must retain the above copyright
9#    notice, this list of conditions and the following disclaimer.
10# 2. Redistributions in binary form must reproduce the above copyright
11#    notice, this list of conditions and the following disclaimer in the
12#    documentation and/or other materials provided with the distribution.
13#
14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24# SUCH DAMAGE.
25#
26
27# Functions which runs commands on the system
28
29. ${BACKEND}/functions.sh
30. ${BACKEND}/functions-parse.sh
31
32do_zfs_restore()
33{
34  load_ssh_settings
35 
36  restore_zfs_from_remote
37
38  restore_stamp_grub
39
40  restore_umount_zfs
41}
42
43# Function to load & check SSH remote settings
44load_ssh_settings()
45{
46  get_value_from_cfg sshHost
47  SSHHOST="$VAL"
48  get_value_from_cfg sshPort
49  SSHPORT="$VAL"
50  get_value_from_cfg sshUser
51  SSHUSER="$VAL"
52  get_value_from_cfg sshKey
53  SSHKEY="$VAL"
54
55  if [ -z "$SSHHOST" ] ; then
56     exit_err "Missing sshHost!"
57  fi
58  if [ -z "$SSHUSER" ] ; then
59     exit_err "Missing sshUser!"
60  fi
61  if [ -z "$SSHPORT" ] ; then
62     SSHPORT="22"
63  fi
64  if [ -n "$SSHKEY" ] ; then
65     SSHKEY="-i $SSHKEY"
66  fi
67
68  # Now that the settings are loaded, lets test this connection
69  ssh -o NumberOfPasswordPrompts=0 $SSHKEY -p $SSHPORT ${SSHUSER}@${SSHHOST} "echo ''"
70  if [ $? -ne 0 ] ; then
71     exit_err "Failed SSH connection to ${SSHHOST}"
72  fi
73
74  export SSHKEY SSHPORT SSHUSER SSHHOST
75}
76
77restore_zfs_from_remote()
78{
79  get_value_from_cfg zfsProps
80  ZFSPROPS="$VAL"
81  if [ -z "$ZFSPROPS" ] ; then
82     exit_err "No zfsProps= specified!"
83  fi
84
85  ZPFILE="${TMPDIR}/.zfs-restore-props"
86
87  # First lets fetch the ZFS properties backup
88  ssh -p ${SSHPORT} ${SSHKEY} ${SSHUSER}@${SSHHOST} cat ${ZFSPROPS} > ${ZPFILE}
89  if [ $? -ne 0 ] ; then
90     exit_err "Unable to get ZFS properties file!"
91  fi
92
93  get_value_from_cfg zfsRemoteDataset
94  ZFSDATASET="$VAL"
95
96  lastSNAP=`ssh -p $SSHPORT ${SSHKEY} ${SSHUSER}@${SSHHOST} "zfs list -t snapshot -d 1 -H ${ZFSDATASET}" | tail -1 | awk '{$1=$1}1' OFS=" " | cut -d '@' -f 2 | cut -d ' ' -f 1`
97
98  echo "lastSnap: $lastSNAP"
99  sleep 5
100   
101  # Lets start pulling our ZFS replication
102  zSEND="ssh -p $SSHPORT ${SSHKEY} ${SSHUSER}@${SSHHOST} zfs send -Rv ${ZFSDATASET}@${lastSNAP}"
103  zRECV="zfs receive -evuF ${ZPOOLNAME}"
104  $zSEND | $zRECV
105  if [ $? -ne 0 ] ; then
106     exit_err "Failed ZFS send / receive"
107  fi
108
109  # OK, with all the ZFS datasets received, we can now rename
110  echo_log "Moving datasets to correct locations"
111  for i in `zfs list -d 2 $ZPOOLNAME | grep -v "^NAME" | awk '{print $1}'`
112  do
113    tDir=`basename ${i}`
114    if [ "$tDir" = "$i" ]; then continue ; fi
115
116    rc_halt "zfs rename -u ${i} ${ZPOOLNAME}/${tDir}"
117  done
118
119  # Lets create our placeholder snapshots on the zpool
120  echo_log "Cloning snapshots on zpool.."
121  hName=`basename $ZFSDATASET`
122  zfs list -d 1 -H -t snapshot ${ZPOOLNAME}/${hName} >${TMPDIR}/.zsnaps
123  while read line
124  do
125    zSnap="`echo $line | awk '{print $1}' | cut -d '@' -f 2`"
126    rc_halt "zfs snapshot ${ZPOOLNAME}@$zSnap"
127  done < ${TMPDIR}/.zsnaps
128  rm ${TMPDIR}/.zsnaps
129
130  # Delete the old hostname dataset
131  rc_halt "zfs destroy -r ${ZPOOLNAME}/${hName}"
132
133  # Lets export / import the pool
134  rc_halt "cp /boot/zfs/zpool.cache ${TMPDIR}/zpool.cache"
135  rc_halt "zpool export ${ZPOOLNAME}"
136  rc_halt "zpool import -R ${FSMNT} ${ZPOOLNAME}"
137
138  # Lets mount the default dataset
139  rc_halt "mount -t zfs ${ZPOOLNAME}/ROOT/default ${FSMNT}"
140
141  echo_log "Setting ZFS dataset properties.."
142  # Now lets read in our ZFS properties and reset them
143  while read zLine
144  do
145      dSet="`echo $zLine | awk '{print $1}' | cut -d '@' -f 2- | cut -d '/' -f 2-`"
146      prop="`echo $zLine | awk '{print $2}'`"
147      val="`echo $zLine | awk '{print $3}'`"
148      dChk="`echo $zLine | awk '{print $1}'`"
149
150      # We can skip setting mountpoint on BEs
151      echo $dSet | grep -q '^ROOT/'
152      if [ $? -eq 0 -a "$prop" = "mountpoint" ] ; then continue; fi
153
154      echo "$dChk" | grep -q '@'
155      if [ $? -eq 0 ] ; then
156        rc_halt "zfs set ${prop}=${val} ${ZPOOLNAME}@${dSet}"
157        continue
158      fi
159      echo "$dChk" | grep -q '/'
160      if [ $? -eq 0 ] ; then
161        rc_halt "zfs set ${prop}=${val} ${ZPOOLNAME}/${dSet}"
162        continue
163      fi
164      if [ "$dSet" = "$dChk" ] ; then
165        if [ "$prop" = "mountpoint" ] ; then continue; fi
166        rc_halt "zfs set ${prop}=${val} ${ZPOOLNAME}"
167        continue
168      fi
169  done < ${ZPFILE}
170
171  # Lastly, lets set bootfs
172  rc_halt "zpool set bootfs=${ZPOOLNAME}/ROOT/default ${ZPOOLNAME}"
173
174}
175
176restore_stamp_grub()
177{
178  rc_halt "cp ${TMPDIR}/zpool.cache /boot/zfs/zpool.cache"
179  setup_grub
180}
181
182restore_umount_zfs()
183{
184   umount_all_dir "${FSMNT}"
185}
Note: See TracBrowser for help on using the repository browser.