민감한 데이터를 저장하는 데 사용하는 파일에 Luks로 암호화된 ext4가 있습니다(이를 FS "내부"라고 부르겠습니다). 파일 자체는 물리적 SSD에 있는 다른 ext4에 있습니다. 이를 "외부" FS라고 부르겠습니다. 내부 FS는 외부 FS의 파일을 가리키는 루프백 장치를 사용하여 마운트됩니다.
sync(1)를 호출하면 내부 FS에 대해 보류 중인 모든 쓰기가 지속된다는 것이 보장됩니까?
불행한 순서로 동기화가 발생하면 (제가 이해한 바에 따르면) 다음과 같은 일이 발생할 수 있습니다.
- 데이터는 내부 FS에 기록됩니다.
sync
옮기다.- 외부 FS 캐시에 대한 쓰기는 디스크에 기록됩니다.
- 내부 FS 캐시에 대한 쓰기는 외부 FS의 파일에 기록됩니다.
- 내부 FS에서 외부 FS로의 쓰기는 캐시에 유지됩니다.
- 충돌이 발생했습니다.
- 그럼에도 불구하고 내부 FS에 대한 쓰기는 여전히 손실됩니다.전에 일어난
sync
A.
동기화가 이런 일이 발생하지 않도록 보장합니까, 아니면 확실히 알기 위해 중첩된 파일 시스템 레이어만큼 동기화를 호출해야 합니까?
Linux를 요청하고 있는데 POSIX에 대한 소식이 있다면 그것도 관심을 갖고 싶습니다.
sync(1)
불행하게도 sync(2)
데비안 매뉴얼 페이지에는 이 사례에 대한 정보가 없습니다.
답변1
예, 보장됩니다.
중첩된 파일 시스템을 수행하는 방법을 명시적으로 언급하지 않았지만 블록 루프백 장치를 사용하고 있다고 가정합니다.
이 경우 핵심 비트는 여기에서 볼 수 있습니다.커널 소스 코드:
static int lo_req_flush(struct loop_device *lo, struct request *rq)
{
struct file *file = lo->lo_backing_file;
int ret = vfs_fsync(file, 0);
if (unlikely(ret && ret != -EINVAL))
ret = -EIO;
return ret;
}
에 대한 전화를 기록해 두십시오 vfs_fsync(file, 0)
. 이는 루프백 드라이버가 루프백 블록 장치를 지원하는 파일에 대해 명시적으로 동기화를 호출하고 있음을 의미합니다.
답변2
이 명령은 승인되지 않았지만 가장 가능성이 높은 방법은 sync(2)
호출 시 커널이 마운트 테이블을 탐색하는 것입니다. 솔라리스에서는 이 방법을 사용하며, 리눅스에서도 이 방법을 사용할 가능성이 높습니다.
이는 마음에 들지 않는 것 같으므로 귀하의 경우에는 동기 호출 이상의 것을 실행해야 합니다.