API Questions, Part 2

View: New views
9 Messages — Rating Filter:   Alert me  

API Questions, Part 2

by Nikolaus Rath :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

Once again I have a bunch of questions I couldn't find answers for in
the docs. This time they're mostly about the python API though. I will
add the answers to the Wiki again, so that everyone can benefit from
them.

 - Is it correct that in the Python API the file_class constructor is
   called whenever *either* open(2) *or* create(2) is called, and that
   one can distinguish between these cases using the mode argument
   which is only present for create()?

   I.e. could one replace the constructor specification
   __init__(self, path, flags, *mode) from the python example fs with
   __init__(self, path, flags, mode=None) or are there any additional
   arguments that are supposed to be collected as a tuple in mode?

 - My filesystem metadata rests in an SQlite database whose handle is
   stored as an instance variable of the Fuse object. Is there any way
   I can pass this handle to the file_class instance? I can't quite
   believe that one can implement any non-trivial file operations
   without having access to any data of the underlying filesystem...
   
 - What is the proper way to access UID and GID of the calling process
   in access() and file_class.__init__()? In the source I found a
   fuse.GetContext() object, but it is undocumented and seems to be
   available only for the fuse instance and not in the file_class
   (unless there is a way to access the fuse instance from the
   file_class, see above)

 - Is there a way to set some fuse options from within the python
   program? I would like to enforce that e.g. the fs always runs with
   -s and -o default_permissions,use_ino,direct_io.
   
 - I tried to use fuse.Stat() as a base class for my getattr() result,
   but I got a lot of exceptions because of undefined st_blocks and
   st_blksize hash keys. Am I the only one with this problem? It seems
   to me that either all attributes should be initialized to sensible
   defaults (meaning 0) or none.

 - I noticed that calls to mkdir() come with a mode argument for which
   S_ISDIR(mode) is false. I therefore manually correct the mode to
   mode = mode | S_IFDIR. Is this a bug?

 - When the call to fuse_main() returns, is it safe to assume that
   there are no other threads running (handling requests) anymore?

 - Do read() and write() have to check if the file was opened with
   O_WRONLY and O_RDONLY respectively and return errors if this was
   the case?

 - If fuse is running multithreaded, what are the threads doing when
   they're not handling requests? Is a thread started when a request
   comes in and terminated when the request has been handled, or are
   the threads managed in some sort of pool, i.e. the same thread is
   used for several requests?
   
 - If a thread might be used for several requests, is there a way to
   execute code upon creation and termination of the thread? (both in
   the Python and C API)

And one more question concerning the fusexmp.c example:

 - xmp_read() and xmp_write() both call pread() and pwrite()
   respectively and return the number of bytes written or read.
   However, fuse.h says that both read() and write() should return
   exactly the number of bytes requested unless the direct_io mount
   option was used. On my system, pread() and pwrite() apparently act
   just like read() and write() and may read/write fewer bytes than
   requested. Does that mean that the example is meant to be run with
   direct_io? If so, it'd be nice to document this somewhere...
   


Thanks again for your help, and also for programming fuse in the first
place!


Best,


   -Nikolaus

--
 »It is not worth an intelligent man's time to be in the majority.
  By definition, there are already enough people to do that.«
                                                         -J.H. Hardy

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C


-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: API Questions, Part 2

by Miklos Szeredi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, 08 Jul 2008, Nikolaus Rath wrote:
> Hello,
>
> Once again I have a bunch of questions I couldn't find answers for in
> the docs. This time they're mostly about the python API though.

I cannot answer the pythons ones.

>  - I noticed that calls to mkdir() come with a mode argument for which
>    S_ISDIR(mode) is false. I therefore manually correct the mode to
>    mode = mode | S_IFDIR. Is this a bug?

No, I don't think so: passing S_IFDIR to mkdir would be redundant.

>  - When the call to fuse_main() returns, is it safe to assume that
>    there are no other threads running (handling requests) anymore?

Yes.

>  - Do read() and write() have to check if the file was opened with
>    O_WRONLY and O_RDONLY respectively and return errors if this was
>    the case?

No, the VFS checks that.

>  - If fuse is running multithreaded, what are the threads doing when
>    they're not handling requests? Is a thread started when a request
>    comes in and terminated when the request has been handled, or are
>    the threads managed in some sort of pool, i.e. the same thread is
>    used for several requests?

There's a pool, but it can grow and shrink on demand.  It's not a very
finely tuned algorithm though.

>  - If a thread might be used for several requests, is there a way to
>    execute code upon creation and termination of the thread? (both in
>    the Python and C API)

In the C API you can use thread specific variables, and you can check
if they have been assigned, and can specify a destructor which will be
called when the thread exits.

> And one more question concerning the fusexmp.c example:
>
>  - xmp_read() and xmp_write() both call pread() and pwrite()
>    respectively and return the number of bytes written or read.
>    However, fuse.h says that both read() and write() should return
>    exactly the number of bytes requested unless the direct_io mount
>    option was used. On my system, pread() and pwrite() apparently act
>    just like read() and write() and may read/write fewer bytes than
>    requested. Does that mean that the example is meant to be run with
>    direct_io? If so, it'd be nice to document this somewhere...

It means the example is sloppy, and doesn't check for short reads.
It's sloppy, because normally the underlying filesystem does not
return short reads/writes, so there is no practical need for checking.

Miklos

-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: API Questions, Part 2

by Nikolaus Rath :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Miklos Szeredi <miklos@...> writes:
> On Tue, 08 Jul 2008, Nikolaus Rath wrote:
>> Hello,
>>
>> Once again I have a bunch of questions I couldn't find answers for in
>> the docs. This time they're mostly about the python API though.
>
> I cannot answer the pythons ones.

Oh, I though you wrote them as well since they're in the same CVS
tree. Do you have any suggestions whom to contact with questions about
them?

>>  - I noticed that calls to mkdir() come with a mode argument for which
>>    S_ISDIR(mode) is false. I therefore manually correct the mode to
>>    mode = mode | S_IFDIR. Is this a bug?
>
> No, I don't think so: passing S_IFDIR to mkdir would be redundant.

Well, I assumed it to be set. Maybe you can apply this patch too?

--- fuse.h 9 Jul 2008 17:05:01 -0000 1.130
+++ fuse.h 12 Jul 2008 17:24:49 -0000
@@ -106,7 +106,12 @@
  */
  int (*mknod) (const char *, mode_t, dev_t);
 
- /** Create a directory */
+ /** Create a directory
+ *
+ * Note that the mode argument may not have the type specification
+ * bits set, i.e. S_ISDIR(mode) can be false.  To obtain the
+ * correct directory type bits use  mode|S_IFDIR
+ * */
  int (*mkdir) (const char *, mode_t);
 
  /** Remove a file */


>>  - If a thread might be used for several requests, is there a way to
>>    execute code upon creation and termination of the thread? (both in
>>    the Python and C API)
>
> In the C API you can use thread specific variables, and you can
> check if they have been assigned,

To me it seems a bit awkward to check this at the beginning of every
operation. Would you accept a patch that adds a specific
initialization function?

> and can specify a destructor which will be called when the thread
> exits.

So how do I do that? I assume it's not the destroy() function, or is
it ("Called on filesystem exit")?


Best,


   -Nikolaus

--
 »It is not worth an intelligent man's time to be in the majority.
  By definition, there are already enough people to do that.«
                                                         -J.H. Hardy

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C


-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: API Questions, Part 2

by Miklos Szeredi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, 12 Jul 2008, Nikolaus Rath wrote:

> Miklos Szeredi <miklos@...> writes:
> > On Tue, 08 Jul 2008, Nikolaus Rath wrote:
> >> Hello,
> >>
> >> Once again I have a bunch of questions I couldn't find answers for in
> >> the docs. This time they're mostly about the python API though.
> >
> > I cannot answer the pythons ones.
>
> Oh, I though you wrote them as well since they're in the same CVS
> tree. Do you have any suggestions whom to contact with questions about
> them?

Csaba Henk is currently the maintainer of the python code.  He
probably doesn't read fuse-devel very regularly, so it's best to CC
him with python related questions.

> > No, I don't think so: passing S_IFDIR to mkdir would be redundant.
>
> Well, I assumed it to be set. Maybe you can apply this patch too?

Yup.  Thanks.

> > In the C API you can use thread specific variables, and you can
> > check if they have been assigned,
>
> To me it seems a bit awkward to check this at the beginning of every
> operation. Would you accept a patch that adds a specific
> initialization function?

What do you want to use the thread specific variable for?  Check this
in the function that _gets_ the value of the thread specific variable.

> > and can specify a destructor which will be called when the thread
> > exits.
>
> So how do I do that? I assume it's not the destroy() function, or is
> it ("Called on filesystem exit")?

No no no.  It's the destructor for the variable upon _thread_ exit.
Thread exit can happen anytime (as discussed earlier) not just when
the filesystem exits.

See the pthread_key_create(3) man page.

Miklos

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: API Questions, Part 2

by Nikolaus Rath :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Miklos Szeredi <miklos@...> writes:
>> > In the C API you can use thread specific variables, and you can
>> > check if they have been assigned,
>>
>> To me it seems a bit awkward to check this at the beginning of every
>> operation. Would you accept a patch that adds a specific
>> initialization function?
>
> What do you want to use the thread specific variable for?  Check this
> in the function that _gets_ the value of the thread specific variable.

