2P by GN⁺ | ★ favorite | 댓글 1개
  • 새 노트북을 처음부터 다시 세팅하는 대신, 기존 노트북의 전체 디스크를 NVMe over TCP로 노출해 네트워크로 그대로 복제함
  • 기존 환경은 전체 디스크 암호화와 512GB 디스크를 사용했고, 새 노트북은 1TB NVMe라 복제 뒤 파티션·LUKS·BTRFS 확장이 필요했음
  • 디스크 내보내기는 systemd-storagetm.service 대신 두 노트북을 GRML rescue CD로 부팅하고 nvmet-tcp/sys/kernel/config/nvmet로 구성함
  • 실제 복사는 dd로 진행했으며, 새 노트북에 이더넷 포트가 없어 WiFi만 사용한 결과 512GB 복제에 약 7시간 30분, 속도는 약 18~20MB/s 수준이었음
  • 복제 후 parted, growpart, cryptsetup resize, BTRFS resize를 거쳐 1TB 전체를 쓰도록 조정했고, 기존 노트북 환경을 거의 그대로 이어받을 수 있었음

NVMe over TCP로 기존 디스크 내보내기

  • 새 노트북 설정 절차를 반복하지 않기 위해, 동료의 제안대로 기존 노트북 디스크 전체를 복사하는 방식을 택함

  • 시작 전 걸림돌은 두 가지였음

    • 기존 노트북을 열어 새 디스크를 USB로 연결할 도구가 없었음
    • 기존 노트북은 전체 디스크 암호화와 512GB 디스크를 사용했고, 새 노트북은 1TB NVMe라 LUKS 크기 조정이 필요했음
  • 작업 흐름은 디스크 노출, 복사, 용량 확장의 세 단계로 이어짐

    • 기존 노트북에서 nvmet-tcp로 디스크를 내보냄
    • 새 노트북에서 해당 디스크를 복사함
    • 파티션을 1TB 전체로 확장함
    • LUKS 크기를 조정함
    • 마지막으로 BTRFS 루트 디스크 크기를 조정함
  • systemd-storagetm.service 대신 GRML 사용

    • 가장 쉬운 방법으로는 systemd-storagetm.service를 사용할 수 있었음
    • rd.systemd.unit=storage-target-mode.target를 지정해 storage-target-mode.target로 부팅하면 호출 가능함
    • 다만 이 방식은 dracut initrd 이미지에 네트워크 서비스를 포함해야 하고, 해당 모드에서 WiFi 설정이 번거로워 제외함
    • 대신 두 노트북을 GRML rescue CD로 부팅한 뒤, 기존 노트북에서 Linux의 nvmet-tcp 모듈로 NVMe 디스크를 내보냄
    modprobe nvmet-tcp
    cd /sys/kernel/config/nvmet
    mkdir ports/0
    cd ports/0
    echo "ipv4" > addr_adrfam
    echo 0.0.0.0 > addr_traaddr
    echo 4420 > addr_trsvcid
    echo tcp > addr_trtype
    cd /sys/kernel/config/nvmet/subsystems
    mkdir testnqn
    echo 1 >testnqn/allow_any_host
    mkdir testnqn/namespaces/1
    cd testnqn
    
    
    # replace the device name with the disk you want to export
    echo "/dev/nvme0n1" > namespaces/1/device_path
    echo 1 > namespaces/1/enable
    ln -s "../../subsystems/testnqn" /sys/kernel/config/nvmet/ports/0/subsystems/testnqn
    
    • 이 설정으로 대상 디바이스가 NVMe over TCP로 노출됨
    • 새 노트북에서는 내보낸 디바이스를 검색하고 연결함
    nvme discover -t tcp -a <ip> -s 4420
    nvme connectl-all -t tcp -a <> -s 4420
    
    • 이후 nvme list에서 새 노트북에 연결된 디바이스를 확인하고 디스크 복사를 진행할 수 있음

