Skip to content

Commit 7697e2c

Browse files
committed
Add option to preserve SD to USB cmdline.txt boots
Implemented Peter Collinson's idea for preserving the SD card cmdline.txt that is set up to boot to USB when cloning from USB back to the SD card. Update README.md examples.
1 parent d00c0d1 commit 7697e2c

File tree

2 files changed

+162
-66
lines changed

2 files changed

+162
-66
lines changed

README.md

Lines changed: 113 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ the original. See the examples below.
55

66
rpi-clone is a shell script that is for cloning a running
77
Raspberry Pi booted source disk (SD card or USB disk) to a destination
8-
disk which will be bootable. Destination disks are SD cards in a
9-
USB card reader, USB flash disks, or USB hard drives.
8+
disk which will be bootable. Destination disks are SD cards in the SD
9+
card slot or a USB card reader, USB flash disks, or USB hard drives.
1010

1111
rpi-clone may work in SD card booted devices other than a
1212
Raspberry Pi because when initializing a disk, rpi-clone images a
@@ -100,16 +100,16 @@ issues are handled in a setup script, then rpi-clone should work fine
100100
creating clone backup disks for a desktop.
101101

102102
## Usage
103-
See the examples below. To get a usage screen showing available options,
103+
To get a usage screen showing available options,
104104
run rpi-clone without any arguments:
105105
```
106106
pi@rpi0: $ sudo ./rpi-clone
107107
No destination disk given.
108108
109109
usage: rpi-clone sdN {-v|--verbose} {-f|--force-initialize}
110110
{-u|--unattended} {-U|--Unattended} {-q|--quiet}
111-
{-s|--setup} {-e|--edit-fstab name }
112-
{-m|--mountdir dir }
111+
{-s|--setup} {-e|--edit-fstab sdX }
112+
{-m|--mountdir dir } {-l|--leave-sd-usb-boot}
113113
{-a|--all-sync} {-F|--Force-sync} {-x} {-V|--version}
114114
115115
-v - verbose rsync, list all files as they are copied.
@@ -126,22 +126,21 @@ usage: rpi-clone sdN {-v|--verbose} {-f|--force-initialize}
126126
device 'sdX'. This is Only for fstabs that use device names.
127127
-m dir - Add dir to a custom list of mounted directories to sync. The
128128
root directory is always synced. NA when initializing.
129+
-l - leave SD card to USB boot alone when cloning to SD card mmcblk0
130+
from a USB boot. This preserves a SD card to USB boot setup.
129131
-a - Sync all partitions if types compatible, not just mounted ones.
130132
-F - force file system sync even if errors.
131133
If source used > destination space error, do the sync anyway.
132134
If a source partition mount error, skip it and do other syncs.
133135
-x - use set -x for very verbose bash shell script debugging
134136
-V - print rpi-clone version.
135137
```
136-
+ If /etc/fstab uses device names:
137-
+ SD card to bootable USB flash or hard disk clones: use "-e sdX"
138-
to set up the destination fstab and cmdline.txt.
139-
+ USB disk to SD card slot (mmcblk0) clones: "-e mmcblk0p" is assumed.
138+
+ See examples below for command line options usage.
140139
+ rpi-clone version 1 briefly had a -s option that is replaced with a
141140
-s option that has different meaning.
142141

143142
## rpi-clone Example Runs
144-
#### 1) First clone to a new SD card
143+
#### 1) First clone to a new SD card in USB card reader
145144
In this example a new SD card in a USB card reader has been plugged in
146145
that I want to clone to. It shows up as sdb because I have another USB
147146
disk sda plugged in. Look in /proc/partitions to see where yours is.
@@ -182,7 +181,7 @@ Optional destination rootfs /dev/sdb2 label (16 chars max): SD-RPI-8a
182181
...
183182
```
184183

185-
#### 2) Subsequent clone to the same SD card as example 1
184+
#### 2) Subsequent clone to the same SD card in USB card reader as example 1
186185
This time the destination partition type will match the source booted
187186
types, and I'll add a rpi-clone-setup script -s arg to set a
188187
different destination disk hostname.
@@ -210,54 +209,113 @@ Verbose mode : no
210209
Ok to proceed with the clone? (yes/no):
211210
```
212211

213-
#### 3) Creating a USB bootable disk - fstab uses device names
214-
Assuming the destination USB flash or hard drive disk shows up as sdb
215-
when plugged in, run the command:
216-
```
217-
$ rpi-clone -e sda sdb
218-
```
219-
+ Destination disk "sdb" will be synced (or initialized if required).
220-
+ The "-e sda" means to edit the destination /etc/fstab to use "sda"
221-
for the root (will be sda1) and /boot (will be sda2) lines.
222-
Also, the destination disk /boot/cmdline.txt
223-
will be edited to use root=/dev/sda2.
224-
I am expecting that when the disk is plugged in for booting
225-
to, it will be sda.
226-
+ rpi-clone will not edit the currently booted SD card cmdline.txt, so
227-
the destination cannot be USB booted until there is a boot with a SD card
228-
plugged in that has had its /boot/cmdline.txt edited as well. The edit
229-
will need to set root=/dev/sda2.
230-
231-
Now when the Pi is booted with a SD card that has a root=/dev/sda2 in its
232-
cmdline.txt, sda2 will be the root that is booted. The fstab there will
233-
cause /dev/sda1 to be mounted on /boot. So, after the boot, the /boot from
234-
the SD card that initiated the boot is not being used.
235-
236-
#### 4) Cloning back to a mmcblk0 SD card from a USB boot - fstab uses device names
237-
For this example, assume the USB bootable disk created in example 3
238-
has been booted. The SD card used to initiate the boot is no longer in use
239-
because the booted file system has /boot mounted from /dev/sda1 as was
240-
edited into the fstab and not /dev/mmcblk0p1.
241-
So the SD card can be removed and another inserted that
242-
I want to clone to. I do that and run:
243-
```
244-
$ rpi-clone mmcblk0
245-
````
246-
+ The destination disk mmcblk0 will be synced or initialized.
247-
+ When cloning to mmcblk0, rpi-clone knows that it is an SD card
248-
and assumes the fstab and cmdline.txt need to edited so that the
249-
card will be bootable. So "-e mmcblk0p" is assumed and does not need
250-
to be given in the rpi-clone command.
251-
252-
253-
#### 5) Cloning a Pi3 when fstab uses PARTUUID
254-
If fstab and cmdline.txt use PARTUUID, rpi-clone always edits
212+
#### 3) Cloning a Pi3 when fstab uses PARTUUID
213+
If fstab and cmdline.txt use PARTUUID as is the case in recent
214+
Raspbian distributions, rpi-clone always edits**
255215
the destination fstab and cmdline.txt to use the PARTUUID of the
256216
destination disk. So the destination is always bootable. If it
257217
is a USB flash or hard drive it is automatically bootable on a Pi3
258218
as a USB disk so long as the Pi3 has been USB boot enabled with
259-
a program_usb_boot_mode=1 line in /boot/config.txt. No special
260-
-e command line arg or SD card preparation is necessary.
219+
a program_usb_boot_mode=1 line in /boot/config.txt.
220+
221+
** There is one exception. When using the -l option, which is used for
222+
creating or preserving a special SD card to USB boot, the cmdline.txt
223+
on the SD card is not edited after a clone to the SD card, see
224+
examples 4 and 5.
225+
226+
#### 4) Creating a USB bootable disk for other than a USB enabled Pi3
227+
+ Warning Note: I have to consider this example experimental because
228+
after doing it on a Pi using device names, /dev/sda1 was not mounted
229+
on /boot after the boot completed but syslog said it did mount.
230+
And after booting a "mount /boot" command worked so the fstab was right.
231+
So far I don't know where the problem is.
232+
In any case, if you do this example, check /boot after
233+
the USB boot to make sure it was mounted. This should not affect
234+
example 5 which works, but don't do example 5 until you are sure the
235+
USB boot has /dev/sda1 mounted on /boot.
236+
237+
rpi-clone can be used to create a SD card to USB boot setup and preserve
238+
that setup when cloning from a USB boot back to the SD card slot.
239+
With the SD card booted and a target USB disk plugged in and assuming
240+
the USB disk shows up as sda, the initial clone command depends on
241+
fstab usage of device names or PARTUUID.
242+
243+
=> Before you do this, have a backup of your booted SD card made
244+
as in example 2 without the -l option because these steps will
245+
change the booted SD card cmdline.txt to a USB boot.
246+
247+
If fstab is using PARTUUID, run:
248+
```
249+
$ rpi-clone -l sda
250+
```
251+
Or if fstab is using device names, run:
252+
```
253+
$ rpi-clone -l -e sda sda
254+
```
255+
+ Destination disk "sda" will be synced or initialized if required (or add
256+
the -f option to force initialize).
257+
+ After files are synced the destination sda fstab and cmdline.txt will
258+
be edited to reference either device names or PARTUUID for the USB disk.
259+
For the fstab uses device names case, the "-e sda" means to edit the
260+
destination /etc/fstab to use "sda" for the root (will be sda1) and
261+
/boot (will be sda2) lines. Also, the destination disk /boot/cmdline.txt
262+
will be edited to use root=/dev/sda2. It is expected that when the USB disk
263+
is plugged in for booting to, it will be sda and this will be a cause
264+
of boot failure if it is not. So using PARTUUID is better because that
265+
will reliably boot.
266+
+ The -l option causes the SD card cmdline.txt to be backed up to
267+
cmdline.boot and the destination USB disk cmdline.txt to be copied
268+
to the SD card. Since the USB cmdline.txt was edited to reference
269+
the USB disk, the next Pi boot will start with the SD card
270+
/boot partition, but will redirect to using the USB root partition.
271+
Since the USB fstab was edited to reference the USB disk, the Pi will boot
272+
with the USB partition 1 mounted on /boot.
273+
The SD card /boot partition that initiated the boot process
274+
is no longer in use but can remain in place for subsequent
275+
SD card to USB boots. To make the SD card standalone bootable
276+
again, its cmdline.boot can be moved back to cmdline.txt.
277+
278+
+ If -l is not used, rpi-clone will not replace the currently booted SD card
279+
cmdline.txt and it will need to be edited by hand for the USB boot to work.
280+
281+
Now when the Pi is booted from SD card to USB and the SD card is no longer
282+
in use, the SD card slot is available for cloning to.
283+
284+
#### 5) Cloning back to SD cards in the SD card slot from USB boots
285+
Whether the boot was a Pi3 straight to USB or a SD card to USB,
286+
the SD card is not in use so it is free** to clone back to. This
287+
creates a standalone bootable SD card:
288+
```
289+
$ rpi-clone mmcblk0
290+
```
291+
However, for the case where the boot was SD card to USB,
292+
this destroys the ability of the SD card to boot to USB.
293+
To preserve that SD to USB boot setup, run:
294+
```
295+
$ rpi-clone -l mmcblk0
296+
```
297+
+ The SD card is cloned to as before. It now has the USB /boot/cmdline.txt.
298+
+ But the -l option prevents editing that cmdline.txt to reference the SD card.
299+
It is left alone so that it still references the USB root partition.
300+
So the clone has created USB disk to SD card backup while preserving
301+
the SD card to USB boot setup. On the SD card a backup cmdline.boot
302+
is created and edited to reference the SD card. That backup can be moved
303+
to be cmdline.txt to make the SD card standalone bootable should
304+
you ever want to do that.
305+
Or you could just clone to the SD card without using -l.
306+
+ Both above mmcblk0 clone commands apply whether using PARTUUID or
307+
device names. When using device names and cloning to SD cards,
308+
rpi-clone knows fstab device names need editing so "-e mmcblk0p" is assumed.
309+
Now the SD card can be left in permanently and periodically cloned to for
310+
backups and reboots to USB will work as you want. Or other SD
311+
cards can be inserted to create a set of backups.
312+
If making a clone for another Pi that will be SD card bootable, don't use -l.
313+
+ **Warning: this works if the original SD card to USB boot setup has edited
314+
the USB /etc/fstab to reference USB partitions as is done by rpi-clone
315+
when creating a USB bootable disk with -l. If you have an existing
316+
SD card to USB boot setup where this was not done, then your USB boot
317+
likely has the SD card /boot partition mounted, the SD card is in use
318+
and using rpi-clone for a clone back to the SD card slot will not work.
261319

262320

263321
#### 6) Creating a Pi3 bootable USB hard drive with extra partitions

rpi-clone

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash
22

3-
version=2.0.1
3+
version=2.0.2
44

55
PGM=`basename $0`
66
setup_command="$PGM-setup"
@@ -67,8 +67,8 @@ usage()
6767
echo $"
6868
usage: $PGM sdN {-v|--verbose} {-f|--force-initialize}
6969
{-u|--unattended} {-U|--Unattended} {-q|--quiet}
70-
{-s|--setup} {-e|--edit-fstab name }
71-
{-m|--mountdir dir }
70+
{-s|--setup} {-e|--edit-fstab sdX }
71+
{-m|--mountdir dir } {-l|--leave-sd-usb-boot}
7272
{-a|--all-sync} {-F|--Force-sync} {-x} {-V|--version}
7373
7474
-v - verbose rsync, list all files as they are copied.
@@ -85,6 +85,8 @@ usage: $PGM sdN {-v|--verbose} {-f|--force-initialize}
8585
device 'sdX'. This is Only for fstabs that use device names.
8686
-m dir - Add dir to a custom list of mounted directories to sync. The
8787
root directory is always synced. NA when initializing.
88+
-l - leave SD card to USB boot alone when cloning to SD card mmcblk0
89+
from a USB boot. This preserves a SD card to USB boot setup.
8890
-a - Sync all partitions if types compatible, not just mounted ones.
8991
-F - force file system sync even if errors.
9092
If source used > destination space error, do the sync anyway.
@@ -101,8 +103,8 @@ usage: $PGM sdN {-v|--verbose} {-f|--force-initialize}
101103
102104
$ sudo rpi-clone sda
103105
104-
$PGM can be from a booted SD card or USB disk. For a complete description
105-
and examples, see the README.md at:
106+
Clones can be from a booted SD card or USB disk. For a description, example
107+
clone runs and example usage of above options, see the README.md at:
106108
107109
https://github.com/billw2/rpi-clone
108110
@@ -386,6 +388,25 @@ print_options()
386388
return
387389
fi
388390
echo $"---------------------------------------------------------------------------"
391+
392+
if [ "$edit_fstab_name" != "" ]
393+
then
394+
printf "%-22s : %s\n" "-e clone fstab edit" \
395+
"edit $src_part_base device entries to $edit_fstab_name"
396+
fi
397+
if ((leave_sd_usb_boot))
398+
then
399+
if ((SD_slot_dst))
400+
then
401+
msg="leave SD card cmdline.txt bootable to USB"
402+
elif ((SD_slot_boot))
403+
then
404+
msg="install boot to USB cmdline.txt on SD card"
405+
else
406+
msg="-l ignored. Src or dst is not a SD card slot."
407+
fi
408+
printf "%-22s : %s\n" "-l SD to USB boot mode" "$msg"
409+
fi
389410
if [ "$setup_args" != "" ]
390411
then
391412
printf "%-22s : %s\n" "Run setup script" "$setup_command $setup_args"
@@ -403,7 +424,7 @@ get_src_disk()
403424
num="${partition: -1}"
404425
if [[ $disk == *"mmcblk"* ]]
405426
then
406-
SD_card_boot=1
427+
SD_slot_boot=1
407428
disk=${disk:0:7}
408429
src_part_base=${disk}p
409430
fi
@@ -416,7 +437,8 @@ get_src_disk()
416437
#
417438
src_boot_dev=`findmnt /boot -o source -n`
418439
src_root_dev=`findmnt / -o source -n`
419-
SD_card_boot=0
440+
SD_slot_boot=0
441+
SD_slot_dst=0
420442
src_part_base=""
421443

422444
boot_part_num=0
@@ -445,7 +467,7 @@ fi
445467

446468
if [ "$src_disk" != "$src_root_disk" ]
447469
then
448-
if ((SD_card_boot))
470+
if ((SD_slot_boot))
449471
then
450472
# Handle SD card boots with root on different USB disk device.
451473
# But will assume SD card has a root partition just above its root.
@@ -591,7 +613,7 @@ unattended=0
591613
Unattended=0
592614
quiet=0
593615
custom_sync=0
594-
616+
leave_sd_usb_boot=0
595617

596618
while [ "$1" ]
597619
do
@@ -660,6 +682,9 @@ do
660682
fi
661683
custom_sync=1
662684
;;
685+
-l|--leave-sd-usb-boot)
686+
leave_sd_usb_boot=1
687+
;;
663688
-F|--Force-sync)
664689
force_sync=1
665690
;;
@@ -777,6 +802,7 @@ if [[ ${chk_disk: -1} =~ ^[0-9]$ ]]
777802
then
778803
if [[ $dst_disk == *"mmcblk"* ]]
779804
then
805+
SD_slot_dst=1
780806
dst_part_base=${dst_disk}p
781807
if [ "$edit_fstab_name" == "" ]
782808
then
@@ -1278,11 +1304,17 @@ done
12781304

12791305
# Fix PARTUUID or device name references in cmdline.txt and fstab
12801306
#
1281-
cmdline_txt=${clone}/boot/cmdline.txt
12821307
fstab=${clone}/etc/fstab
1308+
cmdline_txt=${clone}/boot/cmdline.txt
12831309

12841310
if [ -f $cmdline_txt ]
12851311
then
1312+
if ((leave_sd_usb_boot && SD_slot_dst))
1313+
then
1314+
qecho "=> Leaving SD to USB boot alone."
1315+
cp $cmdline_txt ${clone}/boot/cmdline.boot
1316+
cmdline_txt=${clone}/boot/cmdline.boot
1317+
fi
12861318
if grep -q $src_disk_ID $cmdline_txt
12871319
then
12881320
qecho "=> Editing $cmdline_txt PARTUUID to use $dst_disk_ID"
@@ -1291,7 +1323,13 @@ then
12911323
then
12921324
qecho "=> Editing $cmdline_txt references from $src_part_base to $edit_fstab_name"
12931325
sed -i "s/${src_part_base}/$edit_fstab_name/" "$cmdline_txt"
1294-
fi
1326+
fi
1327+
if ((leave_sd_usb_boot && SD_slot_boot))
1328+
then
1329+
qecho "=> Copying USB cmdline.txt to SD card to set up USB boot."
1330+
cp /boot/cmdline.txt /boot/cmdline.boot
1331+
cp $cmdline_txt /boot/cmdline.txt
1332+
fi
12951333
fi
12961334

12971335
if grep -q $src_disk_ID $fstab

0 commit comments

Comments
 (0)