https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2017F:_Tutorial_7&feed=atom&action=history
Operating Systems 2017F: Tutorial 7 - Revision history
2024-03-29T05:31:27Z
Revision history for this page on the wiki
MediaWiki 1.37.1
https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2017F:_Tutorial_7&diff=21300&oldid=prev
Soma: /* memoryll.py */
2017-11-25T18:04:22Z
<p><span dir="auto"><span class="autocomment">memoryll.py</span></span></p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 14:04, 25 November 2017</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l39">Line 39:</td>
<td colspan="2" class="diff-lineno">Line 39:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>===memoryll.py===</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>===memoryll.py===</div></td></tr>
<tr><td class="diff-marker" data-marker="−"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><source lang="python"></div></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><source lang="python" <ins style="font-weight: bold; text-decoration: none;">line</ins>></div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>#!/usr/bin/env python</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>#!/usr/bin/env python</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l183">Line 183:</td>
<td colspan="2" class="diff-lineno">Line 183:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> fuse = Memory(argv[1])</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> fuse = Memory(argv[1])</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div></source></div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div></source></div></td></tr>
<tr><td class="diff-marker" data-marker="−"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del style="font-weight: bold; text-decoration: none;"></del></div></td><td colspan="2" class="diff-side-added"></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>===fusell.py===</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>===fusell.py===</div></td></tr>
</table>
Soma
https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2017F:_Tutorial_7&diff=21275&oldid=prev
Soma: /* Exercises */
2017-11-19T22:19:46Z
<p><span dir="auto"><span class="autocomment">Exercises</span></span></p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 18:19, 19 November 2017</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l31">Line 31:</td>
<td colspan="2" class="diff-lineno">Line 31:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># Make a few directories in mnt and populate it with several files. Do you see any errors? What messages does memoryll.py output while doing this?</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># Make a few directories in mnt and populate it with several files. Do you see any errors? What messages does memoryll.py output while doing this?</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># When you make files in mnt, are they normal files? Can they be accessed by regular programs?</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># When you make files in mnt, are they normal files? Can they be accessed by regular programs?</div></td></tr>
<tr><td colspan="2" class="diff-side-deleted"></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"># What permissions do you need to "mount" the filesystem? What about to "umount" it?</ins></div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># What happens to these files when you terminate the memoryll.py script? Can you get the files back?</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># What happens to these files when you terminate the memoryll.py script? Can you get the files back?</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># What system calls are associated with which functions in memoryll.py? How close is the correspondence between system calls made and python function invocations? (Note that if you want to use strace you'll have to do everything as root.)</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># What system calls are associated with which functions in memoryll.py? How close is the correspondence between system calls made and python function invocations? (Note that if you want to use strace you'll have to do everything as root.)</div></td></tr>
</table>
Soma
https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2017F:_Tutorial_7&diff=21274&oldid=prev
Soma: /* Exercises */
2017-11-19T22:09:34Z
<p><span dir="auto"><span class="autocomment">Exercises</span></span></p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 18:09, 19 November 2017</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l32">Line 32:</td>
<td colspan="2" class="diff-lineno">Line 32:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># When you make files in mnt, are they normal files? Can they be accessed by regular programs?</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># When you make files in mnt, are they normal files? Can they be accessed by regular programs?</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># What happens to these files when you terminate the memoryll.py script? Can you get the files back?</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># What happens to these files when you terminate the memoryll.py script? Can you get the files back?</div></td></tr>
<tr><td class="diff-marker" data-marker="−"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div># What system calls are associated with which functions in memoryll.py? How close is the correspondence between system calls made and python function invocations?</div></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div># What system calls are associated with which functions in memoryll.py? How close is the correspondence between system calls made and python function invocations? <ins style="font-weight: bold; text-decoration: none;"> (Note that if you want to use strace you'll have to do everything as root.)</ins></div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># Modify the code so that file renames don't delete the old file but instead just create a new name for it.</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># Modify the code so that file renames don't delete the old file but instead just create a new name for it.</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># Modify the code so that when read, files are converted to upper case.</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div># Modify the code so that when read, files are converted to upper case.</div></td></tr>
</table>
Soma
https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2017F:_Tutorial_7&diff=21273&oldid=prev
Soma at 22:08, 19 November 2017
2017-11-19T22:08:26Z
<p></p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 18:08, 19 November 2017</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l17">Line 17:</td>
<td colspan="2" class="diff-lineno">Line 17:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> python memoryll.py mnt</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> python memoryll.py mnt</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td class="diff-marker" data-marker="−"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>(You <del style="font-weight: bold; text-decoration: none;">should </del>get an error about /etc/fuse.conf is not readable; this is <del style="font-weight: bold; text-decoration: none;">normal and is because regular Ubuntu users aren't </del>in the fuse group.)</div></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>(You <ins style="font-weight: bold; text-decoration: none;">may </ins>get an error about /etc/fuse.conf is not readable; <ins style="font-weight: bold; text-decoration: none;">if so don't worry about it, </ins>this <ins style="font-weight: bold; text-decoration: none;">happens when the user </ins>is <ins style="font-weight: bold; text-decoration: none;">not </ins>in the fuse group.)</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>After you do this, a new filesystem will be mounted on /mnt. '''NOTE: all files created in this directory disappear when the script is terminated!'''</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>After you do this, a new filesystem will be mounted on /mnt. '''NOTE: all files created in this directory disappear when the script is terminated!'''</div></td></tr>
</table>
Soma
https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2017F:_Tutorial_7&diff=21272&oldid=prev
Soma: Created page with "In this tutorial you will be learning about [http://fuse.sourceforge.net/ filesystem in userspace (FUSE)] using an example from [https://github.com/terencehonles/fusepy fusepy..."
2017-11-19T21:55:01Z
<p>Created page with "In this tutorial you will be learning about [http://fuse.sourceforge.net/ filesystem in userspace (FUSE)] using an example from [https://github.com/terencehonles/fusepy fusepy..."</p>
<p><b>New page</b></p><div>In this tutorial you will be learning about [http://fuse.sourceforge.net/ filesystem in userspace (FUSE)] using an example from [https://github.com/terencehonles/fusepy fusepy]. Note the example code is written in Python, not C. The code should be readable even if you are not familiar with Python. When you make changes, keep in mind the following:<br />
* Indentation, not curly braces, is used to denote block structure. Thus indentation matters! Pay particular attention to spaces versus tabs. (When in doubt, don't use tabs.)<br />
* To create a local variable, just assign to it. Python will make sure it is only defined within that function.<br />
* If you just type "python" on the command line you get a read-eval-print loop where you can try things out.<br />
* Python is heavily object oriented, so expect to use methods more than straight functions.<br />
<br />
To get going, first download the [http://homeostasis.scs.carleton.ca/~soma/os-2014f/code/fuse.zip fuse example code] in a zip file. Unpack it and change into the directory in a terminal. You should see two files: fusell.py and memoryll.py (both listed below). We will be running and modifying memoryll.py. For it to work, however, fusell.py has to be in the same directory as memoryll.py.<br />
<br />
Specifically, to get started run the following commands:<br />
wget http://homeostasis.scs.carleton.ca/~soma/os-2014f/code/fuse.zip<br />
unzip fuse.zip<br />
cd fuse<br />
mkdir mnt<br />
<br />
Now to run the example program type:<br />
<br />
python memoryll.py mnt<br />
<br />
(You should get an error about /etc/fuse.conf is not readable; this is normal and is because regular Ubuntu users aren't in the fuse group.)<br />
<br />
After you do this, a new filesystem will be mounted on /mnt. '''NOTE: all files created in this directory disappear when the script is terminated!'''<br />
<br />
To terminate the script, type Control-Z then type "kill %1" (kill first job).<br />
<br />
If you terminate the script and re-run it, you may get errors. To fix them, do the following:<br />
* Make sure no processes are using the mnt directory (e.g., being in that directory in another terminal window).<br />
* sudo umount mnt (while in the fuse directory)<br />
We suggest you leave the memoryll.py script running in one terminal window while doing the following exercises (using GUI programs or commands in another terminal window).<br />
<br />
==Exercises==<br />
# Make a few directories in mnt and populate it with several files. Do you see any errors? What messages does memoryll.py output while doing this?<br />
# When you make files in mnt, are they normal files? Can they be accessed by regular programs?<br />
# What happens to these files when you terminate the memoryll.py script? Can you get the files back?<br />
# What system calls are associated with which functions in memoryll.py? How close is the correspondence between system calls made and python function invocations?<br />
# Modify the code so that file renames don't delete the old file but instead just create a new name for it.<br />
# Modify the code so that when read, files are converted to upper case.<br />
<br />
<br />
===memoryll.py===<br />
<source lang="python"><br />
#!/usr/bin/env python<br />
<br />
from collections import defaultdict<br />
from errno import ENOENT, EROFS<br />
from stat import S_IFMT, S_IMODE, S_IFDIR, S_IFREG<br />
from sys import argv, exit<br />
from time import time<br />
<br />
from fusell import FUSELL<br />
<br />
<br />
class Memory(FUSELL):<br />
def create_ino(self):<br />
self.ino += 1<br />
return self.ino<br />
<br />
def init(self, userdata, conn):<br />
self.ino = 1<br />
self.attr = defaultdict(dict)<br />
self.data = defaultdict(str)<br />
self.parent = {}<br />
self.children = defaultdict(dict)<br />
<br />
self.attr[1] = {'st_ino': 1, 'st_mode': S_IFDIR | 0777, 'st_nlink': 2}<br />
self.parent[1] = 1<br />
<br />
forget = None<br />
<br />
def getattr(self, req, ino, fi):<br />
print 'getattr:', ino<br />
attr = self.attr[ino]<br />
if attr:<br />
self.reply_attr(req, attr, 1.0)<br />
else:<br />
self.reply_err(req, ENOENT)<br />
<br />
def lookup(self, req, parent, name):<br />
print 'lookup:', parent, name<br />
children = self.children[parent]<br />
ino = children.get(name, 0)<br />
attr = self.attr[ino]<br />
<br />
if attr:<br />
entry = {'ino': ino, 'attr': attr, 'atttr_timeout': 1.0, 'entry_timeout': 1.0}<br />
self.reply_entry(req, entry)<br />
else:<br />
self.reply_err(req, ENOENT)<br />
<br />
def mkdir(self, req, parent, name, mode):<br />
print 'mkdir:', parent, name<br />
ino = self.create_ino()<br />
ctx = self.req_ctx(req)<br />
now = time()<br />
attr = {<br />
'st_ino': ino,<br />
'st_mode': S_IFDIR | mode,<br />
'st_nlink': 2,<br />
'st_uid': ctx['uid'],<br />
'st_gid': ctx['gid'],<br />
'st_atime': now,<br />
'st_mtime': now,<br />
'st_ctime': now}<br />
<br />
self.attr[ino] = attr<br />
self.attr[parent]['st_nlink'] += 1<br />
self.parent[ino] = parent<br />
self.children[parent][name] = ino<br />
<br />
entry = {'ino': ino, 'attr': attr, 'atttr_timeout': 1.0, 'entry_timeout': 1.0}<br />
self.reply_entry(req, entry)<br />
<br />
def mknod(self, req, parent, name, mode, rdev):<br />
print 'mknod:', parent, name<br />
ino = self.create_ino()<br />
ctx = self.req_ctx(req)<br />
now = time()<br />
attr = {<br />
'st_ino': ino,<br />
'st_mode': mode,<br />
'st_nlink': 1,<br />
'st_uid': ctx['uid'],<br />
'st_gid': ctx['gid'],<br />
'st_rdev': rdev,<br />
'st_atime': now,<br />
'st_mtime': now,<br />
'st_ctime': now}<br />
<br />
self.attr[ino] = attr<br />
self.attr[parent]['st_nlink'] += 1<br />
self.children[parent][name] = ino<br />
<br />
entry = {'ino': ino, 'attr': attr, 'atttr_timeout': 1.0, 'entry_timeout': 1.0}<br />
self.reply_entry(req, entry)<br />
<br />
def open(self, req, ino, fi):<br />
print 'open:', ino<br />
self.reply_open(req, fi)<br />
<br />
def read(self, req, ino, size, off, fi):<br />
print 'read:', ino, size, off<br />
buf = self.data[ino][off:(off + size)]<br />
self.reply_buf(req, buf)<br />
<br />
def readdir(self, req, ino, size, off, fi):<br />
print 'readdir:', ino<br />
parent = self.parent[ino]<br />
entries = [('.', {'st_ino': ino, 'st_mode': S_IFDIR}),<br />
('..', {'st_ino': parent, 'st_mode': S_IFDIR})]<br />
for name, child in self.children[ino].items():<br />
entries.append((name, self.attr[child]))<br />
self.reply_readdir(req, size, off, entries) <br />
<br />
def rename(self, req, parent, name, newparent, newname):<br />
print 'rename:', parent, name, newparent, newname<br />
ino = self.children[parent].pop(name)<br />
self.children[newparent][newname] = ino<br />
self.parent[ino] = newparent<br />
self.reply_err(req, 0)<br />
<br />
def setattr(self, req, ino, attr, to_set, fi):<br />
print 'setattr:', ino, to_set<br />
a = self.attr[ino]<br />
for key in to_set:<br />
if key == 'st_mode':<br />
# Keep the old file type bit fields<br />
a['st_mode'] = S_IFMT(a['st_mode']) | S_IMODE(attr['st_mode'])<br />
else:<br />
a[key] = attr[key]<br />
self.attr[ino] = a<br />
self.reply_attr(req, a, 1.0)<br />
<br />
def write(self, req, ino, buf, off, fi):<br />
print 'write:', ino, off, len(buf)<br />
self.data[ino] = self.data[ino][:off] + buf<br />
self.attr[ino]['st_size'] = len(self.data[ino])<br />
self.reply_write(req, len(buf))<br />
<br />
if __name__ == '__main__':<br />
if len(argv) != 2:<br />
print 'usage: %s <mountpoint>' % argv[0]<br />
exit(1) <br />
fuse = Memory(argv[1])<br />
</source><br />
<br />
<br />
===fusell.py===<br />
<source lang="python"><br />
# Copyright (c) 2010 Giorgos Verigakis <verigak@gmail.com><br />
# <br />
# Permission to use, copy, modify, and distribute this software for any<br />
# purpose with or without fee is hereby granted, provided that the above<br />
# copyright notice and this permission notice appear in all copies.<br />
# <br />
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES<br />
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF<br />
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR<br />
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES<br />
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN<br />
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF<br />
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.<br />
<br />
from __future__ import division<br />
<br />
from ctypes import *<br />
from ctypes.util import find_library<br />
from errno import *<br />
from functools import partial, wraps<br />
from inspect import getmembers, ismethod<br />
from platform import machine, system<br />
from stat import S_IFDIR, S_IFREG<br />
<br />
<br />
_system = system()<br />
_machine = machine()<br />
<br />
class LibFUSE(CDLL):<br />
def __init__(self):<br />
if _system == 'Darwin':<br />
self.libiconv = CDLL(find_library('iconv'), RTLD_GLOBAL)<br />
super(LibFUSE, self).__init__(find_library('fuse'))<br />
<br />
self.fuse_mount.argtypes = (c_char_p, POINTER(fuse_args))<br />
self.fuse_mount.restype = c_void_p<br />
self.fuse_lowlevel_new.argtypes = (POINTER(fuse_args), POINTER(fuse_lowlevel_ops),<br />
c_size_t, c_void_p)<br />
self.fuse_lowlevel_new.restype = c_void_p<br />
self.fuse_set_signal_handlers.argtypes = (c_void_p,)<br />
self.fuse_session_add_chan.argtypes = (c_void_p, c_void_p)<br />
self.fuse_session_loop.argtypes = (c_void_p,)<br />
self.fuse_remove_signal_handlers.argtypes = (c_void_p,)<br />
self.fuse_session_remove_chan.argtypes = (c_void_p,)<br />
self.fuse_session_destroy.argtypes = (c_void_p,)<br />
self.fuse_unmount.argtypes = (c_char_p, c_void_p)<br />
<br />
self.fuse_req_ctx.restype = POINTER(fuse_ctx)<br />
self.fuse_req_ctx.argtypes = (fuse_req_t,)<br />
<br />
self.fuse_reply_err.argtypes = (fuse_req_t, c_int)<br />
self.fuse_reply_attr.argtypes = (fuse_req_t, c_void_p, c_double)<br />
self.fuse_reply_entry.argtypes = (fuse_req_t, c_void_p)<br />
self.fuse_reply_open.argtypes = (fuse_req_t, c_void_p)<br />
self.fuse_reply_buf.argtypes = (fuse_req_t, c_char_p, c_size_t)<br />
self.fuse_reply_write.argtypes = (fuse_req_t, c_size_t)<br />
<br />
self.fuse_add_direntry.argtypes = (c_void_p, c_char_p, c_size_t, c_char_p,<br />
c_stat_p, c_off_t)<br />
<br />
class fuse_args(Structure):<br />
_fields_ = [('argc', c_int), ('argv', POINTER(c_char_p)), ('allocated', c_int)]<br />
<br />
class c_timespec(Structure):<br />
_fields_ = [('tv_sec', c_long), ('tv_nsec', c_long)]<br />
<br />
class c_stat(Structure):<br />
pass # Platform dependent<br />
<br />
if _system == 'Darwin':<br />
ENOTSUP = 45<br />
c_dev_t = c_int32<br />
c_fsblkcnt_t = c_ulong<br />
c_fsfilcnt_t = c_ulong<br />
c_gid_t = c_uint32<br />
c_mode_t = c_uint16<br />
c_off_t = c_int64<br />
c_pid_t = c_int32<br />
c_uid_t = c_uint32<br />
c_stat._fields_ = [<br />
('st_dev', c_dev_t),<br />
('st_ino', c_uint32),<br />
('st_mode', c_mode_t),<br />
('st_nlink', c_uint16),<br />
('st_uid', c_uid_t),<br />
('st_gid', c_gid_t),<br />
('st_rdev', c_dev_t),<br />
('st_atimespec', c_timespec),<br />
('st_mtimespec', c_timespec),<br />
('st_ctimespec', c_timespec),<br />
('st_size', c_off_t),<br />
('st_blocks', c_int64),<br />
('st_blksize', c_int32)]<br />
elif _system == 'Linux':<br />
ENOTSUP = 95<br />
c_dev_t = c_ulonglong<br />
c_fsblkcnt_t = c_ulonglong<br />
c_fsfilcnt_t = c_ulonglong<br />
c_gid_t = c_uint<br />
c_mode_t = c_uint<br />
c_off_t = c_longlong<br />
c_pid_t = c_int<br />
c_uid_t = c_uint<br />
<br />
if _machine == 'x86_64':<br />
c_stat._fields_ = [<br />
('st_dev', c_dev_t),<br />
('st_ino', c_ulong),<br />
('st_nlink', c_ulong),<br />
('st_mode', c_mode_t),<br />
('st_uid', c_uid_t),<br />
('st_gid', c_gid_t),<br />
('__pad0', c_int),<br />
('st_rdev', c_dev_t),<br />
('st_size', c_off_t),<br />
('st_blksize', c_long),<br />
('st_blocks', c_long),<br />
('st_atimespec', c_timespec),<br />
('st_mtimespec', c_timespec),<br />
('st_ctimespec', c_timespec)]<br />
elif _machine == 'ppc':<br />
c_stat._fields_ = [<br />
('st_dev', c_dev_t),<br />
('st_ino', c_ulonglong),<br />
('st_mode', c_mode_t),<br />
('st_nlink', c_uint),<br />
('st_uid', c_uid_t),<br />
('st_gid', c_gid_t),<br />
('st_rdev', c_dev_t),<br />
('__pad2', c_ushort),<br />
('st_size', c_off_t),<br />
('st_blksize', c_long),<br />
('st_blocks', c_longlong),<br />
('st_atimespec', c_timespec),<br />
('st_mtimespec', c_timespec),<br />
('st_ctimespec', c_timespec)]<br />
else:<br />
# i686, use as fallback for everything else<br />
c_stat._fields_ = [<br />
('st_dev', c_dev_t),<br />
('__pad1', c_ushort),<br />
('__st_ino', c_ulong),<br />
('st_mode', c_mode_t),<br />
('st_nlink', c_uint),<br />
('st_uid', c_uid_t),<br />
('st_gid', c_gid_t),<br />
('st_rdev', c_dev_t),<br />
('__pad2', c_ushort),<br />
('st_size', c_off_t),<br />
('st_blksize', c_long),<br />
('st_blocks', c_longlong),<br />
('st_atimespec', c_timespec),<br />
('st_mtimespec', c_timespec),<br />
('st_ctimespec', c_timespec),<br />
('st_ino', c_ulonglong)]<br />
else:<br />
raise NotImplementedError('%s is not supported.' % _system)<br />
<br />
class c_statvfs(Structure):<br />
_fields_ = [<br />
('f_bsize', c_ulong),<br />
('f_frsize', c_ulong),<br />
('f_blocks', c_fsblkcnt_t),<br />
('f_bfree', c_fsblkcnt_t),<br />
('f_bavail', c_fsblkcnt_t),<br />
('f_files', c_fsfilcnt_t),<br />
('f_ffree', c_fsfilcnt_t),<br />
('f_favail', c_fsfilcnt_t)]<br />
<br />
class fuse_file_info(Structure):<br />
_fields_ = [<br />
('flags', c_int),<br />
('fh_old', c_ulong),<br />
('writepage', c_int),<br />
('direct_io', c_uint, 1),<br />
('keep_cache', c_uint, 1),<br />
('flush', c_uint, 1),<br />
('padding', c_uint, 29),<br />
('fh', c_uint64),<br />
('lock_owner', c_uint64)]<br />
<br />
class fuse_ctx(Structure):<br />
_fields_ = [('uid', c_uid_t), ('gid', c_gid_t), ('pid', c_pid_t)]<br />
<br />
fuse_ino_t = c_ulong<br />
fuse_req_t = c_void_p<br />
c_stat_p = POINTER(c_stat)<br />
fuse_file_info_p = POINTER(fuse_file_info)<br />
<br />
FUSE_SET_ATTR = ('st_mode', 'st_uid', 'st_gid', 'st_size', 'st_atime', 'st_mtime')<br />
<br />
class fuse_entry_param(Structure):<br />
_fields_ = [<br />
('ino', fuse_ino_t),<br />
('generation', c_ulong),<br />
('attr', c_stat),<br />
('attr_timeout', c_double),<br />
('entry_timeout', c_double)]<br />
<br />
class fuse_lowlevel_ops(Structure):<br />
_fields_ = [<br />
('init', CFUNCTYPE(None, c_void_p, c_void_p)),<br />
('destroy', CFUNCTYPE(None, c_void_p)),<br />
('lookup', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_char_p)),<br />
('forget', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_ulong)),<br />
('getattr', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, fuse_file_info_p)),<br />
('setattr', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_stat_p, c_int, fuse_file_info_p)),<br />
('readlink', CFUNCTYPE(None, fuse_req_t, fuse_ino_t)),<br />
('mknod', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_char_p, c_mode_t, c_dev_t)),<br />
('mkdir', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_char_p, c_mode_t)),<br />
('unlink', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_char_p)),<br />
('rmdir', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_char_p)),<br />
('symlink', CFUNCTYPE(None, fuse_req_t, c_char_p, fuse_ino_t, c_char_p)),<br />
('rename', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_char_p, fuse_ino_t, c_char_p)),<br />
('link', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, fuse_ino_t, c_char_p)),<br />
('open', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, fuse_file_info_p)),<br />
('read', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_size_t, c_off_t, fuse_file_info_p)),<br />
('write', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_char_p, c_size_t, c_off_t,<br />
fuse_file_info_p)),<br />
('flush', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, fuse_file_info_p)),<br />
('release', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, fuse_file_info_p)),<br />
('fsync', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_int, fuse_file_info_p)),<br />
('opendir', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, fuse_file_info_p)),<br />
('readdir', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_size_t, c_off_t, fuse_file_info_p)),<br />
('releasedir', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, fuse_file_info_p)),<br />
('fsyncdir', CFUNCTYPE(None, fuse_req_t, fuse_ino_t, c_int, fuse_file_info_p))]<br />
<br />
<br />
def struct_to_dict(p):<br />
try:<br />
x = p.contents<br />
return dict((key, getattr(x, key)) for key, type in x._fields_)<br />
except ValueError:<br />
return {}<br />
<br />
def stat_to_dict(p):<br />
try:<br />
d = {}<br />
x = p.contents<br />
for key, type in x._fields_:<br />
if key in ('st_atimespec', 'st_mtimespec', 'st_ctimespec'):<br />
ts = getattr(x, key)<br />
key = key[:-4] # Lose the "spec"<br />
d[key] = ts.tv_sec + ts.tv_nsec / 10 ** 9<br />
else:<br />
d[key] = getattr(x, key)<br />
return d<br />
except ValueError:<br />
return {}<br />
<br />
def dict_to_stat(d):<br />
for key in ('st_atime', 'st_mtime', 'st_ctime'):<br />
if key in d:<br />
val = d[key]<br />
sec = int(val)<br />
nsec = int((val - sec) * 10 ** 9)<br />
d[key + 'spec'] = c_timespec(sec, nsec)<br />
return c_stat(**d)<br />
<br />
def setattr_mask_to_list(mask):<br />
return [FUSE_SET_ATTR[i] for i in range(len(FUSE_SET_ATTR)) if mask & (1 << i)]<br />
<br />
class FUSELL(object):<br />
def __init__(self, mountpoint):<br />
self.libfuse = LibFUSE() <br />
<br />
fuse_ops = fuse_lowlevel_ops()<br />
<br />
for name, prototype in fuse_lowlevel_ops._fields_:<br />
method = getattr(self, 'fuse_' + name, None) or getattr(self, name, None)<br />
if method:<br />
setattr(fuse_ops, name, prototype(method))<br />
<br />
args = ['fuse']<br />
argv = fuse_args(len(args), (c_char_p * len(args))(*args), 0)<br />
<br />
# TODO: handle initialization errors<br />
<br />
chan = self.libfuse.fuse_mount(mountpoint, argv)<br />
assert chan<br />
<br />
session = self.libfuse.fuse_lowlevel_new(argv, byref(fuse_ops), sizeof(fuse_ops), None)<br />
assert session<br />
<br />
err = self.libfuse.fuse_set_signal_handlers(session)<br />
assert err == 0<br />
<br />
self.libfuse.fuse_session_add_chan(session, chan)<br />
<br />
err = self.libfuse.fuse_session_loop(session)<br />
assert err == 0<br />
<br />
err = self.libfuse.fuse_remove_signal_handlers(session)<br />
assert err == 0<br />
<br />
self.libfuse.fuse_session_remove_chan(chan)<br />
self.libfuse.fuse_session_destroy(session)<br />
self.libfuse.fuse_unmount(mountpoint, chan)<br />
<br />
def reply_err(self, req, err):<br />
return self.libfuse.fuse_reply_err(req, err)<br />
<br />
def reply_none(self, req):<br />
self.libfuse.fuse_reply_none(req)<br />
<br />
def reply_entry(self, req, entry):<br />
entry['attr'] = c_stat(**entry['attr'])<br />
e = fuse_entry_param(**entry)<br />
self.libfuse.fuse_reply_entry(req, byref(e))<br />
<br />
def reply_create(self, req, *args):<br />
pass # XXX<br />
<br />
def reply_attr(self, req, attr, attr_timeout):<br />
st = dict_to_stat(attr)<br />
return self.libfuse.fuse_reply_attr(req, byref(st), c_double(attr_timeout))<br />
<br />
def reply_readlink(self, req, *args):<br />
pass # XXX<br />
<br />
def reply_open(self, req, d):<br />
fi = fuse_file_info(**d)<br />
return self.libfuse.fuse_reply_open(req, byref(fi))<br />
<br />
def reply_write(self, req, count):<br />
return self.libfuse.fuse_reply_write(req, count)<br />
<br />
def reply_buf(self, req, buf):<br />
return self.libfuse.fuse_reply_buf(req, buf, len(buf))<br />
<br />
def reply_readdir(self, req, size, off, entries):<br />
bufsize = 0<br />
sized_entries = []<br />
for name, attr in entries:<br />
entsize = self.libfuse.fuse_add_direntry(req, None, 0, name, None, 0)<br />
sized_entries.append((name, attr, entsize))<br />
bufsize += entsize<br />
<br />
next = 0<br />
buf = create_string_buffer(bufsize)<br />
for name, attr, entsize in sized_entries:<br />
entbuf = cast(addressof(buf) + next, c_char_p)<br />
st = c_stat(**attr)<br />
next += entsize<br />
self.libfuse.fuse_add_direntry(req, entbuf, entsize, name, byref(st), next)<br />
<br />
if off < bufsize:<br />
buf = cast(addressof(buf) + off, c_char_p) if off else buf<br />
return self.libfuse.fuse_reply_buf(req, buf, min(bufsize - off, size))<br />
else:<br />
return self.libfuse.fuse_reply_buf(req, None, 0)<br />
<br />
<br />
# If you override the following methods you should reply directly<br />
# with the self.libfuse.fuse_reply_* methods.<br />
<br />
def fuse_getattr(self, req, ino, fi):<br />
self.getattr(req, ino, struct_to_dict(fi))<br />
<br />
def fuse_setattr(self, req, ino, attr, to_set, fi):<br />
attr_dict = stat_to_dict(attr)<br />
to_set_list = setattr_mask_to_list(to_set)<br />
fi_dict = struct_to_dict(fi)<br />
self.setattr(req, ino, attr_dict, to_set_list, fi_dict)<br />
<br />
def fuse_open(self, req, ino, fi):<br />
self.open(req, ino, struct_to_dict(fi))<br />
<br />
def fuse_read(self, req, ino, size, off, fi):<br />
self.read(req, ino, size, off, fi)<br />
<br />
def fuse_write(self, req, ino, buf, size, off, fi):<br />
buf_str = string_at(buf, size)<br />
fi_dict = struct_to_dict(fi)<br />
self.write(req, ino, buf_str, off, fi_dict)<br />
<br />
def fuse_flush(self, req, ino, fi):<br />
self.flush(req, ino, struct_to_dict(fi))<br />
<br />
def fuse_release(self, req, ino, fi):<br />
self.release(req, ino, struct_to_dict(fi))<br />
<br />
def fuse_fsync(self, req, ino, datasync, fi):<br />
self.fsyncdir(req, ino, datasync, struct_to_dict(fi))<br />
<br />
def fuse_opendir(self, req, ino, fi):<br />
self.opendir(req, ino, struct_to_dict(fi))<br />
<br />
def fuse_readdir(self, req, ino, size, off, fi):<br />
self.readdir(req, ino, size, off, struct_to_dict(fi))<br />
<br />
def fuse_releasedir(self, req, ino, fi):<br />
self.releasedir(req, ino, struct_to_dict(fi))<br />
<br />
def fuse_fsyncdir(self, req, ino, datasync, fi):<br />
self.fsyncdir(req, ino, datasync, struct_to_dict(fi))<br />
<br />
<br />
# Utility methods<br />
<br />
def req_ctx(self, req):<br />
ctx = self.libfuse.fuse_req_ctx(req)<br />
return struct_to_dict(ctx)<br />
<br />
<br />
# Methods to be overridden in subclasses.<br />
# Reply with the self.reply_* methods.<br />
<br />
def init(self, userdata, conn):<br />
"""Initialize filesystem<br />
<br />
There's no reply to this method<br />
"""<br />
pass<br />
<br />
def destroy(self, userdata):<br />
"""Clean up filesystem<br />
<br />
There's no reply to this method<br />
"""<br />
pass<br />
<br />
def lookup(self, req, parent, name):<br />
"""Look up a directory entry by name and get its attributes.<br />
<br />
Valid replies:<br />
reply_entry<br />
reply_err<br />
"""<br />
self.reply_err(req, ENOENT)<br />
<br />
def forget(self, req, ino, nlookup):<br />
"""Forget about an inode<br />
<br />
Valid replies:<br />
reply_none<br />
"""<br />
self.reply_none(req)<br />
<br />
def getattr(self, req, ino, fi):<br />
"""Get file attributes<br />
<br />
Valid replies:<br />
reply_attr<br />
reply_err<br />
"""<br />
if ino == 1:<br />
attr = {'st_ino': 1, 'st_mode': S_IFDIR | 0755, 'st_nlink': 2}<br />
self.reply_attr(req, attr, 1.0)<br />
else:<br />
self.reply_err(req, ENOENT) <br />
<br />
def setattr(self, req, ino, attr, to_set, fi):<br />
"""Set file attributes<br />
<br />
Valid replies:<br />
reply_attr<br />
reply_err<br />
"""<br />
self.reply_err(req, EROFS)<br />
<br />
def readlink(self, req, ino):<br />
"""Read symbolic link<br />
<br />
Valid replies:<br />
reply_readlink<br />
reply_err<br />
"""<br />
self.reply_err(req, ENOENT)<br />
<br />
def mknod(self, req, parent, name, mode, rdev):<br />
"""Create file node<br />
<br />
Valid replies:<br />
reply_entry<br />
reply_err<br />
"""<br />
self.reply_err(req, EROFS)<br />
<br />
def mkdir(self, req, parent, name, mode):<br />
"""Create a directory<br />
<br />
Valid replies:<br />
reply_entry<br />
reply_err<br />
"""<br />
self.reply_err(req, EROFS)<br />
<br />
def unlink(self, req, parent, name):<br />
"""Remove a file<br />
<br />
Valid replies:<br />
reply_err<br />
"""<br />
self.reply_err(req, EROFS)<br />
<br />
def rmdir(self, req, parent, name):<br />
"""Remove a directory<br />
<br />
Valid replies:<br />
reply_err<br />
"""<br />
self.reply_err(req, EROFS)<br />
<br />
def symlink(self, req, link, parent, name):<br />
"""Create a symbolic link<br />
<br />
Valid replies:<br />
reply_entry<br />
reply_err<br />
"""<br />
self.reply_err(req, EROFS)<br />
<br />
def rename(self, req, parent, name, newparent, newname):<br />
"""Rename a file<br />
<br />
Valid replies:<br />
reply_err<br />
"""<br />
self.reply_err(req, EROFS)<br />
<br />
def link(self, req, ino, newparent, newname):<br />
"""Create a hard link<br />
<br />
Valid replies:<br />
reply_entry<br />
reply_err<br />
"""<br />
self.reply_err(req, EROFS)<br />
<br />
def open(self, req, ino, fi):<br />
"""Open a file<br />
<br />
Valid replies:<br />
reply_open<br />
reply_err<br />
"""<br />
self.reply_open(req, fi)<br />
<br />
def read(self, req, ino, size, off, fi):<br />
"""Read data<br />
<br />
Valid replies:<br />
reply_buf<br />
reply_err<br />
"""<br />
self.reply_err(req, EIO)<br />
<br />
def write(self, req, ino, buf, off, fi):<br />
"""Write data<br />
<br />
Valid replies:<br />
reply_write<br />
reply_err<br />
"""<br />
self.reply_err(req, EROFS)<br />
<br />
def flush(self, req, ino, fi):<br />
"""Flush method<br />
<br />
Valid replies:<br />
reply_err<br />
"""<br />
self.reply_err(req, 0)<br />
<br />
def release(self, req, ino, fi):<br />
"""Release an open file<br />
<br />
Valid replies:<br />
reply_err<br />
"""<br />
self.reply_err(req, 0)<br />
<br />
def fsync(self, req, ino, datasync, fi):<br />
"""Synchronize file contents<br />
<br />
Valid replies:<br />
reply_err<br />
"""<br />
self.reply_err(req, 0)<br />
<br />
def opendir(self, req, ino, fi):<br />
"""Open a directory<br />
<br />
Valid replies:<br />
reply_open<br />
reply_err<br />
"""<br />
self.reply_open(req, fi)<br />
<br />
def readdir(self, req, ino, size, off, fi):<br />
"""Read directory<br />
<br />
Valid replies:<br />
reply_readdir<br />
reply_err<br />
"""<br />
if ino == 1:<br />
attr = {'st_ino': 1, 'st_mode': S_IFDIR}<br />
entries = [('.', attr), ('..', attr)]<br />
self.reply_readdir(req, size, off, entries)<br />
else:<br />
self.reply_err(req, ENOENT)<br />
<br />
def releasedir(self, req, ino, fi):<br />
"""Release an open directory<br />
<br />
Valid replies:<br />
reply_err<br />
"""<br />
self.reply_err(req, 0)<br />
<br />
def fsyncdir(self, req, ino, datasync, fi):<br />
"""Synchronize directory contents<br />
<br />
Valid replies:<br />
reply_err<br />
"""<br />
self.reply_err(req, 0)<br />
</source></div>
Soma