This is a lot on backup/restore (which I think more Jetson owners should consider before their system needs flash). Just get an idea of what method you want to use, and I will add details specific to that method.
I should add some detail regarding recursive copy versus rsync
. For this I am going to pretend that your external media is “/dev/nvme0n2
”, and that the partition you are destroying (we are syncing outside content, what was there previously is expected to be destroyed…don’t do this if you don’t want to lose existing content on that partition) is “/dev/nvme0n2p1
” (which is the first partition, p1
, of nvme0n2
). This could just as easily be some other partition, e.g., “/dev/sdb2
” (which is the second partition of the second SATA device).
If you recursively copy a directory, then its content is like the inside of a binary file…that too gets copied verbatim. As soon as you use copy to name files, this all changes. Suddenly there are file permissions, interpretation of symbolic link, device special files, so on. Directory “/
” is just a single file with content. If you look at a subset of “/
”, you can call it another file or directory, or you could call it binary content of an image. It is a matter of perspective. Backup and restore methods have different viewpoints.
Using dd
implies everything is binary content. There is nothing special about files owned by a particular user, nothing special about executable content, and nothing special about symbolic links.
Recursive copy of a directory, and not naming files, is almost a binary copy (verbatim). What is inside the directory is verbatim unmodified binary content if the user has permission. The directory itself still has to have interpretation of user, group, read/write/execute permissions, so on. You can tell cp
to preserve permissions, but in reality a copy command of a directory (naming the directory only, not its content) is a binary bit-for-bit copy aside from the directory name itself having attributes.
Let’s say you’ve mounted an ext4
partition “/dev/nvme0n2p1
” at “/mnt
”. This is a device boundary (useful to know later on). Some commands can be told to not cross device boundaries. If we copy anything to “/mnt
”, this means it ends up on /dev/nvme0n2p1
. If we use commands such as cp
or rsync
, then we need this mounted.
If we use a purely binary tool, for example, dd
, then we do not mount the device if it is the source of data. Sometimes we don’t even mount the device which is a destination. dd
can write a partition directly, or it can create a file on a partition. dd
of a partition to /dev/nvme0n2p1
, without /dev/nvme0n2p1
being mounted, would create a partition on the NVMe. That partition would have the same UUID, same content, same size. We’re not doing that, but it is useful to understand. When we flash the Jetson, it is a binary command and directly creates partitions…there are no filesystems.
If we want the simplest of tools, and if we have a mounted /dev/nvme0n2p1
on /mnt
, and we want to copy all of “/home
”, then it is easy. This would create a complete backup of “/home
” there:
sudo cp -adpR /home/mnt/
The result is that every file of every type, including the name “home
” itself, goes to “/mnt
”, and “/mnt
” is your NVMe. You wouldn’t directly mount this on “/home
”, it isn’t a binary partition, but it is useful towards reaching that goal.
We can do similar with rsync
, and although more complicated, rsync
is much more flexible and much more powerful. There are variations to do this over ssh
to a remote host…you could do this from the Jetson to a host PC’s drive via the gigabit network if you wish.
Again, assume you have “/dev/nvme0n2p1
” mounted on “/mnt
”. Now you will back up everything in “/home
” in a way similar to the recursive cp
, but this is not going to be quite the same…there are intentional differences (note that I am using the “--dry-run
” option…a very powerful option if you want to see what would happen without actually doing anything…remove --dry-run
to actually do this):
rsync -avczrx --dry-run --numeric-ids --delete-before /home /mnt
root@thanteros:/home/dan/Documents/embedded/L4T/R23.1/clone/rsync_R23.1
Go ahead and mount your ext4
NVMe partition on “/mnt
” and run that command. It uses --dry-run
, and so you will see log messages as if it were really running, but it won’t actually run.
If you keep your backups and restores to one system, then you don’t have to have the --numeric-ids
. cp
isn’t really capable of reliably doing this, but every account in Linux is really a number, and the name on the account is just an alias. A backup with user name owner “nvidia
”, when copied to another computer that has different accounts, will break this. If there is no account with that numeric ID, then only the number shows up. There are cases where missing names or name differences across systems results in a translation and alters the original data. Thus, a true backup requires --numeric-ids
(not always needed, but it is still a good idea).
The “-avczrx
” is just overkill that works in all situations. One of the options is for compression, and this isn’t needed on a local system, but it also doesn’t hurt. In the case of backing up over the network compression is good to have. It is ok to use this in general.
rsync
can perform direct backups, or it can perform incremental backups. The first time you back up it is always the entire content. Later on, if a few files have changed, any attempt to use cp
will recopy everything…even things not changed. rsync
would check for change and only copy what has changed. The larger the content, the more this helps (especially over a network, but it also helps locally).
The --delete-before
removes a safety. If you are performing an incremental backup, the default is to not destroy the previous content until certain all update content is present. Should there be a power outage or a network failure (for remote backup), then not using --delete-before
prevents losing the content during those circumstances. On the other hand, --delete-before
prevents requiring two copies of data. If you were backing up and had a file which is 20 GB in size, then without --delete-before
your destination disk must be 20 GB larger than what it actually contains in the end. The --delete-before
is what I use because (A) I don’t expect a failure during update, (B) if my backup dies, or at least one file dies, I still have a copy, and (C) I’m really almost out of disk space (it is hard to flash newer Jetson with larger partitions because of this). My default is “--delete-before
” to save space.
Let’s look at a variation: Mounting a backup device on “/mnt
” of a separate host PC, and then backing up from Jetson to host PC. For illustration, the backup device partition is “/dev/sdb1
”. I’m going to simplify by saying we are running as root. You can also unlock root on Ubuntu, set up ssh
keys, and then relock root login via password on ssh
, but still have key access (which is very useful). The host PC name will be “master” on the network (perhaps we’ve put this in “/etc/hosts
” as an alias for the host PC on the Jetson):
# On master:
sudo mount /dev/sdb1 /mnt
# On Jetson:
rsync -avczrx -e ssh --dry-run --numeric-ids --delete-before /home root@master:/mnt
Both methods create a “home/
” on the device mounted on “/mnt
” (one case the /mnt
is on the Jetson, the other case is the /mnt
is on a different host PC).
Working entirely locally implies you don’t have to worry about sudo
, it’ll just work.
A summary of some methods:
- Recursive
cp
of a directory (not file names, rsync -avczrx --dry-run --numeric-ids --delete-before /home /mnt
but a directory name) is simple. This works for copy of “/home
” or “/usr/local
”.
rsync
is more powerful. This works when naming specific files as well as directories. This works across different systems and works correctly even for more exotic file types. rsync
is less intensive than cp
if this is an incremental backup.
dd
and cloning are almost the same thing, but clone is better since the system is offline and shut down during the clone. Clone has no issues with files changing during clone.
- Your “
/usr/local
” is larger than your “/home
”. That directory has over 4 GB of content. That directory includes the CUDA development tools. So this is a good candidate.
- Your “
/home
” might be where you compile software. Imagine you are compiling a kernel. In that case the /home
might actually be larger than /usr/local
(at least temporarily). So although smaller, if you intend to work on a large program, and you develop from /home
, then /home
is a better choicde.
- You could have partitions on both “
/usr/local
” and “/home
”.
- Once you have this backed up we can set it up so that it can be mounted over either
/home
or /usr/local
. If it works, then most of the original /usr/local
content can be deleted to provide more space on the eMMC. In the case of /home
you might delete some content, but leave basics in place so that you still have home content when the external disk is not there.