How to Create an SMB Share (zfs)

This procedure describes how to use the ZFS file system's share property to create ZFS shares on the SMB server.

You can also use the share command to create shares on various file system types. See the share(8) man page.

To create an autohome share, you must have defined autohome rules. For more information, see How to Create a Specific Autohome Share Rule.

  1. Become an administrator.
  2. Create a ZFS pool and a mixed-case ZFS file system that supports cross-protocol locking.

    By default, ZFS file systems enable mixed-case mode.

    $ zpool create pool vdev
    $ zfs create -o nbmand=on pool/dataset

    A share name can include any alphanumeric characters, but not the characters listed here:

    " / \ [ ] : | + ; , ? * =
  3. Enable SMB sharing for the ZFS file system on the dataset or on individual specified shares.

    To enable SMB sharing on the dataset, set the share.smb property to on.

    $ zfs set share.smb=on pool/dataset

    To enable SMB sharing on individual named shares, first set share.smb=off on the dataset and then set share.smb=on on the individual shares.

    Note:

    The zfs command automatically constructs the default share name which is based on the name of the dataset mount point. Any characters that are illegal for share names are replaced by an underscore (_).
  4. (Optional) Create an SMB share that has non-default property values or an SMB share for a directory other than the mount point of the dataset.
    $ zfs share -o share.smb=on pool/dataset%share-name

    Use the zfs command to set share properties. See the zfs(8) man page.

    Share properties are stored as ZFS dataset properties, and the share ACL for each share is stored in the .zfs/shares directory of the dataset.

    Use the ls command to show the share-level ACLs on these entries. Use the chmod command to modify the share-level ACLs on the entries in this directory. See the ls(1) and chmod(1) man pages.

    For example, create the dataset and share:

    $ zfs create -o mountpoint=/users tank/users
    $ zfs share -o share.smb=on tank/users%ushare
  5. (Optional) Specify additional SMB share properties.

    For more information about SMB share properties, see SMB Share Properties, and the share_smb(8), share(8), and zfs(8) man pages.

  6. Verify how the file system is shared by using one of the following methods:
    • Use the zfs get command.

      $ zfs get share.smb.all tank/admins%ashare
      NAME                PROPERTY                VALUE  SOURCE
      tank/admins%ashare  share.smb.abe           off    default
      tank/admins%ashare  share.smb.ad-container         default
      tank/admins%ashare  share.smb.catia         off    default
      tank/admins%ashare  share.smb.cont_avail    off    default
      tank/admins%ashare  share.smb.csc           auto   local
      tank/admins%ashare  share.smb.dfsroot       off    default
      tank/admins%ashare  share.smb.guestok       on     local
      tank/admins%ashare  share.smb.none                 default
      tank/admins%ashare  share.smb.ro                   default
      tank/admins%ashare  share.smb.rw                   default
    • Use the share command.

      $ share
      IPC$     smb     -       Remote IPC
      ashare  /admins  smb     csc=auto,guestok=true
    • View the /etc/dfs/sharetab file.

      $ cat /etc/dfs/sharetab
      -       IPC$   smb - Remote IPC
      /admins ashare smb guestok,csc=auto

Example 3-3 Creating a Share With the Client-Side Caching Policy Set to auto

The following command creates a new share with the client-side caching policy set to auto:

$ zfs create -o mountpoint=/admins tank/admins
$ zfs share -o share.smb=on -o share.smb.csc=auto tank/admins%ashare

You can also add properties to existing shares. The following command sets the guest access policy of the share that was created by the preceding command to true:

$ zfs set share.smb.guestok=on tank/admins%ashare

Example 3-4 Inherited SMB Sharing for ZFS File Systems in a Pool

For information about ZFS share property inheritance, see Sharing and Unsharing ZFS File Systems in Managing ZFS File Systems in Oracle Solaris 11.4.

The following commands create a pool and enable SMB sharing for that pool. When you create the ZFS file systems in that pool, the file systems inherit SMB sharing.

