]>
sourceware.org Git - lvm2.git/blob - scripts/vgimportclone.sh
3 # Copyright (C) 2009 Chris Procter All rights reserved.
4 # Copyright (C) 2009 Red Hat, Inc. All rights reserved.
6 # This file is part of LVM2.
8 # This copyrighted material is made available to anyone wishing to use,
9 # modify, copy, or redistribute it subject to the terms and conditions
10 # of the GNU General Public License v.2.
12 # You should have received a copy of the GNU General Public License
13 # along with this program; if not, write to the Free Software Foundation,
14 # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 # vgimportclone: This script is used to rename the VG and change the associated
17 # VG and PV UUIDs (primary application being HW snapshot restore)
19 # following external commands are used throughout the script
20 # echo and test are internal in bash at least
31 # user may override lvm location by setting LVM_BINARY
32 LVM
="${LVM_BINARY:-lvm}"
40 "$LVM" version
>& /dev
/null || die
2 "Could not run lvm binary '$LVM'"
44 ### get a unique vg name
45 ### $1 = list of exists VGs
46 ### $2 = the name we want
51 BNAME
="${NEWVG:-${VG}}"
55 while [[ "${VGLIST}" =~
"${NAME}" ]]
65 ### check return value and error if non zero
68 die
$1 "$2, error: $1"
74 ### display usage message
75 echo "Usage: ${SCRIPTNAME} [options] PhysicalVolume [PhysicalVolume...]"
76 echo " -n|--basevgname - Base name for the new volume group(s)"
77 echo " -i|--import - Import any exported volume groups found"
78 echo " -t|--test - Run in test mode"
79 echo " --quiet - Suppress output"
80 echo " -v|--verbose - Set verbose level"
81 echo " -d|--debug - Set debug level"
82 echo " --version - Display version information"
83 echo " -h|--help - Display this help message"
90 #set to use old lvm.conf
91 LVM_SYSTEM_DIR
=${ORIG_LVM_SYS_DIR}
93 if [ $KEEP_TMP_LVM_SYSTEM_DIR -eq 1 ]; then
94 echo "${SCRIPTNAME}: LVM_SYSTEM_DIR (${TMP_LVM_SYSTEM_DIR}) must be cleaned up manually."
96 "$RM" -rf -- "${TMP_LVM_SYSTEM_DIR}"
100 SCRIPTNAME
=`"$BASENAME" $0`
103 if [ "$UID" != "0" -a "$EUID" != "0" ]
105 die
3 "${SCRIPTNAME} must be run as root."
111 # for compatibility: using mktemp -t rather than --tmpdir
112 TMP_LVM_SYSTEM_DIR
=`"$MKTEMP" -d -t snap.XXXXXXXX`
113 KEEP_TMP_LVM_SYSTEM_DIR
=0
121 if [ -n "${LVM_SYSTEM_DIR}" ]; then
122 export ORIG_LVM_SYS_DIR
="${LVM_SYSTEM_DIR}"
125 trap cleanup
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
127 #####################################################################
128 ### Get and check arguments
129 #####################################################################
130 OPTIONS
=`"$GETOPT" -o n:dhitv \
131 -l basevgname:,debug,help,import,quiet,test,verbose,version \
132 -n "${SCRIPTNAME}" -- "$@"`
133 [ $?
-ne 0 ] && usage
134 eval set -- "$OPTIONS"
140 NEWVG
="$2"; shift; shift
150 LVM_OPTS
="--quiet ${LVM_OPTS}"
154 let VERBOSE_COUNT
=VERBOSE_COUNT
+1
159 VERBOSE
="${VERBOSE}v"
190 # turn on DEBUG (special case associated with -v use)
191 if [ -z "$DEBUG" -a $VERBOSE_COUNT -gt 3 ]; then
197 if [ -n "${DEBUG}" -o -n "${VERBOSE}" ]
199 LVM_OPTS
="${LVM_OPTS} ${DEBUG} ${VERBOSE}"
202 # process remaining arguments (which should be disks)
207 PVS_OUT
=`"${LVM}" pvs ${LVM_OPTS} --noheadings -o vg_name "$ARG" 2>/dev/null`
208 checkvalue $?
"$ARG is not a PV."
209 PV_VGNAME
=$
(echo $PVS_OUT |
$GREP -v '[[:space:]]+$')
210 [ -z "$PV_VGNAME" ] && die
3 "$ARG is not in a VG."
212 ln -s "$ARG" ${TMP_LVM_SYSTEM_DIR}/vgimport
${DEVNO}
213 DISKS
="${DISKS} ${TMP_LVM_SYSTEM_DIR}/vgimport${DEVNO}"
214 DEVNO
=$
((${DEVNO}+1))
216 die
3 "$ARG is not a block device."
220 ### check we have suitable values for important variables
226 #####################################################################
227 ### Get the existing state so we can use it later
228 #####################################################################
230 OLDVGS
=`"${LVM}" vgs ${LVM_OPTS} -o name --noheadings 2>/dev/null`
231 checkvalue $?
"Current VG names could not be collected without errors"
233 #####################################################################
234 ### Prepare the temporary lvm environment
235 #####################################################################
237 for BLOCK
in ${DISKS}
239 FILTER
="\"a|^${BLOCK}$|\", ${FILTER}"
241 export FILTER
="filter=[ ${FILTER} \"r|.*|\" ]"
243 LVMCONF
=${TMP_LVM_SYSTEM_DIR}/lvm.conf
245 # FIXME convert to cmdline override
246 "$LVM" dumpconfig
${LVM_OPTS} | \
247 "$AWK" -v DEV
=${TMP_LVM_SYSTEM_DIR} -v CACHE
=${TMP_LVM_SYSTEM_DIR}/.cache \
248 -v CACHE_DIR
=${TMP_LVM_SYSTEM_DIR}/cache \
249 '/^[ \t]*filter[ \t]*=/{print ENVIRON["FILTER"];next} \
250 /^[ \t]*scan[ \t]*=/{print "scan = [ \"" DEV "\" ]";next} \
251 /^[ \t]*cache[ \t]*=/{print "cache = \"" CACHE "\"";next} \
252 /^[ \t]*use_lvmetad[ \t]*=/{print "use_lvmetad = 0";next} \
253 /^[ \t]*cache_dir[ \t]*=/{print "cache_dir = \"" CACHE_DIR "\"";next} \
254 {print $0}' > ${LVMCONF}
256 checkvalue $?
"Failed to generate ${LVMCONF}"
257 # Only keep TMP_LVM_SYSTEM_DIR if it contains something worth keeping
258 [ -n "${DEBUG}" ] && KEEP_TMP_LVM_SYSTEM_DIR
=1
260 # verify the config contains the filter, scan and cache_dir (or cache) config keywords
261 "$GREP" -q '^[[:space:]]*filter[[:space:]]*=' ${LVMCONF} || \
262 die
5 "Temporary lvm.conf must contain 'filter' config."
263 "$GREP" -q '^[[:space:]]*scan[[:space:]]*=' ${LVMCONF} || \
264 die
6 "Temporary lvm.conf must contain 'scan' config."
266 # check for either 'cache' or 'cache_dir' config values
267 "$GREP" -q '[[:space:]]*cache[[:space:]]*=' ${LVMCONF}
269 "$GREP" -q '^[[:space:]]*cache_dir' ${LVMCONF}
271 [ $CACHE_RET -eq 0 -o $CACHE_DIR_RET -eq 0 ] || \
272 die
7 "Temporary lvm.conf must contain 'cache' or 'cache_dir' config."
274 ### set to use new lvm.conf
275 export LVM_SYSTEM_DIR
=${TMP_LVM_SYSTEM_DIR}
278 #####################################################################
279 ### Rename the VG(s) and change the VG and PV UUIDs.
280 #####################################################################
282 PVINFO
=`"${LVM}" pvs ${LVM_OPTS} -o pv_name,vg_name,vg_attr --noheadings --separator : 2>/dev/null`
283 checkvalue $?
"PV info could not be collected without errors"
285 # output VG info so each line looks like: name:exported?:disk1,disk2,...
286 VGINFO
=`echo "${PVINFO}" | \
287 "$AWK" -F : '{{sub(/^[ \t]*/,"")} \
288 {sub(/unknown device/,"unknown_device")} \
289 {vg[$2]=$1","vg[$2]} if($3 ~ /^..x/){x[$2]="x"}} \
290 END{for(k in vg){printf("%s:%s:%s\n", k, x[k], vg[k])}}'`
291 checkvalue $?
"PV info could not be parsed without errors"
295 VGNAME
=`echo "${VG}" | "$CUT" -d: -f1`
296 EXPORTED
=`echo "${VG}" | "$CUT" -d: -f2`
297 PVLIST
=`echo "${VG}" | "$CUT" -d: -f3- | "$TR" , ' '`
299 if [ -z "${VGNAME}" ]
302 for DEV
in $PVLIST; do
303 FOLLOW
=`"$READLINK" $DEV`
304 FOLLOWLIST
="$FOLLOW $FOLLOWLIST"
306 die
8 "Specified PV(s) ($FOLLOWLIST) don't belong to a VG."
309 if [ -n "${EXPORTED}" ]
311 if [ ${IMPORT} -eq 1 ]
313 "$LVM" vgimport
${LVM_OPTS} ${TEST_OPT} "${VGNAME}"
314 checkvalue $? "Volume Group
${VGNAME} could not be imported
"
316 echo "Volume Group
${VGNAME} exported
, skipping.
"
321 ### change the pv uuids
322 if [[ "${PVLIST}" =~ "unknown
" ]]
324 echo "Volume Group
${VGNAME} has unknown PV
(s
), skipping.
"
325 echo "- Were all associated PV
(s
) supplied as arguments?
"
329 for BLOCKDEV in ${PVLIST}
331 "$LVM" pvchange ${LVM_OPTS} ${TEST_OPT} --uuid ${BLOCKDEV} --config 'global{activation=0}'
332 checkvalue $? "Unable to change PV uuid
for ${BLOCKDEV}"
335 NEWVGNAME=`getvgname "${OLDVGS}" "${VGNAME}" "${NEWVG}"`
337 "$LVM" vgchange ${LVM_OPTS} ${TEST_OPT} --uuid "${VGNAME}" --config 'global{activation=0}'
338 checkvalue $? "Unable to change VG uuid
for ${VGNAME}"
340 ## if the name isn't going to get changed dont even try.
341 if [ "${VGNAME}" != "${NEWVGNAME}" ]
343 "$LVM" vgrename ${LVM_OPTS} ${TEST_OPT} "${VGNAME}" "${NEWVGNAME}"
344 checkvalue $?
"Unable to rename ${VGNAME} to ${NEWVGNAME}"
350 #####################################################################
351 ### Restore the old environment
352 #####################################################################
353 ### set to use old lvm.conf
354 if [ -z "${ORIG_LVM_SYS_DIR}" ]
358 LVM_SYSTEM_DIR
=${ORIG_LVM_SYS_DIR}
361 ### update the device cache and make sure all
362 ### the device nodes we need are straight
363 if [ ${CHANGES_MADE} -eq 1 ]
365 "$LVM" vgscan
${LVM_OPTS} --mknodes
This page took 0.054425 seconds and 5 git commands to generate.