Ah, true, I wasn't in C thinking mode.

(In python you can declare a global variable as thread local and then
access it normally. So in that case there is no function that gets the
value).


>>> and can specify a destructor which will be called when the thread
>>> exits.
>>
>> So how do I do that? I assume it's not the destroy() function, or is
>> it ("Called on filesystem exit")?
>
> No no no.  It's the destructor for the variable upon _thread_ exit.
> Thread exit can happen anytime (as discussed earlier) not just when
> the filesystem exits.
>
> See the pthread_key_create(3) man page.

Yeah, same mistake. Thanks ;-)


   -Nikolaus

--
 »It is not worth an intelligent man's time to be in the majority.
  By definition, there are already enough people to do that.«
                                                         -J.H. Hardy

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: API Questions, Part 2

by Csaba Henk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 2008-07-08, Nikolaus Rath <Nikolaus@...> wrote:

> Hello,
>
> Once again I have a bunch of questions I couldn't find answers for in
> the docs. This time they're mostly about the python API though. I will
> add the answers to the Wiki again, so that everyone can benefit from
> them.
>
>  - Is it correct that in the Python API the file_class constructor is
>    called whenever *either* open(2) *or* create(2) is called, and that
>    one can distinguish between these cases using the mode argument
>    which is only present for create()?
>
>    I.e. could one replace the constructor specification
>    __init__(self, path, flags, *mode) from the python example fs with
>    __init__(self, path, flags, mode=None) or are there any additional
>    arguments that are supposed to be collected as a tuple in mode?

Yes, exactly. This one can even be found in the FAQ:

  http://mercurial.creo.hu/repos/fuse-python-hg/index.cgi/file/tip/FAQ#l30

>
>  - My filesystem metadata rests in an SQlite database whose handle is
>    stored as an instance variable of the Fuse object. Is there any way
>    I can pass this handle to the file_class instance? I can't quite
>    believe that one can implement any non-trivial file operations
>    without having access to any data of the underlying filesystem...
>    
>  - What is the proper way to access UID and GID of the calling process
>    in access() and file_class.__init__()? In the source I found a
>    fuse.GetContext() object, but it is undocumented and seems to be
>    available only for the fuse instance and not in the file_class
>    (unless there is a way to access the fuse instance from the
>    file_class, see above)

These questions are solved by being able to access the Fuse instance
from a file class instance, which is being discussed in the other
thread.

>  - Is there a way to set some fuse options from within the python
>    program? I would like to enforce that e.g. the fs always runs with
>    -s and -o default_permissions,use_ino,direct_io.

Yes.

As you can read in the documentation:

 |Class Fuse
 |
 |Python interface to FUSE.
 |
 |Basic usage:
 |
 |    * instantiate
 |    * add options to parser attribute (an instance of FuseOptParse)
 |    * call parse
 |    * call main

cf.

  http://fuse4bsd.creo.hu/fuse-python-0.2-doc/fuse.Fuse-class.html

So, what does "parse" do and what is FuseOptParse?

There is the class hierarchy

  FuseOptParse < SubbedOptParse < OptionParser

where:

- OptionParser is the standard Python class, see

  http://www.python.org/doc/current/lib/module-optparse.html

- SubbedOptparse is a subclass of it which implements transparent
handling of suboptions (like "-o foo,bar=baz": here "foo" and "bar"
are suboptions of "-o"). Cf.

  http://fuse4bsd.creo.hu/fuse-python-0.2-doc/fuseparts.subbedopts.SubbedOptParse-class.html 

- FuseOptParse is a subclass of SubbedOptParse with some Fuse specific
customizations, eg. supporting the "mountopt" specifier, cf.

  http://fuse4bsd.creo.hu/fuse-python-0.2-doc/fuse.FuseOptParse-class.html

So after you are done with, eg.

  fs = Fuse(...)

then you'll have the fs.parser FuseOptParse instance at hand, and you
can populate it with options just like any OptionParser instance, plus
you can use the FuseOptParse specific extensions.

Then you call

  fs.parse(...)

to parse the command line. This sets up fs.fuse_args (an instance of
FuseArgs) which is a handy container for the parsed fuse command line,
which you can invesigate or modify. This is where you can do what you
want:

  fs.fuse_args.add('default_permissions')
  ...

Finally, when calling

  fs.main(...)

the command line which is passed down to the FUSE library is produced
via fs.fuse_args.assemble() (you can override it by using the "args"
keyword argument of fs.main [but you'd better shape fs.fuse_args as
you need]).

!!! NOTE: !!!

Setting single/multi threaded operation is not bound to
the fuse command line: it's simply determined by

  fs.multithreaded

Please read the FuseOptParse documentation about special
handling of the "-s" option (and also for "-d", "-f").