$ zfs create rpool/admins/user1
$ zfs create rpool/admins/user2
$ zfs set share.smb=on rpool/admins
$ zfs get -r share.smb rpool/admins
NAME                 PROPERTY   VALUE  SOURCE
rpool/admins         share.smb  on     local
rpool/admins%        share.smb  on     inherited from rpool/admins
rpool/admins/user1   share.smb  on     inherited from rpool/admins
rpool/admins/user1%  share.smb  on     inherited from rpool/admins
rpool/admins/user2   share.smb  on     inherited from rpool/admins
rpool/admins/user2%  share.smb  on     inherited from rpool/admins
$ zfs set share.smb=off rpool/admins/user2
$ zfs get -r share.smb rpool/admins
NAME                 PROPERTY   VALUE  SOURCE
rpool/admins         share.smb  on     local
rpool/admins%        share.smb  on     inherited from rpool/admins
rpool/admins/user1   share.smb  on     inherited from rpool/admins
rpool/admins/user1%  share.smb  on     inherited from rpool/admins
rpool/admins/user2   share.smb  off    local

Example 3-5 SMB Sharing for a ZFS File System

The following commands create a ZFS pool and a mixed-case file system that supports cross-protocol locking and SMB sharing:

$ zpool create system1 c0t3d0
$ zfs create -o share.smb=on -o nbmand=on system1/fs1

In this example, the share name system1_fs1 is based on the dataset mount point system1/fs1.

The zfs get -r share.smb command lists all shares that are defined on a mounted file system.

$ zfs get -r share.smb system1/fs1
NAME          PROPERTY   VALUE  SOURCE
system1/fs1   share.smb  on     local
system1/fs1%  share.smb  on     inherited from system1/fs1

You can also view the list of active shares on the system from the /etc/dfs/sharetab file.

The zfs get command shows a subset of the share properties:

$ zfs get share.smb.all system1/fs1%
NAME          PROPERTY                VALUE  SOURCE
system1/fs1%  share.smb.abe           off    default
system1/fs1%  share.smb.ad-container         default
system1/fs1%  share.smb.catia         off    default
system1/fs1%  share.smb.cont_avail    off    default
system1/fs1%  share.smb.csc                  default
system1/fs1%  share.smb.dfsroot       off    default
system1/fs1%  share.smb.guestok       off    default
system1/fs1%  share.smb.none                 default
system1/fs1%  share.smb.ro                   default
system1/fs1%  share.smb.rw                   default

To view the local and inherited share properties, use the following command:

$ zfs get -rs local,inherited -e share.smb.all system1
NAME                 PROPERTY           VALUE      SOURCE
system1/fs1          share.smb.guestok  on         local
system1/fs1%         share.smb.guestok  on         inherited from system1/fs1
system1/fs2          share.smb.guestok  on         local
system1/fs2          share.smb.ro       otherhost  local
system1/fs2          share.smb.rw       myhost     local
system1/fs2%myshare  share.smb.guestok  on         inherited from system1/fs2
system1/fs2%myshare  share.smb.ro       otherhost  inherited from system1/fs2
system1/fs2%myshare  share.smb.rw       myhost     inherited from system1/fs2

To view all the share properties, use the following command:

$ zfs get share.all system1/fs1%
NAME          PROPERTY         VALUE         SOURCE
system1/fs1%  share.desc                     default
system1/fs1%  share.name       system1_fs1   -
system1/fs1%  share.nfs        off           default
system1/fs1%  share.nfs.*      ...           default
system1/fs1%  share.path                     default
system1/fs1%  share.point      /system1/fs1  -
system1/fs1%  share.protocols  smb           inherited from system1/fs1
system1/fs1%  share.smb        on            inherited from system1/fs1
system1/fs1%  share.smb.*      ...           default
system1/fs1%  share.state      shared        -

A property value of ... can be expanded further by using the .all keyword. For example, you can view the share.smb.* properties by using the following command:

$ zfs get share.smb.all system1/fs1%
NAME          PROPERTY                VALUE         SOURCE
system1/fs1%  share.smb.abe           off           default
system1/fs1%  share.smb.ad-container                default
system1/fs1%  share.smb.catia         off           default
system1/fs1%  share.smb.cont_avail    off           default
system1/fs1%  share.smb.csc                         default
system1/fs1%  share.smb.dfsroot       off           default
system1/fs1%  share.smb.guestok       off           default
system1/fs1%  share.smb.none                        default
system1/fs1%  share.smb.ro                          default
system1/fs1%  share.smb.rw                          default

You can also view both the global share properties and the SMB properties by using the following command:

$ zfs get share.all,share.smb.all system1/fs1%
NAME          PROPERTY                VALUE         SOURCE
system1/fs1%  share.desc                            default
system1/fs1%  share.name              system1_fs1   -
system1/fs1%  share.nfs               off           default
system1/fs1%  share.nfs.*             ...           default
system1/fs1%  share.path                            default
system1/fs1%  share.point             /system1/fs1  -
system1/fs1%  share.protocols         smb           inherited from system1/fs1
system1/fs1%  share.smb               on            inherited from system1/fs1
system1/fs1%  share.smb.*             ...           default
system1/fs1%  share.state             shared        -
system1/fs1%  share.smb.abe           off           default
system1/fs1%  share.smb.ad-container                default
system1/fs1%  share.smb.catia         off           default
system1/fs1%  share.smb.cont_avail    off           default
system1/fs1%  share.smb.csc                         default
system1/fs1%  share.smb.dfsroot       off           default
system1/fs1%  share.smb.guestok       off           default
system1/fs1%  share.smb.none                        default
system1/fs1%  share.smb.ro                          default
system1/fs1%  share.smb.rw                          default

The following commands create another file system in the system1 pool called fs2, associate the file system with the myshare share name, and enable SMB sharing:

$ zfs create -o nbmand=on system1/fs2
$ zfs share -o share.smb=on system1/fs2%myshare

You can use the zfs get command to view the share.smb and share property values for the system1 pool.

$ zfs get -r share.smb.all system1
NAME                 PROPERTY   VALUE  SOURCE
system1              share.smb  off    default
system1/fs1          share.smb  on     local
system1/fs1%         share.smb  on     inherited from system1/fs1
system1/fs2          share.smb  off    default
system1/fs2%myshare  share.smb  on     local

$ zfs get -r share.smb.all system1
NAME                 PROPERTY                VALUE  SOURCE
system1              share.smb.abe           off    default
system1              share.smb.ad-container         default
system1              share.smb.catia         off    default
system1              share.smb.cont_avail    off    default
system1              share.smb.csc                  default
system1              share.smb.guestok       off    default
system1              share.smb.none                 default
system1              share.smb.ro                   default
system1              share.smb.rw                   default
system1/fs1          share.smb.abe           off    default
system1/fs1          share.smb.ad-container         default
system1/fs1          share.smb.catia         off    default
system1/fs1          share.smb.cont_avail    off    default
system1/fs1          share.smb.csc                  default
system1/fs1          share.smb.guestok       off    default
system1/fs1          share.smb.none                 default
system1/fs1          share.smb.ro                   default
system1/fs1          share.smb.rw                   default
system1/fs1%         share.smb.abe           off    default
system1/fs1%         share.smb.ad-container         default
system1/fs1%         share.smb.catia         off    default
system1/fs1%         share.smb.cont_avail    off    default
system1/fs1%         share.smb.csc                  default
system1/fs1%         share.smb.dfsroot       off    default
system1/fs1%         share.smb.guestok       off    default
system1/fs1%         share.smb.none                 default
system1/fs1%         share.smb.ro                   default
system1/fs1%         share.smb.rw                   default
system1/fs2          share.smb.abe           off    default
system1/fs2          share.smb.ad-container         default
system1/fs2          share.smb.catia         off    default
system1/fs2          share.smb.cont_avail    off    default
system1/fs2          share.smb.csc                  default
system1/fs2          share.smb.guestok       off    default
system1/fs2          share.smb.none                 default
system1/fs2          share.smb.ro                   default
system1/fs2          share.smb.rw                   default
system1/fs2%myshare  share.smb.abe           off    default
system1/fs2%myshare  share.smb.ad-container         default
system1/fs2%myshare  share.smb.catia         off    default
system1/fs2%myshare  share.smb.cont_avail    off    default
system1/fs2%myshare  share.smb.csc                  default
system1/fs2%myshare  share.smb.dfsroot       off    default
system1/fs2%myshare  share.smb.guestok       off    default
system1/fs2%myshare  share.smb.none                 default
system1/fs2%myshare  share.smb.ro                   default
system1/fs2%myshare  share.smb.rw                   default

You can also see the list of all active shares on the system by viewing the /etc/dfs/sharetab file.

The following command creates a child file system of system1/fs2 called system1/fs2/fs2_sub1:

$ zfs create system1/fs2/fs2_sub1

The new file system inherits the share.smb property from its parent, system1/fs1, which causes a new default share to be created.

