, 6 min read

Copy Arch Linux to SSD

Task at hand: Copy existing Arch Linux installation to new SSD.

1. Partitioning. Partition new SSD. For example use gparted. After partitioning you should have something like

# parted /dev/nvme0n1
GNU Parted 3.5
Using /dev/nvme0n1
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Model: SAMSUNG MZVL22T0HBLB-00B00 (nvme)
Disk /dev/nvme0n1: 2048GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name  Flags
 1      1049kB  269MB   268MB   fat32        boot  boot, esp
 2      269MB   2048GB  2048GB               root

After partitioning then set up encrypted partition using cryptsetup:

# lsblk -if
# parted /dev/nvme0n1
    print
# cryptsetup luksFormat /dev/nvme0n1p2

After creating encrypted partition create filesystem:

# time mkfs.ext4 /dev/mapper/Samsung2TB
mke2fs 1.46.5 (30-Dec-2021)
Creating filesystem with 500029696 4k blocks and 125009920 inodes
Filesystem UUID: 63669b64-5753-44a6-8626-561a6c98ab5b
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
        102400000, 214990848

Allocating group tables: done
Writing inode tables: done
Creating journal (262144 blocks): done
Writing superblocks and filesystem accounting information: done

    real    0m0.418s
    user    0m0.009s
    sys     0m0.037s
# mkdir /mnt/Samsung2TB
# mount /dev/mapper/Samsung2TB /mnt/Samsung2TB/

2. Copy Arch Linux. Copy content:

# cd /mnt/Samsung2TB
# mkdir boot proc run sys tmp
# cp -a /bin .
# cp -a /etc .
# cp -a /home .
# cp -a /lib .
# cp -a /lib64 .
# time cp -a /var .
    real    2m28.198s
    user    0m0.049s
    sys     0m24.790s
# time cp -a /usr .
    real    1m32.441s
    user    0m0.558s
    sys     0m15.943s

Create entries in /mnt:

mkdir c cryptstick cryptstick2 dvd sd SeagatePortable usb usb2

Create home directory for root-user:

mkdir root

3. Boot setup. Prepare /boot for UEFI by copying old boot-content to new directory:

cd /mnt/cboot
cp -p /boot/vmlinuz-linux .
cp -p /boot/initramfs-linux* .

Copy UEFI shell:

cp -p /usr/share/edk2-shell/x64/Shell_Full.efi shellx64.efi

Change startup.nsh:

vmlinuz-linux root=UUID=63669b64-5753-44a6-8626-561a6c98ab5b rw  cryptdevice=/dev/disk/by-uuid/9b0766ca-06ce-41d6-9b46-04c66573f3aa:nvme0n1p2 ip=192.168.178.118:192.168.178.118:192.168.178.1:255.255.255.0:chieftec:eth0:none initrd=\initramfs-linux-fallback.img

Initially you need initramfs-linux-fallback.img. With later kernel updates you then use the initial ramdisk file without the fallback. Above uuid were looked up by:

ls -l /dev/disk/by-uuid

On the new (=target) root filesystem update /etc/fstab accordingly.

4. General observations. Copying the entire home-directory was quite an ordeal. When I just tried to mount the old hard drive and then try to copy the content, the hard drive failed. The next try was to mount the old hard drive just in read-only mode, like this:

mount -o ro,noload,norelatime /dev/mapper/chieftec--vg-root /mnt/c

That way, not only is the hard drive mounted read-only, but also no access times or log file information are recorded on the old drive. This helped and copy operation succeeded:

time cp -a /mnt/c/home/klm .
    real    172m19.446s
    user    0m9.209s
    sys     11m27.208s

I.e., this lasted for almost three hours. It copied more than 3.7 million files. During this time lots of SATA errors occured:

May 02 14:47:12 chieftec kernel: ata4: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
May 02 14:47:12 chieftec kernel: ata4.00: configured for PIO0
May 02 14:47:58 chieftec kernel: ata4: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
May 02 14:47:58 chieftec kernel: ata4.00: configured for PIO0
May 02 14:49:17 chieftec kernel: ata4: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
May 02 14:49:17 chieftec kernel: ata4.00: configured for PIO0
May 02 14:49:19 chieftec kernel: ata2.00: exception Emask 0x10 SAct 0x600 SErr 0x2c0100 action 0x6 frozen
May 02 14:49:19 chieftec kernel: ata2.00: irq_stat 0x08000000, interface fatal error
May 02 14:49:19 chieftec kernel: ata2: SError: { UnrecovData CommWake 10B8B BadCRC }
May 02 14:49:19 chieftec kernel: ata2.00: failed command: READ FPDMA QUEUED
May 02 14:49:19 chieftec kernel: ata2.00: cmd 60/00:48:00:81:2c/02:00:0f:00:00/40 tag 9 ncq dma 262144 in
                                          res 40/00:50:00:83:2c/00:00:0f:00:00/40 Emask 0x10 (ATA bus error)
May 02 14:49:19 chieftec kernel: ata2.00: status: { DRDY }
May 02 14:49:19 chieftec kernel: ata2.00: failed command: READ FPDMA QUEUED
May 02 14:49:19 chieftec kernel: ata2.00: cmd 60/00:50:00:83:2c/02:00:0f:00:00/40 tag 10 ncq dma 262144 in
                                          res 40/00:50:00:83:2c/00:00:0f:00:00/40 Emask 0x10 (ATA bus error)
May 02 14:49:19 chieftec kernel: ata2.00: status: { DRDY }
May 02 14:49:19 chieftec kernel: ata2: hard resetting link
May 02 14:49:19 chieftec kernel: ata2: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
May 02 14:49:19 chieftec kernel: ata2.00: configured for UDMA/133
May 02 14:49:19 chieftec kernel: sd 1:0:0:0: [sda] tag#9 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=0s
May 02 14:49:19 chieftec kernel: sd 1:0:0:0: [sda] tag#9 Sense Key : Illegal Request [current]
May 02 14:49:19 chieftec kernel: sd 1:0:0:0: [sda] tag#9 Add. Sense: Unaligned write command
May 02 14:49:19 chieftec kernel: sd 1:0:0:0: [sda] tag#9 CDB: Read(10) 28 00 0f 2c 81 00 00 02 00 00
May 02 14:49:19 chieftec kernel: I/O error, dev sda, sector 254574848 op 0x0:(READ) flags 0x80700 phys_seg 5 prio class 0
May 02 14:49:19 chieftec kernel: sd 1:0:0:0: [sda] tag#10 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=0s
May 02 14:49:19 chieftec kernel: sd 1:0:0:0: [sda] tag#10 Sense Key : Illegal Request [current]
May 02 14:49:19 chieftec kernel: sd 1:0:0:0: [sda] tag#10 Add. Sense: Unaligned write command
May 02 14:49:19 chieftec kernel: sd 1:0:0:0: [sda] tag#10 CDB: Read(10) 28 00 0f 2c 83 00 00 02 00 00
May 02 14:49:19 chieftec kernel: I/O error, dev sda, sector 254575360 op 0x0:(READ) flags 0x80700 phys_seg 5 prio class 0
May 02 14:49:19 chieftec kernel: ata2: EH complete
May 02 14:49:51 chieftec kernel: ata2.00: exception Emask 0x10 SAct 0xc0000 SErr 0x2c0100 action 0x6 frozen
May 02 14:49:51 chieftec kernel: ata2.00: irq_stat 0x08000000, interface fatal error
May 02 14:49:51 chieftec kernel: ata2: SError: { UnrecovData CommWake 10B8B BadCRC }
May 02 14:49:51 chieftec kernel: ata2.00: failed command: READ FPDMA QUEUED
May 02 14:49:51 chieftec kernel: ata2.00: cmd 60/00:90:00:d5:6c/02:00:0f:00:00/40 tag 18 ncq dma 262144 in
                                          res 40/00:90:00:d5:6c/00:00:0f:00:00/40 Emask 0x10 (ATA bus error)
