~doctormo/+junk/gremlinfuse

« back to all changes in this revision

Viewing changes to gremlin-fuse.py

  • Committer: Martin Owens
  • Date: 2013-06-29 03:07:33 UTC
  • Revision ID: doctormo@gmail.com-20130629030733-8it96wb9aob6o8je
First commit of gremlin fuse

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
#
 
3
# Taken from http://sourceforge.net/apps/mediawiki/fuse/?title=FUSE_Python_tutorial
 
4
#
 
5
# Modified by Martin Owens 2013
 
6
#
 
7
# This fuse script attempts to cause trouble for the file system, so you can
 
8
# test your applications and how they deal with mis-behaving file systems.
 
9
# Especially useful for network file system issues.
 
10
#
 
11
 
 
12
import os      # for filesystem modes(O_RDONLY, etc)
 
13
import sys     # Get ARGV inputs
 
14
import time    # Pause and wait for nothing
 
15
import fuse    # User Space FileSystem
 
16
import stat    # for file properties
 
17
import errno   # for error number codes(ENOENT, etc)
 
18
               # - note: these must be returned as negatives
 
19
 
 
20
fuse.fuse_python_api =(0, 2)
 
21
 
 
22
_path = '/gizmo.svg'
 
23
_content = """<?xml version="1.0" encoding="UTF-8"?>
 
24
<svg height="120" width="120"><g>
 
25
<rect x="10" y="10" width="100" height="100" style="fill:#aaccee;stroke:#6699cc;stroke-width:12;stroke-opacity:1;"/>
 
26
</g></svg>"""
 
27
 
 
28
def dirFromList(list):
 
29
    """
 
30
    Return a properly formatted list of items suitable to a directory listing.
 
31
    [['a', 'b', 'c']] => [[('a', 0),('b', 0),('c', 0)]]
 
32
    """
 
33
    return [[(x, 0) for x in list]]
 
34
 
 
35
def getDepth(path):
 
36
    """
 
37
    Return the depth of a given path, zero-based from root('/')
 
38
    """
 
39
    if path == '/':
 
40
        return 0
 
41
    else:
 
42
        return path.count('/')
 
43
 
 
44
def getParts(path):
 
45
    """
 
46
    Return the slash-separated parts of a given path as a list
 
47
    """
 
48
    if path == '/':
 
49
        return [['/']]
 
50
    else:
 
51
        return path.split('/')
 
52
 
 
53
class MyStat(fuse.Stat):
 
54
    def __init__(self):
 
55
        self.st_mode = 0
 
56
        self.st_ino = 0
 
57
        self.st_dev = 0
 
58
        self.st_nlink = 0
 
59
        self.st_uid = 0
 
60
        self.st_gid = 0
 
61
        self.st_size = 0
 
62
        self.st_atime = 0
 
63
        self.st_mtime = 0
 
64
        self.st_ctime = 0
 
65
 
 
66
class GremlinFS(fuse.Fuse):
 
67
    """Simple File system for causing mischief"""
 
68
    def __init__(self, *args, **kw):
 
69
        self.what = kw.pop('what', None) or 'attr'
 
70
        fuse.Fuse.__init__(self, *args, **kw)
 
71
        self.fuse_args.setmod('foreground')
 
72
        sys.stderr.write("File System Online: Breaking on %s!\n" % self.what)
 
73
 
 
74
    def midnight_feast(self, name, path):
 
75
        """Block a call forever!"""
 
76
        if path != _path:
 
77
            print " [ ] Ignoring %s for %s" % (name, path)
 
78
            return
 
79
        print " [X] Blocking %s for '%s'" % (name, path)
 
80
        if sys.stdin.read(1) == 'q':
 
81
            self.parser.exit(status=0, msg="Exiting!")
 
82
        print " [:] Continuing for '%s'" % (path)
 
83
 
 
84
    def getattr(self, path):
 
85
        if self.what == 'attr':
 
86
            self.midnight_feast("Get Attribute", path)
 
87
        st = MyStat()
 
88
        if path in ['/', '']:
 
89
            st.st_mode = stat.S_IFDIR | 0755
 
90
            st.st_nlink = 2
 
91
        elif path == _path:
 
92
            st.st_mode = stat.S_IFREG | 0444
 
93
            st.st_nlink = 1
 
94
            st.st_size = len(_content)
 
95
        else:
 
96
            return -errno.ENOSYS
 
97
        return st
 
98
 
 
99
    def chmod(self, path, mode ):
 
100
        if self.what == 'chmod':
 
101
            self.midnight_feast("Change Mode", path)
 
102
        return -errno.ENOSYS
 
103
 
 
104
    def chown(self, path, uid, gid ):
 
105
        if self.what == 'chown':
 
106
            self.midnight_feast("Change Owner", path)
 
107
        return -errno.ENOSYS
 
108
 
 
109
    def fsync(self, path, isFsyncFile ):
 
110
        if self.what == 'fsync':
 
111
            self.midnight_feast("File Sync", path)
 
112
        return -errno.ENOSYS
 
113
 
 
114
    def link(self, targetPath, linkPath ):
 
115
        if self.what == 'link':
 
116
            self.midnight_feast("Link Path", path)
 
117
        return -errno.ENOSYS
 
118
 
 
119
    def mkdir(self, path, mode ):
 
120
        if self.what == 'mkdir':
 
121
            self.midnight_feast("Make Directory", path)
 
122
        return -errno.ENOSYS
 
123
 
 
124
    def mknod(self, path, mode, dev ):
 
125
        if self.what == 'mknod':
 
126
            self.midnight_feast("Make Node", path)
 
127
        return -errno.ENOSYS
 
128
 
 
129
    def open(self, path, flags ):
 
130
        if self.what == 'open':
 
131
            self.midnight_feast("Open File", path)
 
132
        if path != _path:
 
133
            return -errno.ENOENT
 
134
        accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
 
135
        if (flags & accmode) != os.O_RDONLY:
 
136
            return -errno.EACCES
 
137
 
 
138
    def read(self, path, size, offset):
 
139
        if self.what == 'read':
 
140
            self.midnight_feast("Read File", path)
 
141
        if path != _path:
 
142
            return -errno.ENOENT
 
143
        slen = len(_content)
 
144
        if offset < slen:
 
145
            if offset + size > slen:
 
146
                size = slen - offset
 
147
            buf = _content[offset:offset+size]
 
148
        else:
 
149
            buf = ''
 
150
        return buf
 
151
 
 
152
    def readdir(self, path, offset ):
 
153
        if self.what == 'readdir':
 
154
            self.midnight_feast("Read Directory", path)
 
155
        for r in  '.', '..', _path:
 
156
            yield fuse.Direntry(r)
 
157
 
 
158
    def readlink(self, path ):
 
159
        if self.what == 'readlink':
 
160
            self.midnight_feast("Read Link", path)
 
161
        return -errno.ENOSYS
 
162
 
 
163
    def release(self, path, flags ):
 
164
        if self.what == 'release':
 
165
            self.midnight_feast("Release", path)
 
166
        return -errno.ENOSYS
 
167
 
 
168
    def rename(self, oldPath, newPath ):
 
169
        if self.what == 'rename':
 
170
            self.midnight_feast("Rename Path", oldPath)
 
171
        return -errno.ENOSYS
 
172
 
 
173
    def rmdir(self, path ):
 
174
        if self.what == 'rmdir':
 
175
            self.midnight_feast("Remove Directory", path)
 
176
        return -errno.ENOSYS
 
177
 
 
178
    def statfs(self ):
 
179
        if self.what == 'statfs':
 
180
            self.midnight_feast("File System Status", None)
 
181
        return -errno.ENOSYS
 
182
 
 
183
    def symlink(self, targetPath, linkPath ):
 
184
        if self.what == 'symlink':
 
185
            self.midnight_feast("Make Symbolic Link", targetPath)
 
186
        return -errno.ENOSYS
 
187
 
 
188
    def truncate(self, path, size ):
 
189
        if self.what == 'truncate':
 
190
            self.midnight_feast("Truncate File", path)
 
191
        return -errno.ENOSYS
 
192
 
 
193
    def unlink(self, path ):
 
194
        if self.what == 'unlink':
 
195
            self.midnight_feast("Delete File", path)
 
196
        return -errno.ENOSYS
 
197
 
 
198
    def utime(self, path, times ):
 
199
        if self.what == 'utime':
 
200
            self.midnight_feast("Get Update Time", path)
 
201
        return -errno.ENOSYS
 
202
 
 
203
    def write(self, path, buf, offset ):
 
204
        if self.what == 'write':
 
205
            self.midnight_feast("Write to File", path)
 
206
        return -errno.ENOSYS
 
207
 
 
208
import signal
 
209
 
 
210
if __name__ == '__main__':
 
211
    if len(sys.argv) != 2:
 
212
        print 'usage: %s <mountpoint> [freeze-on-what]' % sys.argv[0]
 
213
        exit(1)
 
214
    what = len(sys.argv) == 3 and sys.argv[2] or None
 
215
 
 
216
    fs = GremlinFS(what=what)
 
217
    fs.parse(errex=1)
 
218
    fs.flags = 0
 
219
    fs.multithreaded = 0
 
220
    fs.main()
 
221
 
 
222