Pregunta

I want to learn how to write filesystems in Fuse. My idea is to write a filesystem that communicates with pinboard.in (a bookmark service). I have problem with readdir. As far as I understand (which is not very much since this is new stuff for me) readdir is the function that returns what files and folders are in the filesystem.

I have the following code:

def readdir ( self, path, flags ):
    print '*** readdir', path, flags
    if path == '/':
        # Path is root meaning we need to list tags and untagged bookmarks
        tags_json=urllib2.urlopen('https://api.pinboard.in/v1/tags/get?format=json&auth_token='+self.apitoken).read()
        tags = json.loads(tags_json)
        ret = map(lambda k: fuse.Direntry(name=k, type=stat.S_IFDIR), tags.keys())
        print ret
        return ret
    else:
        pass

When running this in Fuse with debug flags I get something like

    *** getattr /
    unique: 2, success, outsize: 120
    unique: 3, opcode: OPENDIR (27), nodeid: 1, insize: 48, pid: 6441
    unique: 3, success, outsize: 32
    unique: 4, opcode: READDIR (28), nodeid: 1, insize: 80, pid: 6441
    readdir[0] from 0
    *** readdir / 0
    [<fuse.Direntry object at 0xb65b8f70>, <fuse.Direntry object at 0xb65b8f90>,........,<fuse.Direntry > object at 0xb65e1670>]
    unique: 4, success, outsize: 16
    unique: 5, opcode: RELEASEDIR (29), nodeid: 1, insize: 64, pid: 0
    unique: 5, success, outsize: 16

but the file system is empty. I tried a little bit of everything but I think that I don't understand the flow of a filesystem. My real questions are, what do I return so ls shows files/directories? Where should I be reading about this?

In case you need more code you can go to my bitbucket and read everything: https://bitbucket.org/aquaplanet/pinboard.in-fuse/commits/38212eb035d3aba163bab9ed5a6b9284ce1dc93c

Thanks very much for your time reading my question, I am looking forward for any answers!

Solution

Thanks to @aleatha who told me that I wrote correct but there is a kind of type error in tags.keys(), that normal strings works, I quickly found that tags.keys() was unicode. Despite having sv_SE.UTF-8 in both LANG and LC_CTYPE (working on a raspberry pi) it wants 8 bit strings. This works much better:

def readdir ( self, path, flags ):
    print '*** readdir', path, flags
    if path == '/':
        # Path is root meaning we need to list tags and untagged bookmarks
        tags_json=urllib2.urlopen('https://api.pinboard.in/v1/tags/get?format=json&auth_token='+self.apitoken).read()
        tags = json.loads(tags_json)
        ret = map(lambda k: fuse.Direntry(name=k.encode('iso-8859-1','replace'), type=stat.S_IFDIR), tags.keys())
        return ret
    else:
        pass
¿Fue útil?

Solución

You look like you're on the right path... You need to return a series of Direntry objects.

If I replace your API call with a simple array of strings, like so:

tags = ["a", "b", "c"]  
ret = map(lambda k: fuse.Direntry(name = k, type = stat.S_IFDIR), tags)
return ret

Then it works fine. So my surmise is that there's something wrong with tags.keys(). I'd start by inspecting the individual Direntry objects and seeing if they look right.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top