디스크 복사와 크기 조정

  • dd로 512GB 복사

    • 루트 디스크 복사는 dd 명령으로 수행함
    • 새 노트북에 이더넷 포트가 없어 WiFi만 사용했고, 512GB 전체 복사에는 약 7시간 30분이 걸림
    • 전송 속도는 약 18~20MB/s 수준이었음
    • 다른 선택지로는 초기 파티션과 파일 시스템을 만든 뒤 rsync로 루트 디스크를 복사하거나, BTRFS 자체 파일 시스템 전송을 사용하는 방법이 있었음
    dd if=/dev/nvme2n1 of=/dev/nvme0n1 status=progress bs=40M
    
  • 파티션, LUKS, BTRFS 확장

    • parted는 파티션 테이블이 디스크 크기와 맞지 않음을 감지했고, 수정 여부를 확인한 뒤 자동으로 고침
    • 두 번째 파티션 확장을 위해 cloud-guest-utils를 설치하고 growpart를 사용함
    growpart /dev/nvem0n1 p2
    
    • 다음 단계에서는 cryptsetup으로 LUKS 컨테이너 크기를 늘림
    cryptsetup luksOpen /dev/nvme0n1p2 ENC
    cryptsetup resize ENC
    
    • 디스크로 재부팅한 뒤 정상 동작을 확인했고, 로그인 후 BTRFS 파일 시스템 크기를 조정함
    • BTRFS는 크기 조정을 위해 시스템이 마운트되어 있어야 해서 라이브 부팅 상태에서는 시도할 수 없었음
    btfs fielsystem resize max /
    
    • 결과적으로 새 노트북에서도 기존 노트북을 계속 쓰는 것 같은 환경을 얻음
    • 일반적으로 새 노트북에 완전히 적응하려면 약 1~2주가 걸리지만, 이 방식으로 그 시간을 줄임
    • 부가적으로 NVMe over TCP로 디스크를 내보내는 방법을 익힌 점도 남음

댓글과 토론