May 02 14:49:51 chieftec kernel: ata2.00: status: { DRDY }
May 02 14:49:51 chieftec kernel: ata2.00: failed command: READ FPDMA QUEUED
May 02 14:49:51 chieftec kernel: ata2.00: cmd 60/00:98:00:d7:6c/02:00:0f:00:00/40 tag 19 ncq dma 262144 in
                                          res 40/00:90:00:d5:6c/00:00:0f:00:00/40 Emask 0x10 (ATA bus error)
May 02 14:49:51 chieftec kernel: ata2.00: status: { DRDY }
May 02 14:49:51 chieftec kernel: ata2: hard resetting link
May 02 14:49:51 chieftec kernel: ata2: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
May 02 14:49:51 chieftec kernel: ata2.00: configured for UDMA/133

I think I was quite lucky to still get all the data from this old hard drive, even though I do have two backups. Looking up, when I first formatted this disk, it showed I did this eight years ago:

# dumpe2fs /dev/sda1
dumpe2fs 1.46.5 (30-Dec-2021)
Filesystem volume name:   <none>
Last mounted on:          /boot
Filesystem UUID:          83a1bedb-6fd3-46d0-8900-e4e09536168e
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super
Filesystem flags:         signed_directory_hash
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              62248
Block count:              248832
Reserved block count:     12441
Free blocks:              126393
Free inodes:              61933
First block:              1
Block size:               1024
Fragment size:            1024
Reserved GDT blocks:      256
Blocks per group:         8192
Fragments per group:      8192
Inodes per group:         2008
Inode blocks per group:   251
RAID stride:              4
RAID stripe width:        4
Filesystem created:       Mon Apr 21 13:45:32 2014
Last mount time:          Thu Apr 28 10:51:42 2022
Last write time:          Thu Apr 28 10:52:11 2022
Mount count:              37
Maximum mount count:      -1
Last checked:             Sat Dec 12 19:52:48 2015
Check interval:           0 (<none>)
Lifetime writes:          1471 MB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               128
Default directory hash:   half_md4
Directory Hash Seed:      4d77d40d-b806-40da-a989-aee864e30bf4

Time to retire this drive. The new Samsung 2 TB SSD has below header:

# dumpe2fs -h /dev/mapper/nvme0n1p2
dumpe2fs 1.46.5 (30-Dec-2021)
Filesystem volume name:   <none>
Last mounted on:          /
Filesystem UUID:          63669b64-5753-44a6-8626-561a6c98ab5b
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum
Filesystem flags:         signed_directory_hash
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              125009920
Block count:              500029696
Reserved block count:     25001484
Overhead clusters:        8129800
Free blocks:              470004602
Free inodes:              120443053
First block:              0
Block size:               4096
Fragment size:            4096
Group descriptor size:    64
Reserved GDT blocks:      1024
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Flex block group size:    16
Filesystem created:       Sun May  1 11:51:33 2022
Last mount time:          Mon May  2 12:16:54 2022
Last write time:          Mon May  2 12:16:54 2022
Mount count:              10
Maximum mount count:      -1
Last checked:             Sun May  1 11:51:33 2022
Check interval:           0 (<none>)
Lifetime writes:          119 GB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               256
Required extra isize:     32
Desired extra isize:      32
Journal inode:            8
First orphan inode:       100540341
Default directory hash:   half_md4
Directory Hash Seed:      120bab98-bb6d-489c-871f-0570938845db
Journal backup:           inode blocks
Checksum type:            crc32c
Checksum:                 0x0fd2808d
Journal features:         journal_incompat_revoke journal_64bit journal_checksum_v3
Total journal size:       1024M
Total journal blocks:     262144
Max transaction length:   262144
Fast commit length:       0
Journal sequence:         0x0000381e
Journal start:            35399
Journal checksum type:    crc32c
Journal checksum:         0xf81f39b2