Writing own VFS module

James Peach jpeach at samba.org
Mon Jan 30 22:51:45 GMT 2006

On Sat, 2006-01-28 at 19:47 +0200, Timo Neuvonen wrote:
> Hello, Samba Gurus!
> **1**
> I'm writing a VFS module, that would do something after a file is renamed
> by end user.
> To be more spesific, to do something only after a file/directory (tree) is
> _moved_ to another location within the directory tree, I've found a logic to
> make this work. Anyway, the exact functionality is not an issue this time.
> I'm using the "skel_rename" function found in the skel_transparent.c file as
> a skeleton for my own approach.
> skel_rename returns a value, according to my (short) experience 0 or -1,
> depending whether the rename was succesful or not.
> I haven't found any documentation about the return values.
> -1 seems to result at least if the user hasn't necessary write permission,
> is there a more exact way to indicate what kind of failure it was? In other
> words, do different non-zero return values have any spesific meaning here?
> Or is -1 the most correct return value after any failure that needs to be
> differentiated from a no-fail situation?
> **2**
> How compatible the VFS modules are between different Samba versions?
> I think I've seen a note somewhere saying that the VFS interface may change
> from one Samba version to another?
> Should I be prepared to re-compile the module every time Samba gets even a
> minor update? I'm normally using pre-compiled binary packages (FC4 rpms), so
> I don't otherwise need to get the source files at all.

The versioning on the VFS interface only helps a little bit. In
practice, many VFS modules will call internal Samba APIs, and these can
change without warning. You should expect to have to recompile (and
possibly change some code) after each Samba update.

> How about the possible need to modify the source, is it reasonably safe to
> expect that the same source would compile with future 3.xx versions of
> Samba?


> So far I've been testing this idea only with 3.0.14a (current binary
> rpm version for FC4), but I noticed that the skeleton source for 3.0.21a
> already had at least cosmetic changes (for example, "old" and "new" renamed
> to "oldname" and "newname")
> **3**
> Then, finally, the more down-the-earth problems: skel_transparent.c in the
> "examples" directory has the following skeleton:
> static int skel_rename(vfs_handle_struct *handle, connection_struct \
>  *conn, const char *old, const char *new)
> {
>  return SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname);
> }
> This is my  approach so far:
> (strongly minimized & non-compilable version for clarity)
> static int skel_rename(vfs_handle_struct *handle, connection_struct \
>  *conn, const char *old, const char *new)
> {
>   int retvalue;
>   retvalue = SMB_VFS_NEXT_RENAME(handle, conn, old, new);
>   if(retvalue == 0)
>   {
>   // actual rename was succesful, questions 3.1 - 3.2 below
>   own stuff (fork() and exec() to own external routine) here
>     if(own stuff failed)  // optional error handling, Q 3.3 below
>       {
>       SMB_VFS_NEXT_RENAME(handle, conn, new, old);

If this rename fails, you have a difficult choice. The user's file has
been renamed and there's nothing you can do about it (since restoring
the name has already failed). If you return an error, then the user will
be horrifed to find their file gone. If you ignore the program check,
then presumably this violates the policy you are trying to enforce.

>       retvalue = -1;
>       }
>   }
> return retvalue;
> }
> *3.1*
> So, after the original rename action (copied from the skeleton), I would
> save the rename's return value, and fork & exec another program that
> would do something spesific to my own environment.
> Basically, is this a proper way of doing things? Developer's Manual
> http://www.samba.org/samba/docs/man/Samba-Developers-Guide/vfs.html
> lists several VFS operation layers, and says about transparent: "Normal
> operation, calls underlying layer after possibly changing passed data".
> Is "calls after" a big issue here? I'm calling it _before_ doing
> something else.

It all depends ... see above.

> There is also a "layer splitter" level: "Splits operation, calls underlying
> layer _and_ own facility, then combines result." I didn't find any example
> of it... Should I use this anyway, or is transparent layer ok? At least
> it seems to work in my case so far...  :-)

AFAIK, only transparent and opaque operations are ever used. Transparent
is probably what you are looking for. The internal Samba VFS layer only
treats opaque operations specially.

> This (with transparent layer) I have tested in my home server, on a
> for-test-use-only share, and it seems to work -at least at the first
> sight... but is this so far safe, from the viewpoint of a person who really
> knows Samba's internal life?
> How about the case, if there were simultaneusly another VFS module in use
> too? At least, recycle will propably be needed in the final environment.

Stacking multiple transparent operations in different modules is
perfectly ok.

> *3.2*
> Actually, my external "program" is (at least at this time) a shell script.
> System overall performance due to invocation of a shell etc. is not a
> problem here, since in practice the call would happen only very seldom,
> when a workstation user (there won't be too many simultaneus users
> in my environment) has manually moved a something to another location,
> so there's definetely no need to count milliseconds then. But is there
> something potentially dangerous against the system if I'm calling
> a shell script instead of a compiled program from VFS module?

Be careful with filename handling. Make sure that if the filename has
shell special characters nothing bad can happen,
	eg rename of "foo;rm /etc/passwd".

James Peach | jpeach at samba.org

More information about the samba-technical mailing list