Hacker News 의견들
  • 작성자 시나리오에서는 결국 dd(1)직렬 블록 복사만 하므로 NVMe/TCP를 쓸 이점이 거의 없음. 복잡한 명령은 간단한 netcat으로 대체 가능함
    대상 노트북: $ nc -l -p 1234 | dd of=/dev/nvme0nX bs=1M
    원본 노트북: $ nc x.x.x.x 1234
    대상 쪽 dd는 쓰기를 버퍼링해서 더 빠르고 효율적으로 만들기 위한 것임. 원본/대상에 gzip/gunzip을 추가하면 디스크가 꽉 차 있지 않고 0 블록이 많을 때 훨씬 빨라짐. 개인적으로 네트워크로 PC 이미지를 뜰 때 가장 좋아하는 방식이고 여러 번 해봤음
    GigE에서는 압축이 병목이 되는 경우가 많으니 gzip에는 --fast를 넘기는 게 좋고, 더 낫게는 gzip/gunzip 대신 lz4/unlz4를 쓰면 더 빠름. 예전에 1TB NVMe가 든 새 Windows 노트북을 GigE로 이미지화했을 때 20분쯤 걸렸고, 빈 공간이 거의 0에 가깝게 압축되어 결과 이미지는 20GB였음. 보통 그 lz4 이미지를 백업해뒀다가 몇 년 뒤 노트북을 기증할 때 unlz4 | dd로 복원해서 매우 편함
    다만 Linux 커널 모듈 nvme-tcp는 몰랐고, 매일 새로 배우게 됨. 이건 dd로 원시 접근하는 용도보다는 원격 NVMe 위에 파일시스템을 마운트하는 데 더 유용해 보임
    추가로 Linux의 최대 파이프 버퍼 크기는 64kB라서 dd bs=X 인자가 기술적으로 그보다 클 필요는 없음. 그래도 bs=1M은 해롭지 않고 64kB 읽기를 1MB가 될 때까지 모아주며, 나중에 파이프 크기가 커져도 대비됨. 일부 netcat 버전은 입출력 블록 크기 옵션이 있어 dd bs=X가 필요 없지만, 복구 디스크의 netcat은 보통 그런 옵션이 없는 버전임

    • Linux의 파이프 버퍼는 늘릴 수 있고, 기본 최대값은 보통 1MB 정도로 알고 있음. 명령줄에서 하기는 조금 까다롭지만 가능한 구현 예시는 https://unix.stackexchange.com/a/328364에 있음
    • 조금 지저분하긴 하지만 양쪽에서 dd 대신 pv 를 쓰면 적절한 블록 크기를 지정할 걱정이 없고, 진행 그래프도 보기 좋게 나옴
    • 9년쯤 전 내부 해킹을 당한 회사에 컨설팅을 간 적이 있는데, 불만을 품은 공동창업자가 데드맨 스위치처럼 모든 디스크의 앞 20MB를 어떤 버킷으로 복사한 뒤 0으로 덮어쓰게 해뒀음. 데이터를 복구하려고 testdisk로 파티션 테이블을 재구성해야 했지만, 그 전에 손상된 디스크를 건드리고 싶지 않아서 복구 플래시 디스크, netcat, 드라이브로 약 40TB를 복사함
      일부 서버는 물리 RAID 슬롯이 모두 차 있어서 여분 디스크 슬롯을 쓸 수도 없었고, 대략 dd if=/dev/sdc bs=xxx | gzip | nc -l -p 8888와 반대편 역방향 명령을 썼음. 의외로 잘 동작했음. 한 가지 주의할 점은 dd bs 조합을 섹터 크기에 맞춰보는 것인데, 적절한 크기가 dd 처리량에 큰 영향을 줬음
    • dd 사용법은 손상을 일으킬 수 있음. 블록이 잘리지 않게 하려면 iflag=fullblock이 필요하고, 맹목적 관행일 위험은 있지만 conv=sync도 해롭지는 않음. 개인적으로는 그냥 nc -l -p 1234 > /dev/nvme0nX를 선호함
    • 대부분은 로컬 네트워크가 SSD 전송 속도보다 빠르지 않을 듯함. 그래도 그런 환경이 있는 사람들을 위해 동시 입출력 블록 장치 복제 도구가 존재하는지 궁금함
      파이프라인에 pv를 넣으면 예상 완료 시간을 볼 수 있지만, 성능에는 약간 영향이 있을 수 있음
  • AWS/Annapurna/Nitro/Lightbits가 Linux에 NVMe-over-TCP를 가져온 데 감사함
    https://www.techtarget.com/searchstorage/news/252459311/Ligh...
    “NVM Express 컨소시엄은 2018년 11월 NVMe/TCP를 바인딩 전송 계층으로 비준했다. 이 표준은 원래 Lightbits 엔지니어링 팀이 NVM Express에 제출한 코드 기반에서 발전했다.”
    https://www.lightbitslabs.com/blog/linux-distributions-nvme-...
    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...

  • 아래에 비하면 훨씬 번거로워 보임: nbdkit file /dev/nvme0n1, nbdcopy nbd://otherlaptop localfile

    • 이 방식이 실제로 훨씬 나은데, nbdcopy희소 파일을 처리할 수 있고 연결 수와 스레드 수를 코어 수에 맞출 수 있으며, 종료 전에 강제 플러시도 가능하고 진행 막대도 켤 수 있음. 암호화되지 않은 드라이브라면 TLS도 지원함
  • 최근 새 노트북에 xubuntu를 설치해야 했음. 예전에는 복제했지만 이번에는 일부 설정을 새로 정리하고 싶었음
    USB-C 케이블로 10Gb/s 전송을 하는 게 정말 유용했음. 다른 선택지는 WiFi뿐이었기 때문임
    컴퓨터들을 서로 꽂으면 임시 네트워크가 형성되고 그냥 rsync로 넘기면 됨. 보기에는 링크가 포화되어 있어서 다른 프로토콜을 쓰는 건 별 의미가 없어 보였음. 물론 새로 배우는 건 좋지만, 노트북을 복제하는 순간에는 아닐 수도 있음

    • 그냥 바로 동작했는지 궁금함. 마지막으로 이더넷이 아닌 직접 연결을 시도한 게 90년대라서 진지하게 묻는 것임
    • 나도 해봤지만 네트워킹이 되게 하려면 30달러 이상짜리 Thunderbolt 4 케이블을 사야 했음. 일반 USB3-C 케이블만으로는 부족했음
      전송 자체는 엄청 빨라서 몇 분 만에 1TB를 옮겼음. 이번에는 암호화를 쓰지 않아서 훨씬 단순해졌음
    • 라이브 디스크로 부팅한 뒤 전체 파일시스템을 옮긴 건지, 아니면 기본 시스템을 설치한 다음 파일만 옮긴 건지 궁금함
  • 왜 네트워크로 btrfs를 파이프하지 않았는지 이해가 안 됨. 먼저 btrfs 스냅샷을 만들고 btrfs send => nc => network => nc => btrfs receive를 하면 사용 중인 블록만 전송됨

    • btrfs를 썼다는 걸 보자마자 나도 제일 먼저 그 생각이 났음. btrfs send/receive를 SSH로 항상 쓰는데 아주 잘 동작함. GRML 라이브 세션에서 SSH 서버를 쉽게 띄울 수도 있었을 것임
      다만 주의점이 하나 있음. btrfs에서는 스냅샷을 재귀적으로 보낼 수 없어서, 재귀 스냅샷이 많다면 새 디스크에 같은 구조를 미러링하기가 비교적 어렵다. Docker/LXD/Incus에서는 그런 일이 생길 수 있음. btrfs를 좋아하지만, 재귀 send/receive는 ZFS가 더 나은 부분임
  • 최근 WiFi로 약 200GB 파일을 복사해야 했음. 연결 실패 시 처음부터 다시 시작하지 않도록, 또 손실이 없도록 rsync를 썼는데 최소 6시간이 걸렸음. 더 나은 방법이 있었을지 궁금함
    그리고 dd 방식은 어떤 보장을 주는지도 궁금함. 결과 블록 장치의 md5를 비교해야 하는 건가?

    • 200GB를 WiFi로 옮기는 데 6시간이면 로컬 전송치고는 인상적인 처리량이 아님. 이더넷 케이블을 썼어야 했을 듯함
      WiFi는 성능 병목 원인이 훨씬 많음. 기기 하나만이라도 케이블로 라우터에 연결하고, 다른 기기는 무선으로 두는 것만으로도 꽤 도움이 됨
    • 파일이 아주 많고 작았다면 rsync가 한 번에 한 파일만 전송한다는 점이 병목이었을 가능성이 큼. xargs/parallel로 파일 목록을 나눠 여러 rsync 인스턴스를 돌리거나, 자체적으로 병렬 전송을 지원하는 rclone 같은 걸 쓸 수 있음
    • 6시간이면 대략 10MB/s라서 훨씬 더 빠르게 할 수 있었을 가능성이 큼. -z로 압축했는지 궁금함. 이더넷을 쓸 수 있었다면 대부분의 장치에서 100MB/s에 가까워져서 35분 정도였을 것임
    • rsync의 전송 방식이 SSH였다면 그게 병목인 경우가 많음. OpenSSH는 역사적으로 이상한 성능 제한이 있었고, 이를 우회하려면 잘 알려지지 않은 패치가 필요했던 적도 있음. CPU가 병목이 되지 않는다면 압축을 켜는 것도 도움이 됨
    • WiFi는 다른 모든 무선 장치와 공기라는 매체를 공유함. 충돌을 감지하면 멈춘 뒤 무작위 시간만큼 기다림
      “컴퓨터 네트워킹에서 충돌 회피 반송파 감지 다중 접속(CSMA/CA)은 반송파 감지를 사용하되, 채널이 ‘유휴’로 감지된 뒤에만 전송을 시작해 충돌을 피하려는 네트워크 다중 접속 방식이다. 전송할 때는 노드가 패킷 데이터를 전체로 전송한다
      이는 무선 송신기가 패킷 전송 중 수신기를 둔감하게 만들어 꺼버리기 때문에 충돌 감지 방식인 CSMA/CD를 쓸 수 없는 무선 네트워크에서 특히 중요하다
      CSMA/CA는 숨은 노드 문제 때문에 신뢰성이 낮다
      CSMA/CA는 데이터 링크 계층에서 동작하는 프로토콜이다.”
      https://en.wikipedia.org/wiki/Carrier-sense_multiple_access_...
  • 이 접근법의 장점은 있겠지만, 예전에 노트북을 옮길 때는 양쪽에서 설치 프로그램을 띄운 뒤 ddnc를 조합했음. 기억으로는 큰 널 구간을 더 빠르게 전송하려고 gzip도 추가했음
    새 노트북에 이더넷 포트가 없었다면, 내 해키한 방식이 압축 덕분에 조금 더 빨랐을 수도 있음. 네트워크 속도가 빠른 링크에서 압축이 추가하는 한계에 근접하지 못할 정도였을 테니까

    • 전체 디스크 암호화 상태라면 LUKS에 TRIM 통과를 지시하지 않은 한, 작성자가 설명한 방식으로는 사실상 무작위 데이터만 얻게 됨
  • 그냥 Clonezilla를 쓰면 되지 않나? 실제 데이터 블록만 복사하고 파티션 자동 크기 조정도 가능함. 나는 항상 그렇게 함
    물론 보통은 노트북에서 NVMe 디스크를 빼서 고속 독에 꽂음

    • Clonezilla는 훌륭함. 할 일이 하나이고 보통 첫 시도에 성공함. 다만 초기 학습 곡선 때문에 이것저것 만져봐야 하는 게 유일한 불만임
      아직 완전히 믿고 방치할 수준은 아님. 백업은 백업과 복원을 합친 것과 같지 않으니 실험이 권장됨. Clonezilla도 원본과 많이 다른 디스크에 파티션을 재생성할 때는 문제가 생길 수 있음
  • 데스크톱이나 노트북에 운영체제를 실제로 “설치”한 지는 수십 년이 됐고, 항상 파일을 복사한 뒤 필요한 부분만 조정했음. 보통은 이 기회에 파일시스템 종류나 블록 크기 같은 매개변수, 암호화 등을 업데이트하려고 새 파일시스템을 만들고 rsync로 파일을 옮김
    그래도 미리 계획하는 타입이라면 설정만 복사하고 나머지는 자동 재설치하는 NixOS 같은 더 선언적인 방식이 더 나을 것 같음

  • 중간 AP 없이 WiFi로 장치들을 직접 연결하면 전송 속도를 두 배로 높일 수 있을 것임. 이 상황에서는 해볼 만했을 듯함