<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>btrfs &#8211; richliu&#039;s blog</title>
	<atom:link href="https://blog.richliu.com/tag/btrfs/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.richliu.com</link>
	<description>Linux, 工作, 生活, 家人</description>
	<lastBuildDate>Mon, 09 Sep 2019 09:01:24 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.2</generator>
	<item>
		<title>embedded system btrfs</title>
		<link>https://blog.richliu.com/2017/04/01/2124/embedded-system-btrfs/</link>
					<comments>https://blog.richliu.com/2017/04/01/2124/embedded-system-btrfs/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Sat, 01 Apr 2017 11:42:49 +0000</pubDate>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[btrfs]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=2124</guid>

					<description><![CDATA[<p>這一篇是 btrfs 用在 embedded system 的開發測試上會用到的指令. mkfs.btrfs  [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2017/04/01/2124/embedded-system-btrfs/">embedded system btrfs</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>這一篇是 btrfs 用在 embedded system 的開發測試上會用到的指令.<br />
<span id="more-2124"></span></p>
<p>mkfs.btrfs /dev/sda2<br />
這有一點要注意, 有些 btrfs tool 預設 sectorsize 是 4096, 但是新的系統不能再用 4096 了. 要用 65536 . 所以要改用</p>
<pre lang="bash">
$ mkfs.btrfs -s 65536 /dev/sda2
</pre>
<p>首先 btrfs 的 tag 是樹狀的, 最頂端的 tag 應該是 root level &#8220;0&#8221;.<br />
往下一層就是 level 5 , 所以一開始就要 mount 上去然後開 top level 5 的目錄. ex:</p>
<pre lang="bash">
$ mount /dev/sda2 /mnt/disk
$ cd /mnt/disk
$ btrfs subvolume create @
$ btrfs subvolume create @home
</pre>
<p>這樣就會有二個預設的 top level 5 的目錄, 先 umount 再 mount 新的 tag 過的 partition. install 系統, ex:</p>
<pre lang="bash">
$ umount /mnt/disk
$ mount -o subvol=@ /mnt/disk
$ mkdir -p /mnt/disk/home
$ mount -o subvol=@home /mnt/disk 
.... install linux into /mnt/disk 
# 在開機時直接 mount @home 到 /home , 這樣以後切換系統時就可以一直用 @home tag
$ echo "/dev/sda2 /home  btrfs  defaults,subvol=@home 0 0" >> /etc/fstab
</pre>
<p>做完之後, 就要做一個 snapshot, 以後就在 snapshot 上做事情, 弄壞了砍掉再重來就可以. </p>
<pre lang="bash">
(假設系統都還沒有 mount)
$ mount /dev/sda2 /mnt/disk
$ cd /mnt/disk
$ btrfs subvolume snapshot @ 1604
</pre>
<p>這樣就會產生一個 1604 的 snapshot. 內容和 @ 內是一模一樣的</p>
<p>接下來不管在 這個 snapshot 如何惡搞也不會影響到 @ 的內容</p>
<p>開機參數, 如何在開機時選擇那一個 subvol 開機, 如果是 embedded system 用 u-boot, 寫在 bootarg 內就可以了. 參數是 rootflags=subvol=<br />
ex: 在 uboot 下</p>
<pre lang="text">
$ setenv subvol 1604
$ setenv bootdev /dev/sda2
$ setenv updkrnargs=setenv bootargs  console=ttyAMA0,115200n8 earlycon=pl011,0x87e028000000 debug maxcpus=24 rootw
ait rw  rootflags=subvol=${subvol} root=${bootdev} coherent_pool=16M/
$ setenv start 'setenv ethact vnic3 ; dhcp ; run updkrnargs;  tftpboot $kernel_addr Image ; booti $kernel_addr - $fdtcontroladdr'
</pre>
<p>因為 u-boot 只能在 setenv 更新參數, 所以要再多一層 setenv 讀入參數.<br />
這樣開機時, 就可以隨興設定 subvol, 開到正確的 subvol 上. 如果以後要砍掉, 砍掉這個 subvol 後再重建一個 snapshot. 省掉不少重灌的時間, 是不是很方便呢? </p>
<p>砍掉 subvol,<br />
假設開到 @ 上去. </p>
<pre lang="bash">
$ mount /dev/sda2 /mnt/disk
$ cd /mnt/disk
$ btrfs subvol del 1604
$ btrfs subvol snapshot @ 1604
</pre>
<p>有時候開發到一半想要留個備份, 也可以 snapshot, 就像 git tag 一版</p>
<pre lang="bash">
$ mount -o subvol=1604 /dev/sda2 /mnt/disk
$ btrfs subvol snapshot /mnt/disk /mnt/disk/1604-backup
</pre>
<p>這樣就可以了, 接下去再怎麼亂搞也沒有關係, 都可以回到 1604-backup<br />
如果是開到 1604 時, 會看到 1604-backup 在根目錄, 也可以直接刪除</p>
<pre labg="bash">
# btrfs subvol del 1604-backup
Delete subvolume (no-commit): '//1604-backup'
</pre>
<p>是不是超方便的? 超像有 git 功能的 file system.<br />
提外話: Microsoft 搞了一個 git 專用的 file system<a href="https://blogs.msdn.microsoft.com/visualstudioalm/2017/02/03/announcing-gvfs-git-virtual-file-system/" target="_blank" rel="noopener">file system Announcing GVFS (Git Virtual File System)</a></p>
<p>如果系統是一般的 ubuntu, 沒有 u-boot, 想要改 grub 達到類似切換的效果. 個人的做法是在 @ 目錄下放一個檔案, 只要修改這個檔案之後, 就可以切換 subvol.</p>
<p>編輯 /etc/grub.d/10_linux, 找到 rootsubvol= 的字串, 改成圖內這樣</p>
<pre lang="text">
case x"$GRUB_FS" in
    xbtrfs)
        rootsubvol="`cat /root/defaultsubvol`" => 改成這樣, update 之後就可以切來切去了
        rootsubvol="${rootsubvol#/}"
        if [ "x${rootsubvol}" != x ]; then
            GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
        fi;;
</pre>
<p>以後就可以靠修改 @ 的 /root/defaultsubvol 然後再 update grub 達到切換不同 subvol 的目的.<br />
ex:</p>
<pre lang="bash">
$ mount -o subvol=@ /dev/sda2 /mnt/disk
$ for i in dev dev/pts sys proc run; do sudo mount --bind /$i mnt/disk/$i; done
$ chroot /mnt/disk
$ echo "1604-backup" > /root/defaultsubvol
$ update-grub
</pre>
<p>reboot 就會切換到 1604-backup </p>
<p>如果是己經開到 1604 下, 然後這時候針對 1604 的 root 用了 snapshot , 如果再開機的時候, subvol 就要加上上一層的名稱<br />
像是這案例就要下 1604/odp<br />
ex:</p>
<pre lang="bash">
$ btrfs subvol snapshot / /odp
reboot to subvol 1604/odp
$ btrfs subvol list / 
ID 257 gen 446 top level 5 path @
ID 258 gen 1809 top level 5 path @home
ID 262 gen 1812 top level 5 path 1604
ID 268 gen 1807 top level 5 path gentoo
ID 276 gen 1689 top level 268 path gentoo/gentoo-1
ID 277 gen 1810 top level 262 path 1604/odp
</pre>
<p>這也不難理解, odp 是從 1604 snapshot 出來的放在 1604 下, 所以開到 1604 下會有一個 odp 的目錄, 就是指向 odp 的 snapshot.<br />
簡單的說, 產生了一個新的目錄是 1604 根目錄的 snapshot.<br />
如果不想要多一個 1604 , 可以 mount root 針對 1604 snapshot , 檔案放到 root 下即可. </p>
<p>可能剛開始會不習慣, 不過用了幾次之後就會發現這非常的省時間.<br />
非常適合 embedded 開發用. </p>
<p>另外我不知道是不是我常常惡搞, 我的確有碰過一次整個 btrfs filesystem  壞掉. 雖然如此, 不影響它對我的方便性. </p>
<p>ref.<br />
<a href="https://wiki.archlinux.org/index.php/Btrfs" target="_blank" rel="noopener">ArchLinux Btrfs</a></p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2017/04/01/2124/embedded-system-btrfs/">embedded system btrfs</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2017/04/01/2124/embedded-system-btrfs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>BTRFS 心得</title>
		<link>https://blog.richliu.com/2017/01/18/2070/btrfs-%e5%bf%83%e5%be%97/</link>
					<comments>https://blog.richliu.com/2017/01/18/2070/btrfs-%e5%bf%83%e5%be%97/#respond</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Wed, 18 Jan 2017 15:16:21 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[btrfs]]></category>
		<guid isPermaLink="false">https://blog.richliu.com/?p=2070</guid>

					<description><![CDATA[<p>ext3/ext4 是傳統的檔案系統,BTRFS 是 Linux 下新一代的檔案系統, 在除了檔案系統基本功能 [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2017/01/18/2070/btrfs-%e5%bf%83%e5%be%97/">BTRFS 心得</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>ext3/ext4 是傳統的檔案系統,<br />BTRFS 是 Linux 下新一代的檔案系統, 在除了檔案系統基本功能以外的操作都很不一樣.</p>



<p>BTRFS 主要增加了<br />可擴充性(scalability). B-tree 系列的效能很好. 看起來是號稱, 簡單的 Write 還不錯, 複雜性的操作的效能就沒有很好(<a href="http://www.phoronix.com/scan.php?page=news_item&amp;px=Linux-4.7-FS-5-Way" target="_blank" rel="noreferrer noopener">Linux 4.7 &#8211; Btrfs vs. EXT4 vs. F2FS vs. XFS vs. NTFS Benchmarks</a>). 其中提到了幾個特性<br />數據一致性(Data integrity) , 快照管理(Snapshot/clone),&nbsp;速度<br />而最近在開發的時候發現 BTRFS 快照管理在測試系統時頗好用</p>



<span id="more-2070"></span>



<p>在講快照之前, 先要提一下 BTRFS 的樹狀架構, 和傳統的檔案系統不太一樣.<br />BTRFS 比較像是, 建立了 File System 之後, 一個一個 subvolume 切出來使用. 而不是傳統的硬碟有多大就可以用多大. 想像成一個 pool , 可以隨時建立一個新的區塊, 這個區塊可以是 clone 或是全新的參數.</p>



<p>當一個 BTRFS 用 mkfs.btrfs 建立好之後, 像是一個 pool , 首先最頂級的 volume 目錄是 root, 符號 /, 第一個 subvolume 是 default, 符號 @ .<br />Ubuntu 預設安裝(我只用過 Ubuntu, 其他的不確定) 會產生二個預設的 subvolume @, @home</p>



<p>所以看起來就像是這樣</p>



<pre class="wp-block-preformatted">/dev/sda2
+- /
+- @
+- @home </pre>



<p>@ 也就是 default subvolume, 第一個 subvolume</p>



<p>基本的命令, 列出目前 mount 的 btrfs 和相關的訊息<br />$ btrfs subvol list /<br />將 /dev/sda2 subvolume @ mount 在 /mnt/disk<br />$ mount -o subvol=@ /dev/sda2 /mnt/disk</p>



<p>這是一個範例, top level 5 都是 / 下來的第一層 subvolume</p>



<pre class="wp-block-preformatted"> # btrfs subvol list /                                                                                ID 257 gen 4383 top level 5 path @ 
ID 258 gen 4388 top level 5 path @home 
ID 261 gen 4303 top level 5 path 1404 
ID 289 gen 4297 top level 261 path 1404/1404working 
ID 290 gen 4364 top level 257 path @/working 
ID 291 gen 4434 top level 5 path working
   </pre>



<p>而 1404/1404working 則是指 ID 261 的 clone(snapshot)<br />@/working 則是指 ID 257 的 clone(snapshot)</p>



<p>所以有些人問說為什麼不能刪除 top level 5 的 snapshot , 原因就是要 mount -o subvol=/ 之後再用 btrfs subvol delete</p>



<p>所以如果</p>



<pre class="wp-block-preformatted">mount -o subvol=/ /dev/sda2 /mnt/disk
btrfs subvolume snapshot /mnt/disk/@ /mnt/disk/working </pre>



<p>working 就會是開在 top level 5 之下</p>



<p>如果執行了以下指令，第一行是 mount btrfs root，第二行是針對目前的 @ 做 snapshot</p>



<pre class="wp-block-preformatted">mount -o subvol=@ /dev/sda2 /mnt/disk  
btrfs subvolume snapshot /mnt/disk/@ /mnt/disk/working</pre>



<p>working 就會是開在 top level 257 (@/working) 之下<br />主要的差異是一個 mount / , 另一個 mount @ </p>



<p>另外講一下 Ubuntu 16.04 可以針對 @ snapshot 之後將 root 開到另一個 subvolume.<br />首先修改 /etc/grub.d/10_linux</p>



<p>找到以下段落（約在 74 行的地方）, 改成 cat /root/defaultsubvol , 檔名隨你高興<br />這一段會取出 /etc/defaultsubvol 內的內容做為 root 的 subvol .</p>



<pre class="wp-block-preformatted">case x"$GRUB_FS" in
     xbtrfs)
         rootsubvol="<code><strong>cat /root/defaultsubvol</strong></code>"
         rootsubvol="${rootsubvol#/}"
         if [ "x${rootsubvol}" != x ]; then
             GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
         fi;;</pre>



<p>

所以這樣是切到 working

</p>



<pre class="wp-block-preformatted">sudo bash -c "echo 'working' >> /root/defaultsubvol" 
sudo update-grub </pre>



<p>現在可以編輯檔案 /boot/grub/grub.conf 確認 subvol 都是指向 working<br /><br /> 如果己經在 working 要切到 @ , 比較複雜一點 </p>



<pre class="wp-block-preformatted">mount -o subvol=@ /mnt/disk 
for i in dev dev/pts sys proc run; do sudo mount --bind /$i /mnt/disk/$i; done 
sudo chroot /mnt/disk bash -c "echo '@' >> /root/defaultsubvol" 
sudo chroot /mnt/disk 
sudo update-grub 
reboot  </pre>



<p>

這樣之後就可以切來切去了<br />對於要常常測測從系統重灌設定的人很好用.

</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2017/01/18/2070/btrfs-%e5%bf%83%e5%be%97/">BTRFS 心得</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2017/01/18/2070/btrfs-%e5%bf%83%e5%be%97/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>git 和 filesystem 的 Performance</title>
		<link>https://blog.richliu.com/2011/07/24/1109/git-%e5%92%8c-filesystem-%e7%9a%84-performance/</link>
					<comments>https://blog.richliu.com/2011/07/24/1109/git-%e5%92%8c-filesystem-%e7%9a%84-performance/#comments</comments>
		
		<dc:creator><![CDATA[richliu]]></dc:creator>
		<pubDate>Sat, 23 Jul 2011 16:00:54 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[btrfs]]></category>
		<category><![CDATA[ext3]]></category>
		<category><![CDATA[ext4]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[peformance]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[xfs]]></category>
		<category><![CDATA[問題]]></category>
		<category><![CDATA[效能]]></category>
		<guid isPermaLink="false">http://blog.richliu.com/?p=1109</guid>

					<description><![CDATA[<p>前二天因為硬碟壞掉, 所以硬碟升級成 raid1. 而 file system 手賤換成 xfs. 這個星期我 [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2011/07/24/1109/git-%e5%92%8c-filesystem-%e7%9a%84-performance/">git 和 filesystem 的 Performance</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>前二天因為硬碟壞掉, 所以硬碟升級成 raid1. 而 file system 手賤換成 xfs.<br />
這個星期我都在查詢 system 的 performance 問題.</p>
<p>因為我 git 的各項操作實在是太慢了.<br />
慢到整個系統大概可以和 P5 比吧 (反正就是慢慢慢)<br />
<span id="more-1109"></span><br />
一開始我以為是 raid/disk 的問題, 不過在數次交叉測試下, 看起來兇手指向 File System<br />
以下就是我的測試環境.</p>
<p>CPU: Intel(R) Core(TM)2 Quad CPU    Q9550  @ 2.83GHz<br />
OS: Ubuntu Linux 10.04 LTS<br />
HDD1: Device Model:     Seagate ST31000528AS (1T)<br />
HDD2: Device Model:     Seagate ST31000528AS (1T)<br />
同一顆.</p>
<p>測試方式.</p>
<p>HDD1, HDD2 分別切了 40G 的 Primary 1 Partition.<br />
第一次在 HDD1 測 ext4 , HDD2 測 xfs<br />
第二次在 HDD1 測 xfs , HDD2 測 ext3<br />
第二次測完後追加 ext3 和 btrfs<br />
使用 time command 測試時間.<br />
在 Copy 之前會先 mkfs disk .<br />
硬碟內先行準備好一個 git repository 的測試資料, 然後再另建一個目錄 clone 這份測試資料(不細測 Read/Write)</p>
<p>測試資料.<br />
9.1G 的 .git source tree. 包含 5G 的 .git database 還有 4.1G 的 source code/binary/image .. 等等資料. 約有 2800 個 commit.</p>
<p>以下是測試數據<br />
First Round<br />
sda1: ext4<br />
# time git clone ../trunk/<br />
Initialized empty Git repository in /mnt/disk/1/trunk/.git/<br />
Checking out files: 100% (216892/216892), done.</p>
<p>real 3m30.381s<br />
user 0m24.878s<br />
sys 0m31.402s</p>
<p>sdb1: xfs<br />
# time git clone ../trunk/<br />
Initialized empty Git repository in /mnt/disk2/1/trunk/.git/<br />
Checking out files: 100% (216892/216892), done.</p>
<p>real 13m47.297s<br />
user 0m31.510s<br />
sys 0m24.482s</p>
<p>Round 2:<br />
sda1: xfs<br />
# time git clone ../trunk/<br />
Initialized empty Git repository in /mnt/disk/1/trunk/.git/<br />
Checking out files: 100% (216892/216892), done.</p>
<p>real 13m10.405s<br />
user 0m32.122s<br />
sys 0m19.761s</p>
<p>sdb1: ext4<br />
# time git clone ../trunk/<br />
Initialized empty Git repository in /mnt/disk2/1/trunk/.git/<br />
Checking out files: 100% (216892/216892), done.</p>
<p>real 1m25.192s<br />
user 0m26.210s<br />
sys 0m14.017s</p>
<p>sdb: ext3<br />
# time git clone ../trunk/<br />
Initialized empty Git repository in /mnt/disk2/1/trunk/.git/<br />
Checking out files: 100% (216892/216892), done.</p>
<p>real 3m5.792s<br />
user 0m25.534s<br />
sys 0m23.065s</p>
<p>sda: btrfs<br />
# time git clone ../trunk/<br />
Initialized empty Git repository in /mnt/disk/1/trunk/.git/<br />
Checking out files: 100% (216892/216892), done.</p>
<p>real 1m13.981s<br />
user 0m24.670s<br />
sys 0m32.730s</p>
<p>簡單的做一個圖表做測試結果.</p>
<p><a href="http://blog.richliu.com/wp-content/uploads/2011/07/time.png"><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-1110" title="time" src="http://blog.richliu.com/wp-content/uploads/2011/07/time.png" alt="" width="483" height="292" srcset="https://blog.richliu.com/wp-content/uploads/2011/07/time.png 483w, https://blog.richliu.com/wp-content/uploads/2011/07/time-300x181.png 300w" sizes="(max-width: 483px) 100vw, 483px" /></a></p>
<p>由此圖可知, 我的效能問題是出在 xfs 上.將 raid system 改成 ext4 後, 這個問題就解決了.</p>
<p>但是奇怪的是, xfs 雖然花了 13m, 但是實際 CPU 使用時間並不多. 這個問題也有可能是 ubuntu/Linux kernel 造成的.</p>
<p>ext4 和  btrfs 都各有一次不錯的表現. 尤其是 btrfs, 才 1m13 秒. 大家有常常使用 git 的, 可以考慮一下 btrfs.</p>
<p>受限於個人時間, 這個測試並不嚴謹, 不過己經可以解決我目前的問題, 至於這個數據, 簡單整理一下以後, 可以給常常使用 git 的朋友一個參考的資料.<br />
接下來就是希望有人能夠花點時間做出更完整的數據, 或是順便 Debug 了. </p>
<p>The post <a rel="nofollow" href="https://blog.richliu.com/2011/07/24/1109/git-%e5%92%8c-filesystem-%e7%9a%84-performance/">git 和 filesystem 的 Performance</a> appeared first on <a rel="nofollow" href="https://blog.richliu.com">richliu&#039;s blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.richliu.com/2011/07/24/1109/git-%e5%92%8c-filesystem-%e7%9a%84-performance/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
