aboutsummaryrefslogtreecommitdiffstats
path: root/fusearchive.py
diff options
context:
space:
mode:
authorSteve Slaven <bpk@hoopajoo.net>2009-07-23 16:48:31 (GMT)
committerSteve Slaven <bpk@hoopajoo.net>2009-07-23 16:48:31 (GMT)
commit505e75eee4c35bdf7cefb1fedaac99ee920b6177 (patch)
treee8a6959c98eece821c5ed95b58829b6b3bc73fa3 /fusearchive.py
parent89ef51df1680c7c4a7f8a155d87a21b448d91555 (diff)
downloadfusearchive-505e75eee4c35bdf7cefb1fedaac99ee920b6177.zip
fusearchive-505e75eee4c35bdf7cefb1fedaac99ee920b6177.tar.gz
fusearchive-505e75eee4c35bdf7cefb1fedaac99ee920b6177.tar.bz2
Converted debugging messages to print based on levels, fix truncate to use
the archive file ftruncate to make sure we don't hose up the file format
Diffstat (limited to 'fusearchive.py')
-rwxr-xr-xfusearchive.py84
1 files changed, 49 insertions, 35 deletions
diff --git a/fusearchive.py b/fusearchive.py
index 6f6305f..328ee49 100755
--- a/fusearchive.py
+++ b/fusearchive.py
@@ -2,6 +2,7 @@
# Copyright (C) 2001 Jeff Epler <jepler@unpythonic.dhs.org>
# Copyright (C) 2006 Csaba Henk <csaba.henk@creo.hu>
+# Copyright (C) 2009 Steve Slaven <bpk@hoopajoo.net>
#
# This program can be distributed under the terms of the GNU LGPL.
# See the file COPYING.
@@ -25,6 +26,11 @@ fuse.feature_assert('stateful_files', 'has_init')
magic_blocksize = 1024 * 32
magic_depth = 5
+debug_level = 2
+
+def dmsg(level,message):
+ if level <= debug_level:
+ print str(level) + ": " + message
def flag2mode(flags):
md = {os.O_RDONLY: 'r', os.O_WRONLY: 'w', os.O_RDWR: 'w+'}
@@ -39,16 +45,16 @@ def flag2mode(flags):
# should go
# we assume our chunks are in storage/
def inflate( src, dest ):
- print "inflate!"
+ dmsg( 1, "inflate!" )
out = open( dest, "w" )
- print "Unpickling: " + src
+ dmsg( 2, "Unpickling: " + src )
# TODO: return an IO error if inflating fails
inp = gzip.open( src, "r" )
magic = pickle.load( inp )
inp.close()
- print "Got data: " + str( magic )
+ dmsg( 2, "Got data: " + str( magic ) )
#pdb.set_trace()
@@ -57,27 +63,27 @@ def inflate( src, dest ):
( hash, seq ) = key
chars = list( hash )
- print chars
+ dmsg( 4, chars )
# Todo: make a digest -> path function to share with deflate
hexdigest = ''.join( [ "%02x" % ord( x ) for x in chars ] );
subparts = [ "%02x" % ord( x ) for x in chars[ :magic_depth ] ]
subpath = '/'.join( subparts );
- print "Subpath: " + subpath
+ dmsg( 3, "Subpath: " + subpath )
subpath += "/" + hexdigest + "_" + str( seq );
- print "Chunk path: " + subpath
+ dmsg( 3, "Chunk path: " + subpath )
if os.path.exists( "./storage/" + subpath ):
- print "Exporting chunk"
+ dmsg( 3, "Exporting chunk" )
readchunk = gzip.open( "./storage/" + subpath )
out.write( readchunk.read() )
readchunk.close()
else:
raise IOError
- print "File inflated"
+ dmsg( 2, "File inflated" )
out.close()
# TODO: deflate only if the file has been modified
@@ -85,7 +91,7 @@ def inflate( src, dest ):
# Deflate a file, src is the unpacked file, dest is where we want to pack
# to, and we assume storage/ is where chunks are stored
def deflate( src, dest ):
- print "deflate!"
+ dmsg( 2, "deflate!" )
inp = open( src, "r" )
hashs = [];
@@ -106,7 +112,7 @@ def deflate( src, dest ):
# Write out our chunk
chars = list( digest )
- print chars
+ dmsg( 4, chars )
# We make the hexdigest here, yeah we could just call hexdigest()
# but we need to essentially do this same thing to reassemble the
@@ -116,23 +122,23 @@ def deflate( src, dest ):
# Subparts just needs the first N chars
subparts = [ "%02x" % ord( x ) for x in chars[ :magic_depth ] ]
- print subparts
+ dmsg( 4, subparts )
subpath = '/'.join( subparts );
- print "Subpath: " + subpath
+ dmsg( 3, "Subpath: " + subpath )
# Make sure this sub path exists
nextpart = "./storage"
for part in subparts:
nextpart += "/" + part
if not os.path.exists( nextpart ):
- print "Creating subdir: " + nextpart
+ dmsg( 3, "Creating subdir: " + nextpart )
os.mkdir( nextpart )
# Find a chunk slot
sub = 0
while True:
checkpath = "./storage/" + subpath + "/" + hexdigest + "_" + str( sub )
- print "Checking: " + checkpath
+ dmsg( 3, "Checking: " + checkpath )
if os.path.exists( checkpath ):
# Check if this is our data
verify = gzip.open( checkpath, "r" )
@@ -140,20 +146,20 @@ def deflate( src, dest ):
verify.close()
if verify_contents == chunk:
- print "Found existing block"
+ dmsg( 2, "Found existing block" )
break
else:
- print "Block exists but is not the same"
+ dmsg( 2, "Block exists but is not the same" )
sub += 1
else:
# We found a spot, dump our data here
- print "No block here, creating new block"
+ dmsg( 2, "No block here, creating new block" )
savechunk = gzip.open( checkpath, "w" )
savechunk.write( chunk )
savechunk.close
break
- print "Got chunk slot: " + str( sub )
+ dmsg( 2, "Got chunk slot: " + str( sub ) )
hashs.append( [ digest, sub ] )
inp.close()
@@ -195,7 +201,7 @@ class FuseArchive(Fuse):
stats = os.lstat( treefile )
if os.path.isfile( treefile ):
- print "Reading file to get size: " + path
+ dmsg( 3, "Reading file to get size: " + path )
#pdb.set_trace()
@@ -204,7 +210,7 @@ class FuseArchive(Fuse):
magic = pickle.load( inp )
inp.close()
- print "Overridding getattr"
+ dmsg( 3, "Overridding getattr" )
stats = FuseArchiveStat( stats, magic[ 'stat' ] )
return stats
@@ -238,9 +244,11 @@ class FuseArchive(Fuse):
os.chown("./tree" + path, user, group)
def truncate(self, path, len):
- f = open("./tree" + path, "a")
- f.truncate(len)
- f.close()
+ # Truncate using the ftruncate on the file
+ dmsg( 2, "Using FuseArchiveFile to truncate " + path + " to " + str(len) )
+ f = self.FuseArchiveFile( path, os.O_APPEND, 0 )
+ f.ftruncate(len)
+ f.release( 0 )
def mknod(self, path, mode, dev):
os.mknod("./tree" + path, mode, dev)
@@ -310,56 +318,62 @@ class FuseArchive(Fuse):
def __init__(self, path, flags, *mode):
# Inflate the file
- print "Init file: " + path
+ dmsg( 2, "Init file: " + path )
self.orig_path = path;
( fdnum, self.tmp_name ) = tempfile.mkstemp();
#os.close( fdnum );
if os.path.exists( "./tree" + self.orig_path ):
inflate( "./tree" + path, self.tmp_name )
+ else:
+ if re.match( '(a|w)', flag2mode( flags ) ):
+ dmsg( 2, "File doesn't exist and we're going to write, creating temp empty file" )
+ deflate( "/dev/null", "./tree" + path )
- print "Shadow file: " + self.tmp_name + " for " + self.orig_path
- print "Going to open shadow file with flags: " + str(flags) + " mode " + str(mode)
+ dmsg( 2, "Shadow file: " + self.tmp_name + " for " + self.orig_path )
+ dmsg( 2, "Going to open shadow file with flags: " + str(flags) + " mode " + str(mode) )
# pdb.set_trace()
- print "Flag2mode is: " + str( flag2mode( flags ) )
+ dmsg( 2, "Flag2mode is: " + str( flag2mode( flags ) ) )
# Just use the fdnum they gave us instead of reopening it,
# since that might fail
# fdnum = os.open( self.tmp_name, flags, *mode )
#print "Got fdnum: " + str(fdnum)
self.file = os.fdopen( fdnum, flag2mode( flags ) )
- print "Open"
+ dmsg( 2, "Open" )
self.fd = self.file.fileno()
self.direct_io = False
self.keep_cache = False
- print str(self) + " init complete"
+ self.modified = False
+
+ dmsg( 2, str(self) + " init complete" )
def read(self, length, offset):
- print "Reading from " + self.orig_path
+ dmsg( 2, "Reading from " + self.orig_path )
self.file.seek(offset)
return self.file.read(length)
def write(self, buf, offset):
- print "Writing to " + self.orig_path
+ dmsg( 2, "Writing to " + self.orig_path )
self.file.seek(offset)
self.file.write(buf)
return len(buf)
def release(self, flags):
# Deflate the file
- print "Release: " + self.orig_path
+ dmsg( 2, "Release: " + self.orig_path )
self.file.close()
- print "Copying working file back to storage: " + \
- self.tmp_name + " -> " + self.orig_path
+ dmsg( 2, "Copying working file back to storage: " + \
+ self.tmp_name + " -> " + self.orig_path )
#pdb.set_trace()
deflate( self.tmp_name, "./tree" + self.orig_path );
- print "Deleting old file: " + self.tmp_name
+ dmsg( 2, "Deleting old file: " + self.tmp_name )
os.unlink( self.tmp_name );
def _fflush(self):