$ zfs create -o nbmand=on system1/fs1/fs1_sub1
$ zfs get -r share.smb system1
NAME                   PROPERTY   VALUE  SOURCE
system1                share.smb  off    default
system1/fs1            share.smb  on     local
system1/fs1%           share.smb  on     inherited from system1/fs1
system1/fs1/fs1_sub1   share.smb  on     inherited from system1/fs1
system1/fs1/fs1_sub1%  share.smb  on     inherited from system1/fs1
system1/fs2            share.smb  off    default
system1/fs2%myshare    share.smb  on     local
system1/fs2/fs2_sub1   share.smb  off    default

You can also see the list of all active shares on the system by viewing the /etc/dfs/sharetab file.

$ cat /etc/dfs/sharetab
/system1/fs2              myshare                   smb     -
/system1/fs1              system1_fs1               smb     -
/system1/fs1/fs1_sub1     system1_fs1_fs1_sub1      smb     -

If you disable SMB sharing for system1/fs1, that file system and its children are affected.

$ zfs set share.smb=off system1/fs1
$ zfs get -r share.smb system1
NAME                  PROPERTY   VALUE  SOURCE
system1               share.smb  off    default
system1/fs1           share.smb  off    local
system1/fs1/fs1_sub1  share.smb  off    inherited from system1/fs1
system1/fs2           share.smb  off    default
system1/fs2%myshare   share.smb  on     local
system1/fs2/fs2_sub1  share.smb  off    default

$ cat /etc/dfs/sharetab | grep system1
/system1/fs2      myshare smb     -

Note that disabling the share.smb property unpublishes the shares but does not remove the share definitions. The /etc/dfs/sharetab file shows that only the myshare share is still published, while the system1_fs1 and system1_fs2_fs2_sub1 shares still exist but are no longer published.

Example 3-6 Setting the csc Property for Shares

The following example shows how to configure client-side caching on shares.

First, create and share a file system.

If you specify share.smb=on during dataset creation, the share is automatically created as a default share. The name of the share is based on the share path, where slashes (/) are replaced by underscores (_).

The automatic (auto) share is represented as tank/zvol%, which is the ZFS property name for the auto share. The default share name is constructed from the file system name. Invalid characters are converted to underscores. The share.name property stores the default share name, which is the name by which the share is published. The following example uses a default share name of tank_zvol.

$ zfs create -o utf8only=on -o share.smb=on tank/zvol
$ share
IPC$                            smb     -       Remote IPC
c$              /var/smb/cvol   smb     -       Default Share
tank_zvol       /tank/zvol      smb     -
$ zfs get name,share.protocols,share.state,share.point tank/zvol%

NAME        PROPERTY         VALUE       SOURCE
tank/zvol%  name             tank/zvol%  -
tank/zvol%  share.protocols  smb         local
tank/zvol%  share.state      shared      -
tank/zvol%  share.point      /tank/zvol  -

To list automatic shares, use the zfs list -o share command:

$ zfs create -o utf8only=on -o share.smb=on tank/zvol
$ zfs get share tank/zvol%
$ zfs list -o share
NAME        SHARENAME  PROTOCOLS  STATE        SHAREPOINT
tank/zvol%  tank_zvol  smb        shared       /tank/zvol
$ zfs get share.name tank/zvol%
NAME        PROPERTY    VALUE      SOURCE
tank/zvol%  share.name  tank_zvol  -

To create a share with non-default values, use the zfs command, as shown in the following example:

  1. Create the dataset.

    $ zfs create -o utf8only=on tank/zvol
  2. Create and enable an SMB share with the name of ashare.

    $ zfs share -o share.smb=on tank/zvol%ashare
    $ zfs get name,share.protocols,share.state,share.point tank/zvol%ashare
    NAME                    PROPERTY        VALUE                   SOURCE
    tank/zvol%ashare        name            tank/zvol%ashare        -
    tank/zvol%ashare        share.protocols smb                     local
    tank/zvol%ashare        share.state     -                       -
    tank/zvol%ashare        share.point     /tank/zvol              -
  3. View the active shares on the system.

    $ cat /etc/dfs/sharetab
    /tank/zvol ashare smb -

The following command creates a new share, bshare, with the csc property set to auto:

$ zfs share -o share.smb=on -o share.smb.csc=auto tank/zvol%bshare
$ zfs get share.smb.all tank/zvol%bshare
NAME                    PROPERTY                VALUE                   SOURCE
tank/zvol%bshare        name                    tank/zvol%bshare        -
tank/zvol%bshare        share.smb.abe           off                     default
tank/zvol%bshare        share.smb.ad-container                          default
tank/zvol%bshare        share.smb.catia         off                     default
tank/zvol%bshare        share.smb.cont_avail    off                     default
tank/zvol%bshare        share.smb.csc           auto                    local
tank/zvol%bshare        share.smb.dfsroot       off                     default
tank/zvol%bshare        share.smb.guestok       off                     default
tank/zvol%bshare        share.smb.none                                  default
tank/zvol%bshare        share.smb.ro                                    default
tank/zvol%bshare        share.smb.rw                                    default

Using the zfs command enables you to add properties to a share without specifying all the other previously specified properties and their values.

In the following example, the first command creates a share with the name of cshare. The second command adds the csc property.

$ zfs share -o share.smb=on tank/zvol3%cshare
$ zfs set -o share.smb.csc=auto tank/zvol3%cshare

You can also set the csc property on autohome shares in the smbautohome map. As with the ZFS share property, multiple property-value pairs can be specified in a comma-separated list. The following smbautohome map disables client-side caching by default, but sets csc=auto for /export/home/engadmin:

*      /export/home/&   share.smb.csc=disabled,description=&
userone   /export/home/&   share.smb.csc=auto,dn=oracle,dn=com,ou=users

Example 3-7 Using ls and chmod to Manage SMB Share-Level ACLs

Although you can manage share ACLs on an Oracle Solaris system, a better practice is to use Windows utilities to manage share ACLs. The ACLs are stored on resources located in the .zfs/shares subdirectory in the root of the shared file system. For more information about using the chmod command to modify ACLs, see the chmod(1) man page.

In this example, the shared file system is /zpool/cosmos and one resource, pluto, is stored in the .zfs/shares directory for this file system.

After changing to the /zpool/cosmos/.zfs/shares directory, you can use the ls -lv command to view the ACL information about the resources in that directory.

$ cd /zpool/cosmos/.zfs/shares
$ ls -lv
total 2
----------+  1 root     root           0 Feb  8 18:35 pluto
     0:everyone@:read_data/write_data/append_data/read_xattr/write_xattr
         /execute/delete_child/read_attributes/write_attributes/delete
         /read_acl/write_acl/write_owner/synchronize:allow

The ls -lv output shows that the pluto resource is owned by the root user and the root group. The everyone ACL entry covers all other users who are not the root user or part of the root group. The everyone ACL entry shows that everyone has all access privileges, which is the default.

Next, use the chmod command to add a user, userone, who only has read access to the pluto resource. After running the chmod command, the ls -lv command shows you the new ACL entry for user userone. Note that the ACL entry for everyone is unchanged.

$ chmod A+user:userone:read_data/read_xattr/read_attributes/read_acl:allow pluto
$ ls -lv
total 2
-rwxrwxrwx+  1 root     root           0 Feb  8 18:35 pluto
     0:user:userone:read_data/read_xattr/read_attributes/read_acl:allow
     1:everyone@:read_data/write_data/append_data/read_xattr/write_xattr
         /execute/delete_child/read_attributes/write_attributes/delete
         /read_acl/write_acl/write_owner/synchronize:allow

Use the chmod command to modify the ACL entry for user userone to permit all access privileges. Now, the ls -lv command shows that the ACL entry for user userone has been updated to have all access privileges.

$ chmod A0=user:userone:read_data/write_data/append_data/read_xattr/ \
write_xattr/execute/delete_child/read_attributes/write_attributes/delete/ \
read_acl/write_acl/write_owner/synchronize:allow pluto
$ ls -lv
total 2
-rwxrwxrwx+  1 root     root           0 Feb  8 18:35 pluto
     0:user:userone:read_data/write_data/append_data/read_xattr/write_xattr
         /execute/delete_child/read_attributes/write_attributes/delete
         /read_acl/write_acl/write_owner/synchronize:allow
     1:everyone@:read_data/write_data/append_data/read_xattr/write_xattr
         /execute/delete_child/read_attributes/write_attributes/delete
         /read_acl/write_acl/write_owner/synchronize:allow