by Ed Plese ed@edplese.com
Updated 2007-09-21: Added shadow_copy_zfs module compiled for use with Samba shipped with Solaris 10 Update 4 (x86). Unlike the latest patches the module name is shadow_copy_zfs to keep it independent from the preinstalled shadow_copy module. Added note about using the module with large numbers of snapshots. Added to section about ZFS ACLs.
Updated 2007-08-24: Added shadow copy patches for 3.0.25. Added section on ACLs. I am now using ZFS in production serving almost 2 TB across over 3,000 ZFS filesystems from a Sun X4500. Performance is excellent and is a very noticable improvement over our previous (older) Linux system. I need to confirm it but a single connection from a single CIFS client seems able to copy to the server at 70-80 MB/s over a gigabit connection, a speed which I didn't think was possible with the CIFS protocol. Due to various non-related issues I'm not yet using the shadow copy module in this environment.
Samba is an excellent piece of software for serving files over the SMB/CIFS protocol. When combined with some of the awesome features of Solaris and ZFS, many fun things are possible.
Just a word of warning, be sure to understand the implications of using these techniques before rolling them out into a production environment. Also, don't just copy and paste the examples verbatim because you'll likely need to modify them to at least change the filesystem locations and share names.
Samba's root preexec share parameter can really come in handy when setting up user home directories. Here we tell it to automatically create a ZFS filesystem for every new user, set the owner, and set the quota to 1 GB. This can easily be expanded to other filesystem properties as well.
Create a file /usr/bin/createhome.sh:
#!/usr/bin/tcsh if ( ! -e /tank/home/$1 ) then zfs create tank/home/$1 chown $1 tank/home/$1 zfs set quota=1G tank/home/$1 endif
Modify smb.conf and modify [homes] to resemble:
[homes] comment = User Home Directories browseable = no writable = yes root preexec = /usr/bin/createhome.sh '%U'
Using root preexec again, a share can be created that will create a snapshot of the filesystem every time the share is connected to. The snapshot name in this example is compatible with the shadow copy example below.
Create a snapshot script /usr/bin/snapshot_date.sh to use the date as the snapshot name:
#!/bin/sh zfs snapshot $1@GMT-`date -u +%Y.%m.%d-%H.%M.%S`
Setup the share in smb.conf:
[testshare] comment = Test Share writable = yes root preexec = /usr/bin/snapshot_date.sh tank/testshare
To create the snapshot on disconnect just use the root postexec parameter instead of root preexec.
Another example using the root preexec share parameter in smb.conf is to create a unique clone of a snapshot for every connection and then destroy the clone when the client disconnects. One possible use for this would be in a build/testing environment.
Here's an example share from smb.conf that accomplishes this. The process ID (%d) of the smbd process is used as the unique identifier for the clone name.
[build] comment = Build Share writable = yes path = /tank/clones/%d root preexec = zfs clone tank/clones/base@snap tank/clones/%d root postexec = zfs destroy tank/clones/%d
For those unfamiliar with shadow copy, here's a good overview of what it gets you.
I'd always found the shadow copy VFS module in Samba to be quite interesting but I never had a good source for the snapshots until ZFS. The stock shadow copy VFS module that ships with Samba works with ZFS but has some issues that make it difficult to use:
The following series of patches add flexible enhancements to the shadow_copy module to work nicely with ZFS as well as many other snapshot techniques. I'd like give a big thanks to Alison Winters for contributing many of the ideas for this patch as well as code and testing.
The defaults for all of the new smb.conf parameters are set to values that preserve backwards compatibility with the current module.
This fixes the module to work on systems that define struct dirent with d_name[1]. Solaris is an example of such a system and it causes the share to appear to be completely empty.
With the existing shadow_copy module the shadow copies are displayed in the Windows GUI in the order the server obtains them from readdir(3). On some systems and filesystems readdir(3) does not return files in any particular order which leads to the list in the GUI being unsorted and difficult to use. This patch allows the list to be sorted based on a "sort" parameter specified for the module. Allowed values are "asc" or "desc". When not specified the current unsorted behavior is maintained.
This patch allows for various components of the snapshot paths to be easily customized. Currently this must be done by creating scripts that will create the appropriate symbolic links every time a snapshot is taken and consequently clean up all of the symbolic links whenever a snapshot is deleted. With this patch the path components are specified in the smb.conf file using the new parameters "path", "subpath", "format", and "localtime". The defaults for all of the new parameters maintain the current behavior of the module.
Specifies the path to the directory that contains the snapshots.
This is the format of the snapshot names in str[fp]time notation except that $ characters are used in place of % characters.
The subdirectory under the snapshot that contains all of the files for this shadow copy.
Treat the snapshot names as being in localtime instead of the default of GMT.
These probably aren't the clearest explanations of the parameters but the examples below should help to clear up any confusion.
For those using Solaris 10 Update 4 (x86) here's a compiled module: shadow_copy_zfs-sol10u4-x86.so.gz. Copy the uncompressed module to /usr/sfw/lib/vfs/shadow_copy_zfs.so and substitute shadow_copy_zfs in place of shadow_copy in the examples below.
Some limitations include:
Example uses:
Use with @GMT- directories oows 2000 and XP. You can download it from Microsoft here.
This patch to Samba 3.0.23d adds a shadow_copy_zfs VFS module that makes Samba play nicer with ZFS snapshots. Though untested this should compile correctly on 3.0.24 as well.
After installing a patched Samba, a single modification to smb.conf takes care of the configuration. Here's an example:
[testshare] comment = Shadow Copy Share writable = yes path = /tank/fs vfs objects = shadow_copy_zfs shadow_copy_zfs: sort = desc
Once this is setup, just create snapshots for the filesystem named like GMT-2003.08.05-12.00.00 that indicates the snapshot time:
# zfs snapshot tank/fs@GMT-`date -u +%Y.%m.%d-%H.%M.%S`
Solaris 10 Update 4 ships with Samba 3.0.25a, complete with support for ZFS ACLs, Active Directory, and SMF integration.
Support for ZFS ACLs was slated to be included in version 3.0.26 the source releases of Samba but the release ended up being a security fix release. The next major Samba release will be 3.2.0 which will include integration of ZFS ACLs.
Despite the lack of ZFS ACL support in the source release of Samba, ZFS ACLs still work nicely with Samba. By design Samba performs fileo operations in the context of the user so that any existing access controls on the files apply regardless of Samba support for them.
Samba can be compiled with the --with-acl-support option to disable all ACL support in Samba and it will respect the ACLs applied to files. A share-level option in smb.conf that might want to be used is:
acl check permissions = False
Without specifying this option Windows will not allow any files with ACLs to be deleted. Setting this to False will still yield odd behavior when a user tries to delete files that without the permission to do so.