이전 포스팅(링크)에서 libostree에 대해서 간략하게 살펴봤다. 이번 포스팅에서는 실제 libostree를 사용해보면서 좀 더 깊이있게 살펴보고자 한다.
우분투 기준으로 아래 명령을 통해 ostree 명령어를 설치할 수 있다.
$ sudo apt install ostree
임의의 디렉토리에 ostree 저장소를 만들어보자. 아래 명령으로 repo 디렉토리가 생성된다.
여러 필요한 디렉토리들 파일이 생성된 것을 확인할 수 있다.
저장소 내의 config 파일에는 저장소의 버전과 모드가 표시되어 있다.
$ ostree init --repo=repo
$ tree repo/
repo/
├── config
├── extensions
├── objects
├── refs
│ ├── heads
│ ├── mirrors
│ └── remotes
├── state
└── tmp
└── cache
$ cat repo/config
[core]
repo_version=1
mode=bare
테스트를 위해 디렉토리와 파일을 생성해보자.
$ mkdir tree
$ echo "Hello world!" > tree/hello.txt
아래 명령으로 tree 디렉토리를 repo 저장소로 import 할 수 있다. 결과로 해쉬값을 얻을 수 있다.
리턴결과는 디렉토리명 + 해쉬값이다. 아래 결과값의 03은 commit 파일이 저장될 위치이고 뒤의 해쉬값은 commit 파일의 파일명이 된다.
$ ostree commit --repo=repo --branch=foo tree/
0372d465ef33876ea21ff4aecb4cf99c01ab3ac1f648fc3f4c8f5ef73b39a48b
여기까지 진행하고 repo 저장소의 상황을 보자. object 디렉토리 밑에 file, commit, dirmeta, dirtree 파일이 생성되었음을 알 수 있다. 참고로 file은 위에서 생성한 hello.txt 파일 자체이다.
commit 파일에는 커밋 자체에 대한 정보가 저장된다. time, log message는 당연히 들어가고 상위 커밋이 누구인지 해당 커밋을 구성하는 dirtree와 dirmeta들의 리스트가 저장된다.
dirmeta는 permission 같은 디렉토리의 meta 정보가 저장된다고 하고 dirtree에는 디렉토리 내의 파일, 서브 파일들의 정보가 저장된다고 한다.
$ tree repo/
repo/
├── config
├── extensions
├── objects
│ ├── 00
│ │ └── 19bd0d2a51f79e12fc57e6f8f46d53c8d764f788034908a5b1c9c745e436bf.file
│ ├── 03
│ │ └── 72d465ef33876ea21ff4aecb4cf99c01ab3ac1f648fc3f4c8f5ef73b39a48b.commit
│ ├── 2a
│ │ └── 28dac42b76c2015ee3c41cc4183bb8b5c790fd21fa5cfa0802c6e11fd0edbe.dirmeta
│ └── c1
│ └── 1ef48f17b78ef908ff4d4d4601be0881fe7fdacd5439099b07533b3f3b5464.dirtree
├── refs
│ ├── heads
│ │ └── foo
│ ├── mirrors
│ └── remotes
├── state
└── tmp
└── cache
$ cat repo/objects/00/19bd0d2a51f79e12fc57e6f8f46d53c8d764f788034908a5b1c9c745e436bf.file
Hello world!
두 번째 commit을 만들어보자. subject와 body를 추가 옵션으로 사용했다. 새로 생선된 file은 최신의 내용을 가리키고 과거에 생성된 파일은 기존 내용 그대로 있음을 확인할 수 있다.
$ echo "Hello world2" >> tree/hello.txt
$ ostree commit --repo=repo --branch=foo --subject="2nd" --body="TEST" tree/
151ff899221021b6917762494feb4f1d8f64f32dc340af6e91f2ed91a6369804
$ tree repo/
repo/
├── config
├── extensions
├── objects
│ ├── 00
│ │ └── 19bd0d2a51f79e12fc57e6f8f46d53c8d764f788034908a5b1c9c745e436bf.file
│ ├── 03
│ │ └── 72d465ef33876ea21ff4aecb4cf99c01ab3ac1f648fc3f4c8f5ef73b39a48b.commit
│ ├── 15
│ │ └── 1ff899221021b6917762494feb4f1d8f64f32dc340af6e91f2ed91a6369804.commit
│ ├── 2a
│ │ └── 28dac42b76c2015ee3c41cc4183bb8b5c790fd21fa5cfa0802c6e11fd0edbe.dirmeta
│ ├── c1
│ │ └── 1ef48f17b78ef908ff4d4d4601be0881fe7fdacd5439099b07533b3f3b5464.dirtree
│ ├── c5
│ │ └── 2e4723fc2bc5e1acdc1525c6aed446149457470a2d2251440af1ba013fb17d.dirtree
│ └── e1
│ └── 8323be69d55b59c2c4d7e0644c825823a06e45cbb8fba5dedc59700328887b.file
├── refs
│ ├── heads
│ │ └── foo
│ ├── mirrors
│ └── remotes
├── state
└── tmp
└── cache
$ cat repo/objects/e1/8323be69d55b59c2c4d7e0644c825823a06e45cbb8fba5dedc59700328887b.file
Hello world!
Hello world2
$ cat repo/objects/00/19bd0d2a51f79e12fc57e6f8f46d53c8d764f788034908a5b1c9c745e436bf.file
Hello world!
아래 명령을 통해서 refs들을 확인할 수 있다.
$ ostree refs --repo=repo
foo
foo라는 refs의 세부 내용은 아래 명령어를 통해서 확인이 가능하다.
log, ls 그리고 cat 서브 명령은 특정 refs의 내용에 대한 명령어 포팅이라고 생각하면 된다.
아래 부분의 cat의 명령을 보면 git과 비슷한 명령도 먹히는 것을 볼 수 있다.
의미 불명이었던 repo/refs/heads/foo 파일에는 현재 HEAD의 해쉬값이 저장되어 있다.
$ ostree log --repo=repo foo
commit 151ff899221021b6917762494feb4f1d8f64f32dc340af6e91f2ed91a6369804
ContentChecksum: b4add12f8db72bdfcc852a22a410f1877e28c0adb39a3ca1f2d85423d23eb2e4
Date: 2019-01-30 07:35:10 +0000
2nd
TEST
commit 0372d465ef33876ea21ff4aecb4cf99c01ab3ac1f648fc3f4c8f5ef73b39a48b
ContentChecksum: 002b0f344a89d0f8949dbf9fbb3f0fbf1b5ef64b18243faf84b420a44e057062
Date: 2019-01-30 07:26:54 +0000
(no subject)
$ ostree ls --repo=repo foo
d00775 1000 1000 0 /
-00664 1000 1000 13 /hello.txt
$ ostree cat --repo=repo foo /hello.txt
Hello world!
Hello world2
$ ostree cat --repo=repo foo^ /hello.txt
Hello world!
$ cat repo/refs/heads/foo
151ff899221021b6917762494feb4f1d8f64f32dc340af6e91f2ed91a6369804
foo refs를 checkout하는 명령어는 다음과 같다. 이전에 생성한 tree는 지워도 무방하다.
$ rm -rf tree
$ ostree checkout --repo=repo foo tree-checkout/
$ cat tree-checkout/hello.txt
Hello world!
Hello world2
새로운 파일로 실험을 해보자.
일단 아래와 같이 0으로 채워진 10MB, 20MB 파일을 준비한다.
$ dd if=/dev/zero of=10M.zero bs=1 count=0 seek=10M
0+0 레코드 들어옴
0+0 레코드 나감
0 bytes copied, 0.000252533 s, 0.0 kB/s
$ dd if=/dev/zero of=20M.zero bs=1 count=0 seek=20M
0+0 레코드 들어옴
0+0 레코드 나감
0 bytes copied, 0.000261508 s, 0.0 kB/s
10MB, 20MB 파일을 적용할 때 마다, 파일의 사이즈가 늘어나는 것을 볼 수 있다.
일단 libostree는 여러 파일 간의 중복에 대해서는 처리하지 않는 것을 알 수 있다.
$ du -sh repo/
104K repo/
$ cp 10M.zero tree/
$ ostree commit --repo=repo --branch=foo --subject="10MB" tree/
ba58b22b38530dcfafbf3c7ec1e786013991cf99a3875deac26ceacede479f6f
$ du -sh repo/
11M repo/
$ ostree commit --repo=repo --branch=foo --subject="20MB" tree/
21cdfe4c0703f9d308d12411a03a6df8622d577ad69251238869689f77ee90ae
$ du -sh repo/
31M repo/
20M.zero 파일의 뒷 부분에 강제로 2.3MB 가량의 파일을 추가했다.
commit 이후 용량을 살펴보자. 순수하게 용량이 늘었음을 알 수 있다. 즉, libostree 파일의 변경사항에 대해서만 저장하는게 아니고 변경이 된 파일에 대해서는 파일 전체가 바뀐다.
$ dd if=/usr/bin/Xwayland bs=1 >> tree/20M.zero
2299608+0 레코드 들어옴
2299608+0 레코드 나감
2299608 bytes (2.3 MB, 2.2 MiB) copied, 2.70449 s, 850 kB/s
$ ostree commit --repo=repo --branch=foo --subject="20MB+@" tree/
9a6e99cd6bde1ed0d6302798d191ab3e4d4b142317ea9e34663c8f38059e8b25
$ du -sh repo/
53M repo/
libostree의 최대 장점은 checkout 한 client들이 모두 hard link로 유지됨으로 인해 실제 파일시스템의 용량을 차지하지 않는다는 것이다. 확인해보자.
우선 df 명령을 앞뒤로 수행해서 용량변화를 체크하자. 결론은 사용량의 변화가 없음을 알 수 있다.
실제로 각 파일의 inode 값이 동일함을 알 수 있다.
$ df --block-size=M
... A ...
$ ostree checkout --repo=repo foo 1/
$ ostree checkout --repo=repo foo 2/
$ ostree checkout --repo=repo foo 3/
$ ostree checkout --repo=repo foo 4/
$ ostree checkout --repo=repo foo 5/
$ ostree checkout --repo=repo foo^ 6/
$ ostree checkout --repo=repo foo^^ 7/
$ df --block-size=M
... B ...
$ du -sh 1/
33M 1/
$ du -sh 2/
33M 2/
$ du -sh 3/
33M 3/
$ du -sh 4/
33M 4/
$ du -sh 5/
33M 5/
$ du -sh 6/
31M 6/
$ du -sh 7/
11M 7/
$ ls -i 1/10M.zero
30296884 1/10M.zero
$ ls -i 2/10M.zero
30296884 2/10M.zero
$ ls -i 3/10M.zero
30296884 3/10M.zero
$ ls -i 4/10M.zero
30296884 4/10M.zero
'소프트웨어 > OTA(on-the-air)' 카테고리의 다른 글
libostree (OStree) 예제 - 리모트 & 로컬 저장소 (1) (0) | 2019.01.30 |
---|---|
Eclipse hawkBit 간략하게 살펴보기 (0) | 2019.01.22 |
RAUC(Robust Auto-Update Controller) 살펴보기 (0) | 2019.01.21 |
Clear Linux & swupd 살펴보기 (0) | 2019.01.18 |
SWUpdate (Software Update for Embedded Systems) 살펴보기 (0) | 2019.01.16 |