Add USB boots to SD card slot (mmcblk0) clones and update README.md
This commit is contained in:
88
README.md
88
README.md
@@ -95,8 +95,9 @@ handles my /etc/grub.d/ custom menus and fstab, and the script runs
|
||||
grub_install. rpi-clone does handle editing of
|
||||
PARTUUID values in /etc/fstab, but a customized setup script for
|
||||
a desktop might need to handle file system UUID values or device
|
||||
name editing in /etc/fstab and the bootloader config.
|
||||
|
||||
name editing in /etc/fstab and the bootloader config. If these possible
|
||||
issues are handled in a setup script, then rpi-clone should work fine
|
||||
creating clone backup disks for a desktop.
|
||||
|
||||
## Usage
|
||||
See the examples below. To get a usage screen showing available options,
|
||||
@@ -105,8 +106,10 @@ run rpi-clone without any arguments:
|
||||
pi@rpi0: $ sudo ./rpi-clone
|
||||
No destination disk given.
|
||||
|
||||
usage: rpi-clone sdN {-v|--verbose} {-f|--force-initialize} {-u|--unattended}
|
||||
{-U|--Unattended} {-s|--setup} {-m|--mountdir dir }
|
||||
usage: rpi-clone sdN {-v|--verbose} {-f|--force-initialize}
|
||||
{-u|--unattended} {-U|--Unattended}
|
||||
{-s|--setup} {-e|--edit-fstab name }
|
||||
{-m|--mountdir dir }
|
||||
{-a|--all-sync} {-F|--Force-sync} {-x} {-V|--version}
|
||||
|
||||
-v - list all files as they are copied.
|
||||
@@ -118,6 +121,8 @@ usage: rpi-clone sdN {-v|--verbose} {-f|--force-initialize} {-u|--unattended}
|
||||
-s host - add 'host' to args passed to script rpi-clone-setup and run it
|
||||
after cloning but before unmounting partitions. For setting
|
||||
clone disk hostname, but args can be what the script expects.
|
||||
-e sdX - edit fstab to change booted device names to new device 'sdX'.
|
||||
Only for device names. Don't use if fstab uses PARTUUID, etc.
|
||||
-m dir - Add dir to a custom list of mounted directories to sync. The
|
||||
root directory is always synced. NA when initializing.
|
||||
-a - Sync all partitions if types compatible, not just mounted ones.
|
||||
@@ -127,6 +132,12 @@ usage: rpi-clone sdN {-v|--verbose} {-f|--force-initialize} {-u|--unattended}
|
||||
-x - use set -x for very verbose bash shell script debugging
|
||||
-V - print rpi-clone version.
|
||||
```
|
||||
+ If /etc/fstab uses device names:
|
||||
+ SD card to bootable USB flash or hard disk clones: use "-e sdX"
|
||||
to set up the destination fstab and cmdline.txt.
|
||||
+ USB disk to SD card slot (mmcblk0) clones: "-e mmcblk0p" is assumed.
|
||||
+ rpi-clone version 1 briefly had a -s option that is replaced with a
|
||||
-s option that has different meaning.
|
||||
|
||||
## Raspberry Pi SD Card Booted Examples
|
||||
#### First clone to a new SD card
|
||||
@@ -137,7 +148,7 @@ have matching partition types, so the clone is an initialize where
|
||||
the source partition structure is cloned to the destination. Because
|
||||
the destination is smaller, the last partition will be resized down.
|
||||
When disks are initialized a label can be given for the
|
||||
destination a root file system. I do that so I can keep track of
|
||||
destination root file system. I do that so I can keep track of
|
||||
my cloned cards. When you run rpi-clone, it tells you what it will do:
|
||||
```
|
||||
pi@rpi0: $ sudo ./rpi-clone sdb
|
||||
@@ -194,9 +205,9 @@ Ok to proceed with the clone? (yes/no):
|
||||
#### Clone to manually partitioned hard drive
|
||||
I wanted to have a Pi3 hard drive USB boot with extra data partitions
|
||||
and I want to be able to clone back to 2 partition SD cards for use
|
||||
in other SD card booted Pis. So my USB disk, which was showing up
|
||||
as sdc, was manually partitioned with partitions of the appropriate
|
||||
types and file systems made with mkfs.
|
||||
in other SD card booted Pis. So my USB connected hard drive, which
|
||||
was showing up as sdc, was manually partitioned with partitions of
|
||||
the appropriate types and file systems made with mkfs.
|
||||
|
||||
Raspbian on the Raspberry Pi needs for the first two partitions to be:
|
||||
```
|
||||
@@ -204,18 +215,41 @@ Raspbian on the Raspberry Pi needs for the first two partitions to be:
|
||||
1: type c W95 FAT32 (LBA) mkfs -t vfat /dev/sdc1
|
||||
2: type 83 Linux mkfs.ext4 /dev/sdc2
|
||||
```
|
||||
Although the first partition file system cound be mkfs -t vfat -F 32.
|
||||
Although the first partition file system could be mkfs -t vfat -F 32.
|
||||
I made the extra partitions mkfs.ext4 and I made a swap partition for
|
||||
possible later use. Now when rpi-clone is run it will see
|
||||
that the destination disk has matching types for the booted partitions
|
||||
1 and 2, so it will do a sync clone without trying to initialize the
|
||||
destination and my extra partitions 5 and 6 will not be touched.
|
||||
Here's the first clone attempt to my manually partitioned disk.
|
||||
The partition types match so rpi-clone goes straight to a sync clone.
|
||||
Note: when manually preparing like this and you make partition types
|
||||
match, don't forget that you must also make the file systems. rpi-clone
|
||||
won't know if you've forgotten that until it tries to mount the
|
||||
possible later use (since this is a hard drive and not a flash drive).
|
||||
Now when rpi-clone is run it will see that the destination disk has
|
||||
matching types for the booted partitions 1 and 2, so it will do a
|
||||
sync clone without trying to initialize the destination and my extra
|
||||
partitions 5 and 6 will not be touched. This will be the first clone
|
||||
attempt to my manually partitioned disk. The partition types match so
|
||||
rpi-clone will go straight to a sync clone.
|
||||
|
||||
Notes:
|
||||
+ When manually preparing partitions like this and you make partition types
|
||||
match, don't forget that you must also make the matching file systems.
|
||||
rpi-clone won't know if you've forgotten that until it tries to mount the
|
||||
partitions.
|
||||
+ What I say here applies generally, not just for manually partitioned
|
||||
drives. The clone to create a bootable USB disk can work without
|
||||
any additional steps beyond the rpi-clone run I show in
|
||||
this example if you are on a Pi3 that uses PARTUUID in cmdline.txt and fstab
|
||||
because rpi-clone automatically edits those.
|
||||
But if you are using device names and are setting up to have a
|
||||
system that SD card boots but uses a USB root, then you have to add an
|
||||
argument to the rpi-clone run:
|
||||
+ Use the "-e sdX" option and rpi-clone will edit the destination
|
||||
/etc/fstab and /boot/cmdline.txt to reference sdX partition names
|
||||
instead of the SD card mmcblk0p partition names.
|
||||
+ Once you boot your system and are running with a USB root, then the
|
||||
SD card slot is available and you can put a SD card into it and clone
|
||||
the running USB disk back to it. In that case you would
|
||||
run: "rpi-clone mmcblk0". If you do this, rpi-clone assumes you want
|
||||
to make the SD card standalone bootable and assumes "-e mmcblk0p"
|
||||
and you don't have to explicitly add the argument.
|
||||
+ But rpi-clone will not edit the currently booted SD card cmdline.txt.
|
||||
You must do that yourself.
|
||||
|
||||
```
|
||||
pi@rpi0: $ sudo ./rpi-clone sdc
|
||||
|
||||
@@ -242,7 +276,7 @@ Ok to proceed with the clone? (yes/no):
|
||||
|
||||
## Raspberry Pi USB Hard Drive Booted Examples
|
||||
Now I have booted the USB hard drive I cloned to in the example just
|
||||
above. I'm going to show several examples here because things now get
|
||||
above. I'm going to show several examples here because things get
|
||||
interesting with rpi-clone's flexibility.
|
||||
|
||||
#### Routine USB disk clone to 16GB SD card
|
||||
@@ -296,11 +330,15 @@ The destination disk is too small.
|
||||
```
|
||||
rpi-clone sees the mounted partition 5 and wants to clone it but finds
|
||||
there's not enough space on the destination drive and won't let me.
|
||||
A bigger disk is needed to clone all the way through partition 5.
|
||||
|
||||
#### USB disk with mounted partition 5 clone to 16GB SD card try 2
|
||||
I"ve got things I'm working on and don't want to unmount the partition
|
||||
I've got things I'm working on and don't want to unmount the partition
|
||||
to make the clone work, so I use the -m option to tell rpi-clone to
|
||||
only clone root and /boot and exclude the mounted /mnt/mnt directory:
|
||||
only clone root and /boot and exclude any other directory mounts not given
|
||||
with a -m option. You don't need to specify "-m /" because root is
|
||||
always included in a clone. But you can give only one "-m /" option
|
||||
and rpi-clone will clone only the root.
|
||||
```
|
||||
pi@rpi0: ~$ sudo rpi-clone sda -m /boot
|
||||
|
||||
@@ -360,7 +398,9 @@ space, there is a -F option which will allow the clone to proceed
|
||||
anyway. Maybe not a good idea, but the interesting thing about
|
||||
this case is that the sync will actually succeed. That's
|
||||
because the root used space includes an almost 2GB file system based
|
||||
swap file (/var/swap) that will be excluded from the sync.
|
||||
swap file (/var/swap) that will be excluded from the sync. I haven't
|
||||
yet switched to using the hard disk swap partition.
|
||||
This is just a FYI.
|
||||
|
||||
#### USB disk clone to large USB disk
|
||||
If you have an extra backup hard drive, you can clone to it and back up
|
||||
@@ -369,7 +409,9 @@ plugging in a drive I happen to use for backing up my desktop,
|
||||
so the partition types won't match and rpi-clone will want to do an
|
||||
initialize. The part to note is that rpi-clone will tell you the
|
||||
steps it will take when doing an image clone of several partitions.
|
||||
It will even make a swap partition on the destination.
|
||||
It will even make a swap partition on the destination. So, I'll also
|
||||
note that this example gives a clue if you want to try using rpi-clone
|
||||
on a desktop.
|
||||
```
|
||||
pi@rpi0: ~$ sudo rpi-clone sda
|
||||
|
||||
|
110
rpi-clone
110
rpi-clone
@@ -65,8 +65,10 @@ HOSTNAME=`hostname`
|
||||
usage()
|
||||
{
|
||||
echo $"
|
||||
usage: $PGM sdN {-v|--verbose} {-f|--force-initialize} {-u|--unattended}
|
||||
{-U|--Unattended} {-s|--setup} {-m|--mountdir dir }
|
||||
usage: $PGM sdN {-v|--verbose} {-f|--force-initialize}
|
||||
{-u|--unattended} {-U|--Unattended}
|
||||
{-s|--setup} {-e|--edit-fstab name }
|
||||
{-m|--mountdir dir }
|
||||
{-a|--all-sync} {-F|--Force-sync} {-x} {-V|--version}
|
||||
|
||||
-v - list all files as they are copied.
|
||||
@@ -78,6 +80,8 @@ usage: $PGM sdN {-v|--verbose} {-f|--force-initialize} {-u|--unattended}
|
||||
-s host - add 'host' to args passed to script $setup_command and run it
|
||||
after cloning but before unmounting partitions. For setting
|
||||
clone disk hostname, but args can be what the script expects.
|
||||
-e sdX - edit destination fstab to change booted device names to new
|
||||
device 'sdX'. This is Only for fstabs that use device names.
|
||||
-m dir - Add dir to a custom list of mounted directories to sync. The
|
||||
root directory is always synced. NA when initializing.
|
||||
-a - Sync all partitions if types compatible, not just mounted ones.
|
||||
@@ -260,7 +264,7 @@ print_partitions()
|
||||
if ((alt_root_part_num > 0))
|
||||
then
|
||||
echo $"
|
||||
** Assuming destination root partition for the clone is $dst_disk$root_part_num
|
||||
** Assuming destination root partition for the clone is $dst_part_base$root_part_num
|
||||
The root FS mount is not from booted $src_disk. It is ${src_root_dev#/dev/}"
|
||||
|
||||
fi
|
||||
@@ -278,9 +282,9 @@ print_sync_actions()
|
||||
if ((p == root_part_num && alt_root_part_num > 0))
|
||||
then
|
||||
part=${src_root_dev#/dev/}
|
||||
flow="$part to $dst_disk$p"
|
||||
flow="$part to $dst_part_base$p"
|
||||
else
|
||||
flow="to $dst_disk$p"
|
||||
flow="to $dst_part_base$p"
|
||||
fi
|
||||
if ((src_sync_part[p]))
|
||||
then
|
||||
@@ -309,9 +313,9 @@ print_image_actions()
|
||||
if ((p == root_part_num && alt_root_part_num > 0))
|
||||
then
|
||||
part=${src_root_dev#/dev/}
|
||||
flow="$part to $dst_disk$p"
|
||||
flow="$part to $dst_part_base$p"
|
||||
else
|
||||
flow="to $dst_disk$p"
|
||||
flow="to $dst_part_base$p"
|
||||
fi
|
||||
|
||||
action=""
|
||||
@@ -365,7 +369,7 @@ print_options()
|
||||
printf "%-23s:\n" "-----------------------"
|
||||
}
|
||||
|
||||
get_disk()
|
||||
get_src_disk()
|
||||
{
|
||||
partition=${1#/dev/}
|
||||
disk=${partition:: -1}
|
||||
@@ -374,7 +378,7 @@ get_disk()
|
||||
then
|
||||
SD_card_boot=1
|
||||
disk=${disk:0:7}
|
||||
src_part_p="p"
|
||||
src_part_base=${disk}p
|
||||
fi
|
||||
printf -v "${2}" "%s" "$disk"
|
||||
printf -v "${3}" "%s" "$num"
|
||||
@@ -386,7 +390,7 @@ get_disk()
|
||||
src_boot_dev=`findmnt /boot -o source -n`
|
||||
src_root_dev=`findmnt / -o source -n`
|
||||
SD_card_boot=0
|
||||
src_part_p=""
|
||||
src_part_base=""
|
||||
|
||||
boot_part_num=0
|
||||
alt_root_part_num=0
|
||||
@@ -394,12 +398,12 @@ alt_root_part_num=0
|
||||
|
||||
if [ "$src_boot_dev" == "" ]
|
||||
then
|
||||
get_disk "$src_root_dev" "src_disk" "unused"
|
||||
get_src_disk "$src_root_dev" "src_disk" "unused"
|
||||
else
|
||||
get_disk "$src_boot_dev" "src_disk" "boot_part_num"
|
||||
get_src_disk "$src_boot_dev" "src_disk" "boot_part_num"
|
||||
fi
|
||||
|
||||
get_disk "$src_root_dev" "src_root_disk" "root_part_num"
|
||||
get_src_disk "$src_root_dev" "src_root_disk" "root_part_num"
|
||||
|
||||
if [ "$src_disk" == "" ]
|
||||
then
|
||||
@@ -407,6 +411,11 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$src_part_base" == "" ]
|
||||
then
|
||||
src_part_base=$src_disk
|
||||
fi
|
||||
|
||||
if [ "$src_disk" != "$src_root_disk" ]
|
||||
then
|
||||
if ((SD_card_boot))
|
||||
@@ -481,7 +490,7 @@ do
|
||||
src_partition[p]=${src_root_dev#/dev/}
|
||||
src_device[p]=$src_root_dev
|
||||
else
|
||||
src_partition[p]="${src_disk}${src_part_p}${p}"
|
||||
src_partition[p]="${src_part_base}${p}"
|
||||
src_device[p]="/dev/${src_partition[p]}"
|
||||
fi
|
||||
|
||||
@@ -544,7 +553,7 @@ done
|
||||
# command line
|
||||
#
|
||||
setup_args=""
|
||||
|
||||
edit_fstab_name=""
|
||||
verbose="no"
|
||||
|
||||
force_initialize=0
|
||||
@@ -579,6 +588,10 @@ do
|
||||
fi
|
||||
setup_args="$setup_args $1"
|
||||
;;
|
||||
-e|--edit-fstab)
|
||||
shift
|
||||
edit_fstab_name=$1
|
||||
;;
|
||||
-f|--force-initialize)
|
||||
force_initialize=1
|
||||
;;
|
||||
@@ -720,13 +733,24 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dst_part_base=$dst_disk
|
||||
|
||||
if [[ ${chk_disk: -1} =~ ^[0-9]$ ]]
|
||||
then
|
||||
echo $"
|
||||
if [[ $dst_disk == *"mmcblk"* ]]
|
||||
then
|
||||
dst_part_base=${dst_disk}p
|
||||
if [ "$edit_fstab_name" == "" ]
|
||||
then
|
||||
edit_fstab_name=$dst_part_base
|
||||
fi
|
||||
else
|
||||
echo $"
|
||||
Target disk $dst_disk ends with a digit so may be a partition.
|
||||
$PGM requires disk names like 'sda' and not partition names like 'sda1'."
|
||||
|
||||
confirm "Continue anyway?" "abort"
|
||||
confirm "Continue anyway?" "abort"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -740,7 +764,7 @@ dst_partition_table=$(parted -m "/dev/$dst_disk" unit s print | tr -d ';')
|
||||
n_dst_parts=$(echo "$dst_partition_table" | tail -n 1 | cut -d ":" -f 1)
|
||||
dst_disk_size=$(echo "$dst_partition_table" \
|
||||
| grep "^/dev/$dst_disk" | cut -d ":" -f 2 | tr -d 's')
|
||||
dst_root_dev=/dev/${dst_disk}${root_part_num}
|
||||
dst_root_dev=/dev/${dst_part_base}${root_part_num}
|
||||
|
||||
dst_mount_table=$(findmnt -o source,target -n -l -b \
|
||||
| grep "^/dev/$dst_disk" | tr -s " ")
|
||||
@@ -765,7 +789,7 @@ do
|
||||
fi
|
||||
dst_exists[p]=1
|
||||
|
||||
part="${dst_disk}${p}"
|
||||
part="${dst_part_base}${p}"
|
||||
dst_partition[p]="$part"
|
||||
dst_device[p]="/dev/$part"
|
||||
|
||||
@@ -985,14 +1009,12 @@ The destination disk is too small.
|
||||
sync
|
||||
|
||||
sfd0=$(sfdisk -d /dev/$src_disk)
|
||||
# part="$dst_disk$n_src_parts"
|
||||
part="$src_disk$src_part_p$n_src_parts"
|
||||
part="${src_part_base}$n_src_parts"
|
||||
sfd1=$(echo "$sfd0" | sed "\/dev\/$part/s/size=[^,]*,//")
|
||||
|
||||
if ((ext_part_num > 0))
|
||||
then
|
||||
# part="$dst_disk$ext_part_num"
|
||||
part="$src_disk$src_part_p$ext_part_num"
|
||||
part="${src_part_base}$ext_part_num"
|
||||
sfd1=$(echo "$sfd1" | sed "\/dev\/$part/s/size=[^,]*,//")
|
||||
fi
|
||||
|
||||
@@ -1023,7 +1045,7 @@ The destination disk is too small.
|
||||
then
|
||||
continue
|
||||
fi
|
||||
dst_dev=/dev/${dst_disk}${p}
|
||||
dst_dev=/dev/${dst_part_base}${p}
|
||||
fs_type=${src_fs_type[$p]}
|
||||
if ((p == ext_part_num)) \
|
||||
|| [ "$fs_type" == "--" ]
|
||||
@@ -1174,7 +1196,7 @@ do
|
||||
fi
|
||||
sync_msg_done=1
|
||||
mount_partition ${src_device[p]} $clone_src ""
|
||||
mount_partition /dev/$dst_disk$p $clone "$clone_src"
|
||||
mount_partition /dev/${dst_part_base}$p $clone "$clone_src"
|
||||
unmount_list="$clone_src $clone"
|
||||
rsync_file_system "${clone_src}/" "${clone}" ""
|
||||
unmount_list "$unmount_list"
|
||||
@@ -1201,13 +1223,49 @@ do
|
||||
then
|
||||
mkdir -p $dst_dir
|
||||
fi
|
||||
mount_partition /dev/$dst_disk$p "$dst_dir" "$unmount_list"
|
||||
mount_partition /dev/${dst_part_base}$p "$dst_dir" "$unmount_list"
|
||||
rsync_file_system "${src_mounted_dir[p]}/" "${dst_dir}" ""
|
||||
unmount_list="$dst_dir $unmount_list"
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
# Fix asked for device name reference change in fstab
|
||||
#
|
||||
fstab=${clone}/etc/fstab
|
||||
cmdline_txt=${clone}/boot/cmdline.txt
|
||||
|
||||
if [ "$edit_fstab_name" != "" ] \
|
||||
&& grep -q ${src_part_base} ${clone}/etc/fstab
|
||||
then
|
||||
echo "=> Editing $fstab references from $src_part_base to $edit_fstab_name"
|
||||
sed -i "s/${src_part_base}/${edit_fstab_name}/" "$fstab"
|
||||
lines=$(grep "$edit_fstab_name" $fstab)
|
||||
printf " New destination fstab lines:\n$lines\n\n"
|
||||
|
||||
if [ -f $cmdline_txt ] \
|
||||
&& grep -q ${src_part_base} $cmdline_txt
|
||||
then
|
||||
echo "=> Editing $cmdline_txt references from $src_part_base to $edit_fstab_name"
|
||||
sed -i "s/${src_part_base}/$edit_fstab_name/" "$cmdline_txt"
|
||||
printf " New destination cmdline.txt:\n"
|
||||
cat $cmdline_txt
|
||||
echo ""
|
||||
|
||||
if ((SD_card_boot))
|
||||
then
|
||||
echo $"
|
||||
=> ** Warning ** If setting up for a USB boot, you must edit the booted
|
||||
cmdline.txt yourself and set the root= line to root=${edit_fstab_name}${root_part_num}
|
||||
"
|
||||
fi
|
||||
fi
|
||||
elif [ "$edit_fstab_name" != "" ] && ((!SD_card_boot))
|
||||
then
|
||||
echo "
|
||||
=> ** Warning ** ${src_part_base} not found in fstab. Can't edit it."
|
||||
fi
|
||||
|
||||
# Fix PARTUUID references in fstab and cmdline.txt
|
||||
#
|
||||
if grep -q $src_disk_ID ${clone}/etc/fstab
|
||||
|
Reference in New Issue
Block a user