1 <!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns=
"http://www.w3.org/1999/xhtml"
4 lang=
"en" xml:
lang=
"en">
7 <meta http-equiv=
"Content-Type" content=
"text/html;charset=iso-8859-1"/>
8 <meta name=
"generator" content=
"Org-mode"/>
9 <meta name=
"generated" content=
"2009-11-19 18:21:17 MSK"/>
10 <meta name=
"author" content=
"Monahov Dmitry"/>
11 <style type=
"text/css">
12 <!--/*--><![CDATA[/*><!--*/
13 html { font-family: Times, serif; font-size: 12pt; }
14 .title { text-align: center; }
16 .done { color: green; }
17 .tag { background-color:lightblue; font-weight:normal }
19 .timestamp { color: grey }
20 .timestamp-kwd { color: CadetBlue }
21 p.verse { margin-left: 3% }
23 border: 1pt solid #AEBDCC;
24 background-color: #F3F5F7;
26 font-family: courier, monospace;
30 table { border-collapse: collapse; }
31 td, th { vertical-align: top; }
32 dt { font-weight: bold; }
33 div.figure { padding: 0.5em; }
34 div.figure p { text-align: center; }
35 .linenr { font-size:smaller }
36 .code-highlighted {background-color:#ffff00;}
37 .org-info-js_info-navigation { border-style:none; }
38 #org-info-js_console-label { font-size:10px; font-weight:bold;
40 .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
44 <script type="text/javascript">
45 <!--/*--><![CDATA[/*><!--*/
46 function CodeHighlightOn(elem, id)
48 var target = document.getElementById(id);
50 elem.cacheClassElem = elem.className;
51 elem.cacheClassTarget = target.className;
52 target.className = "code-highlighted";
53 elem.className = "code-highlighted";
56 function CodeHighlightOff(elem, id)
58 var target = document.getElementById(id);
59 if(elem.cacheClassElem)
60 elem.className = elem.cacheClassElem;
61 if(elem.cacheClassTarget)
62 target.className = elem.cacheClassTarget;
67 <h1 class="title">quota</h1>
70 <div id="table-of-contents">
71 <h2>Table of Contents</h2>
72 <div id="text-table-of-contents">
74 <li><a href="#sec-1">1 directory tree quota design and implementation </a>
76 <li><a href="#sec-1.1">1.1 STATUS </a></li>
77 <li><a href="#sec-1.2">1.2 Introduction </a></li>
78 <li><a href="#sec-1.3">1.3 Containers fs root requirement </a></li>
79 <li><a href="#sec-1.4">1.4 Containers directory tree-id assumptions </a>
81 <li><a href="#sec-1.4.1">1.4.1 ->rename() restriction </a></li>
82 <li><a href="#sec-1.4.2">1.4.2 ->link restriction </a></li>
85 <li><a href="#sec-1.5">1.5 Patch queue </a></li>
86 <li><a href="#sec-1.6">1.6 How-to </a>
88 <li><a href="#sec-1.6.1">1.6.1 Enabling tree quota an Easy way </a></li>
89 <li><a href="#sec-1.6.2">1.6.2 Enabling tree quota from very beginning </a></li>
90 <li><a href="#sec-1.6.3">1.6.3 Creating containers tree </a></li>
99 <div id="outline-container-1" class="outline-2">
100 <h2 id="sec-1">1 directory tree quota design and implementation </h2>
106 <div id="outline-container-1.1" class="outline-3">
107 <h3 id="sec-1.1">1.1 STATUS </h3>
110 <p>V0.07 :: I've succeed in testing journalled tree-quota. At least it survived
111 in fsstress and other manual tests.
117 <div id="outline-container-1.2" class="outline-3">
118 <h3 id="sec-1.2">1.2 Introduction </h3>
121 <p>This document contains basic introduction to directory tree
122 quota for dedicated trees. Currently Linux support many
123 virtualization extensions. One of approaches is containers.
124 Containers is OS level paravirtualization like jail in BSD.
125 In two words container is a set of process isolated from
126 other system. Each process has it's own name-spaces for
127 network,fs,ipc,etc. You may think of container as secure chroot.
133 <div id="outline-container-1.3" class="outline-3">
134 <h3 id="sec-1.3">1.3 Containers fs root requirement </h3>
137 <p>Container's root are independent tree or several trees.
138 usually they organized like follows <b>/ct-root/CT${ID\}/${tree-content}</b>
139 There are many reasons to keep this trees separate one from another
141 <dt>inode attr</dt><dd>
144 If inode has links in A and B trees. And A-user call chown() for
145 this inode, then B's owner will be surprised.
146 The only way to overcome this is to virtualize inode attributes
147 (for each tree) which is madness IMHO.
149 <dt>checkpoint/restore/online-backup</dt><dd>
152 This is like suspend resume for VM, but in this case only
153 container's process are stopped(freezed) for some time. After CT's
154 process are stopped we may create backup CT's tree without freezing
160 <p>As I already say there are many way to isolate per-container fs-tree.
161 But everyone has strong disadvantages:
163 <dt>Virtual block devices(qemu-like)</dt><dd>
164 problems with consistency and performance
166 <dt>ext3/4 + stack-fs(unionfs)</dt><dd>
167 Bad failure resistance. It is impossible to support jorunalling quota file on stack-fs level.
169 <dt>XFS with proj quota</dt><dd>
170 Lack of quota file journalling.
175 <p>So the only way to implement journalled quota for containers is to
176 implement it on native fs level.
182 <div id="outline-container-1.4" class="outline-3">
183 <h3 id="sec-1.4">1.4 Containers directory tree-id assumptions </h3>
188 Tree id is embedded inside inode
191 Tree id is inherent from parent dir
194 Inode can not belongs to different directory trees
199 <p>Default directory tree (with id == 0) has special meaning.
200 directory which belongs to default tree may contains roots of
201 other trees. Default tree is used for subtree manipulation.
205 <div id="outline-container-1.4.1" class="outline-4">
206 <h4 id="sec-1.4.1">1.4.1 ->rename() restriction </h4>
207 <div id="text-1.4.1">
212 <pre class="example">
213 if (S_ISDIR(old_inode->i_mode)) {
214 if ((new_dir->i_tree_id == 0) || /* move to default tree */
215 (new_dir->i_tree_id == old_inode->i_tree_id)) /*same tree */
219 /* If entry have more than one link then it is bad idea to allow
220 rename it to different (even if it's default tree) tree,
221 because this result in rule (3) violation.
223 if (old_inode->i_nlink > 1) &&
224 (new_dir->i_tree_id != old_inode->i_tree_id)
236 <div id="outline-container-1.4.2" class="outline-4">
237 <h4 id="sec-1.4.2">1.4.2 ->link restriction </h4>
238 <div id="text-1.4.2">
243 <pre class="example">
244 /* Links may belongs to only one tree */
245 if(new_dir->i_tree_id != old_inode->i_tree_id)
256 <div id="outline-container-1.5" class="outline-3">
257 <h3 id="sec-1.5">1.5 Patch queue </h3>
260 <p>I've prepare proof of concept patch queue.
261 <a href="http://www.2ka.mipt.ru/~mov/tree-quota.tgz">patch-queue</a>
266 <div id="outline-container-1.6" class="outline-3">
267 <h3 id="sec-1.6">1.6 How-to </h3>
270 <p>This part contain some tips of tree-quota usage. Assume you have kernel
271 with tree-quota patch applied.
275 <div id="outline-container-1.6.1" class="outline-4">
276 <h4 id="sec-1.6.1">1.6.1 Enabling tree quota an Easy way </h4>
277 <div id="text-1.6.1">
279 <p>You may download small file-system image with tree-quota enabled.
280 <a href="http://www.2ka.mipt.ru/~mov/fs-trquota.img.gz">fs-trquota.img.gz(3Mb)</a>
281 mount /test/fs.img /mnt -oloop,quota,grpquota,treeid,trquota
282 <b>NOTE in order to use journalling quota use following mount options</b>
286 <pre class="example">
287 jqfmt=vfsv0,treeid,trjquota=aquota.tree
293 <pre class="example">
294 Currently quota-tools has no tree-quota support. So you have to manually
295 create aquota.tree file. Just copy quota-tree/tool/aquota.tree to the root
297 mount /test/fs.img /mnt -oloop,quota,grpquota,treeid,trquota
298 cp quota-tree/tool/aquota.tree /mnt/
300 quota-tree/tool/quotactl --on --all --path /mnt --dev /dev/loop0
301 # show quotas type ==0 -> usrquota, type == 2 -> trqota
302 quota-tree/tool/quotactl --get --all --type 2 --dev /dev/loop0
311 <div id="outline-container-1.6.2" class="outline-4">
312 <h4 id="sec-1.6.2">1.6.2 Enabling tree quota from very beginning </h4>
313 <div id="text-1.6.2">
318 <pre class="example">
319 Currently quota-tools has no tree-quota support. So you have to manually
320 create aquota.tree file. Just copy quota-tree/tool/aquota.tree to the root
322 mount /test/fs.img /mnt -oloop,quota,grpquota,treeid,trquota
323 cp quota-tree/tool/aquota.tree /mnt/
325 quota-tree/tool/quotactl --on --all --path /mnt --dev /dev/loop0
326 # show quotas type ==0 -> usrquota, type == 2 -> trqota
327 quota-tree/tool/quotactl --get --all --type 2 --dev /dev/loop0
336 <div id="outline-container-1.6.3" class="outline-4">
337 <h4 id="sec-1.6.3">1.6.3 Creating containers tree </h4>
338 <div id="text-1.6.3">
343 <pre class="example">
344 # create root dir for directory-tree
346 # Assign id for the root
347 ./chattr -Q 1 /mnt/ct-root-1
348 # set quota limits for tree
349 quota-tree/tool/quotactl --set --type 2 --id 1 --bsoft 100000 --bhard 110000 --dev /dev/loop0
351 quota-tree/tool/quotactl --get --all --type 2 --dev /dev/loop0
352 # Populate root with content, it will be accounted in to
353 # tree-quota with id "1"
354 tar zxf root.tar -C /mnt/ct-root-1
356 quota-tree/tool/quotactl --get --all --type 2 --dev /dev/loop0
365 <div id="postamble"><p class="author"> Author: Monahov Dmitry
366 <a href="mailto:mov@jazz.campus"><mov@jazz.campus></a>
368 <p class="date"> Date: 2009-11-19 18:21:17 MSK</p>
369 <p>HTML generated by org-mode 6.21b in emacs 23</p>