These things are also demonstrated in xmp.py (to some rate), see the
main() function:

  http://mercurial.creo.hu/repos/fuse-python-hg/index.cgi/file/23eee8905dd0/example/xmp.py#l253

>  - I tried to use fuse.Stat() as a base class for my getattr() result,
>    but I got a lot of exceptions because of undefined st_blocks and
>    st_blksize hash keys. Am I the only one with this problem? It seems
>    to me that either all attributes should be initialized to sensible
>    defaults (meaning 0) or none.

That's a bug which is fixed in the development version. A bugfix release
in the close future will include the fix. (Please make a try with the
code from the CVS/Hg repo and check if it really works out now.)

Regards,
Csaba


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: API Questions, Part 2

by Nikolaus Rath :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Csaba Henk <csaba-ml@...> writes:

> On 2008-07-08, Nikolaus Rath <Nikolaus@...> wrote:
>> Hello,
>>
>> Once again I have a bunch of questions I couldn't find answers for in
>> the docs. This time they're mostly about the python API though. I will
>> add the answers to the Wiki again, so that everyone can benefit from
>> them.
>>
>>  - Is it correct that in the Python API the file_class constructor is
>>    called whenever *either* open(2) *or* create(2) is called, and that
>>    one can distinguish between these cases using the mode argument
>>    which is only present for create()?
>>
>>    I.e. could one replace the constructor specification
>>    __init__(self, path, flags, *mode) from the python example fs with
>>    __init__(self, path, flags, mode=None) or are there any additional
>>    arguments that are supposed to be collected as a tuple in mode?
>
> Yes, exactly. This one can even be found in the FAQ:
>
>   http://mercurial.creo.hu/repos/fuse-python-hg/index.cgi/file/tip/FAQ#l30

So how do I return an errno? I cannot return a value from a
constructor.

>>  - Is there a way to set some fuse options from within the python
>>    program? I would like to enforce that e.g. the fs always runs with
>>    -s and -o default_permissions,use_ino,direct_io.
>
> Yes.
>
[...]

Thanks a lot for the detailed explanations. That makes things a lot
clearer.

Best,

   -Nikolaus

--
 »It is not worth an intelligent man's time to be in the majority.
  By definition, there are already enough people to do that.«
                                                         -J.H. Hardy

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: API Questions, Part 2

by Csaba Henk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 2008-07-21, Nikolaus Rath <Nikolaus@...> wrote:

> Csaba Henk <csaba-ml@...> writes:
>> On 2008-07-08, Nikolaus Rath <Nikolaus@...> wrote:
>>> Hello,
>>>
>>> Once again I have a bunch of questions I couldn't find answers for in
>>> the docs. This time they're mostly about the python API though. I will
>>> add the answers to the Wiki again, so that everyone can benefit from
>>> them.
>>>
>>>  - Is it correct that in the Python API the file_class constructor is
>>>    called whenever *either* open(2) *or* create(2) is called, and that
>>>    one can distinguish between these cases using the mode argument
>>>    which is only present for create()?
>>>
>>>    I.e. could one replace the constructor specification
>>>    __init__(self, path, flags, *mode) from the python example fs with
>>>    __init__(self, path, flags, mode=None) or are there any additional
>>>    arguments that are supposed to be collected as a tuple in mode?
>>
>> Yes, exactly. This one can even be found in the FAQ:
>>
>>   http://mercurial.creo.hu/repos/fuse-python-hg/index.cgi/file/tip/FAQ#l30
>
> So how do I return an errno? I cannot return a value from a
> constructor.

Just raise the suitable exception and the fuse module will try to
convert it to a sensible errno value (OSError and IOError are
supported in fact; otherwise you get EINVAL).

See

  http://fuse4bsd.creo.hu/README.new_fusepy_api.html#id6

about the various ways of returning from fs callbacks.

See the fuse.ErrnoWrapper class and the PROLOGUE / EPILOGUE
C macros if you are interested in the gory details.

Csaba


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: API Questions, Part 2

by Nikolaus Rath :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Csaba Henk <csaba-ml@...> writes:
>> So how do I return an errno? I cannot return a value from a
>> constructor.
>
> Just raise the suitable exception and the fuse module will try to
> convert it to a sensible errno value (OSError and IOError are
> supported in fact; otherwise you get EINVAL).

Ah, I thought that the "proper" way to signal and error would be to
return a value, while the catching of exceptions just happens because
it has to happen.

It'd be great if the README could mention that the "sensible"
exceptions to throw are OSError and IOError.

Best,

   -Nikolaus

--
 »It is not worth an intelligent man's time to be in the majority.
  By definition, there are already enough people to do that.«
                                                         -J.H. Hardy

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel
LightInTheBox - Buy quality products at wholesale price