Learning how to use FuseFS

January 29, 2008

Well, I started this blog about a year ago and haven’t written anything since. Ah, but now my writer’s block has been broken and here I am.

For a little while now, I’ve been interested in FUSE, but documentation has been scant and for the most part, inaccessible to me. There is even less documentation on Ruby’s bindings, FuseFS (a situation made worse by the existence of this song). The best example I’ve seen is Why the Lucky Stiff’s implementation of a filesystem for ActiveRecord objects.

Fortunately the package is reasonably well documented, and has some good sample code. Unfortunately, the business end of the library is in C, which complicates understanding what methods are doing what.

Here’s something that might help. We’re going to wrap all of methods of the supplied MetaDir (which mounts a Hash as a filesystem) in some logging calls. Now, I’m sure there’s a nicer way to do this, and you should blog about it.:P

   1  #!/usr/bin/env ruby
   2  require 'logger'
   3  require 'fusefs'
   5  METHODS_TO_IGNORE = [:__id__, :__send__, :send, :instance_variables, :puts]
   7  class TutorFS < FuseFS::MetaDir
   8    superclass.instance_methods.reject {|method_name|
   9      METHODS_TO_IGNORE.include? method_name.to_sym
  10    }.find_all {|method_name|
  11      method_name.to_s =~ /^[A-Za-z].*/
  12    }.each do |method_name|
  13      alias_method "old_#{method_name.to_s}".to_sym, method_name
  14      self.class_eval(%{
  15        def #{method_name}(*args, &block)
  16          @log.debug "Called #{method_name.to_s} with \#{args}"
  17          send(} + ":old_#{method_name}" +%{, *args, &block)
  18        end
  19      })
  21      puts "Wrapped :#{method_name}"
  22    end
  24    def initialize
  25      @log = Logger.new(STDOUT)
  26      @log.datetime_format = "%H:%M:%S"
  27      @log.level = Logger::DEBUG
  28      super
  29    end
  30  end
  32  if (File.basename($0) == File.basename(__FILE__))
  33    if (ARGV.size != 1)
  34      puts "Usage: #{$0} "
  35      exit
  36    end
  38    dirname = ARGV[0]
  40    unless File.directory?(dirname)
  41      puts "Usage: #{dirname} is not a directory."
  42      exit
  43    end
  45    root = TutorFS.new
  47    # Set the root FuseFS
  48    FuseFS.set_root(root)
  50    FuseFS.mount_under(dirname)
  52    FuseFS.run # This doesn't return until we're unmounted.
  53  end

When you mount this, it should give you access to the hash at the filesystem level. It should also start logging your messages and their arguments.


One Response to “Learning how to use FuseFS”

  1. Hello just wanted to give you a quick heads up. The text in your article seem to be running off the
    screen in Firefox. I’m not sure if this is a formatting issue or something to do with browser compatibility but I figured I’d post to let you know.
    The design look great though! Hope you get the issue solved soon.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: