Jails with embedded, but not jailed, ZFS datasets – how to mount/umount

This approach did not work, because I used the wrong set of filesystems. See below for Error.

This post has been replaced by Jails with embedded, but not jailed, ZFS datasets – how to mount/umount – corrected.

NOTE: on yesterday’s (2023-10-04) reboot, the file systems did not properly mount. zfs get mounted said they were mounted, but the directories were empty. Stopping, then starting the jail resulted in a proper mount. I wonder if this is some race condition during boot.

EDIT: 2023-10-22 This problem is persistent. The host was rebooted yesterday. Restarting the jail solves the problem. I’m going to add a monitoring check. Eventually, we need to solve this problem.

First, this is not about jailed ZFS datasets. I use them for FreshPorts, but that’s not I’m going to talk about here.

In this post:

  • FreeBSD 13.2

This is my example:

[23:22 r730-03 dvl ~] % zfs list | grep bacula-sd-04
data01/bacula-volumes                     7.40T  5.82T       96K  /jails/bacula-sd-04/usr/local/bacula/volumes
data01/bacula-volumes/DiffFile            71.6G   952G     71.6G  /jails/bacula-sd-04/usr/local/bacula/volumes/DiffFile
data01/bacula-volumes/FullFile            3.48T  2.52T     3.42T  /jails/bacula-sd-04/usr/local/bacula/volumes/FullFile
data01/bacula-volumes/FullFileNoNextPool  3.30T  5.82T     3.30T  /jails/bacula-sd-04/usr/local/bacula/volumes/FullFileNoNextPool
data01/bacula-volumes/IncrFile             568G  1.95T     99.4G  /jails/bacula-sd-04/usr/local/bacula/volumes/IncrFile
data01/jails/bacula-sd-04                 1.96G  5.82T     1.70G  /jails/bacula-sd-04
[23:22 r730-03 dvl ~] % 

The jail bacula-sd-04 has a lot of data, backups, which persists outside the jail. I didn’t want all this data inside the data01/jails/bacula-sd-04 dataset, because that’s for jails. In other hosts that data is in a entirely different zpool. In fact, I may move all the jails into a different zpool. Keeping the data separate is what I want to do.

The problem, if I want to umount/move/play, the fact that other datasets are mounted into it causes a problem. I can’t because:


[23:25 r730-03 dvl ~] % sudo service jail stop bacula-sd-04
Stopping jails: bacula-sd-04.
[23:27 r730-03 dvl ~] % sudo zfs umount data01/jails/bacula-sd-04
cannot unmount ‘/jails/bacula-sd-04’: pool or dataset is busy
[23:27 r730-03 dvl ~] %

I may have a solution.

The background

My dev-ingress01 jail configuration contains this:

    exec.created+="zfs set jailed=on data02/freshports/jailed/dev-ingress01";
    exec.created+="zfs jail $name    data02/freshports/jailed/dev-ingress01";

I do something like that for FreshPorts.

Where are these fancy directives defined? man 8 jail – enjoy the reading.

Why not use the same method to mount/umount?

I was talking to Jan Bramkamp about this, and the following is the example approach he provided.

$fstab                  = "<<- 'EOF'
                devfs               $path/dev       devfs   rw,ruleset=$devfs_ruleset        0 0
                fdescfs             $path/dev/fd    fdescfs rw                               0 0
                tmpfs               $path/tmp       tmpfs   rw,mode=1777,size=128m           0 0
                tmpfs               $path/var/cache tmpfs   rw,mode=0755,size=128m           0 0
                tmpfs               $path/var/db    mfs     rw,size=256m,-k$base_path/var/db 0 0
                tmpfs               $path/var/run   tmpfs   rw,mode=0755,size=128m           0 0
                tmpfs               $path/var/tmp   tmpfs   rw,mode=1777,size=128m           0 0
        EOF";

exec.prepare            += "[   -d $snapshot_path ] || mount -F /dev/stdin -a -v $fstab";

How do I convert that to zfs? I’m not going to interpret the above for you, but I will show you what worked for me. My best clue was Alternate /etc/fstab in the Root On ZFS. Here is what I tried first.

The beauty of this: the same data ($fstab) is used for both mount and umount.

# path is defined globally and is the same for all jails.
# name will be bacula-sd-04, in this case.
path = /jails/$name;

bacula-sd-04 {
    persist;
    ip4.addr = "$NIC|10.55.0.7";


$fstab                  = "<<- 'EOF'
     data01/bacula-volumes                    $path/usr/local/bacula/volumes                    zfs   rw,noatime        0 0
     data01/bacula-volumes/DiffFile           $path/usr/local/bacula/volumes/DiffFile           zfs   rw,noatime        0 0
     data01/bacula-volumes/FullFile           $path/usr/local/bacula/volumes/FullFile           zfs   rw,noatime        0 0
     data01/bacula-volumes/FullFileNoNextPool $path/usr/local/bacula/volumes/FullFileNoNextPool zfs   rw,noatime        0 0
     data01/bacula-volumes/IncrFile           $path/usr/local/bacula/volumes/IncrFile           zfs   rw,noatime        0 0
     EOF";

exec.prepare  += "mount -F /dev/stdin -a -v $fstab";
exec.poststop += "umount -a -f -F /dev/stdin $fstab";
}

Why it didn’t work on boot

EDIT 2023-11-08 – There was a persistent problem with this approach. It would not work on reboot. It would work if I restarted the jail. Why? $path/usr/local/bacula/volumes should not be in that list.

[23:20 r730-03 dvl ~] % zfs list -r -o name,mounted,canmount,mountpoint data01/bacula-volumes
NAME                                      MOUNTED  CANMOUNT  MOUNTPOINT
data01/bacula-volumes                     no       off       /jails/bacula-sd-04/usr/local/bacula/volumes
data01/bacula-volumes/DiffFile            no       on        /jails/bacula-sd-04/usr/local/bacula/volumes/DiffFile
data01/bacula-volumes/FullFile            no       on        /jails/bacula-sd-04/usr/local/bacula/volumes/FullFile
data01/bacula-volumes/FullFileNoNextPool  no       on        /jails/bacula-sd-04/usr/local/bacula/volumes/FullFileNoNextPool
data01/bacula-volumes/IncrFile            no       on        /jails/bacula-sd-04/usr/local/bacula/volumes/IncrFile
[23:20 r730-03 dvl ~] % 

Although data01/bacula-volumes is specified as canmount off, that part is ignored with legacy mount, as opposed to zfs mount. The problem: data01/bacula-volumes would get mounted overtop of the other mount points, and you’d see nothing. That’s not helpful at all.

The solution, remove data01/bacula-volumes from the configuration. Then it worked just fine. Several people spent about 2 hours tracking that one down. It’s something we all knew about, but everyone suspected something else as the culprit.

We now return you to the original article

This takes advantage of the -Foption on mount

Specifying the mount points both here and zfs is a duplication. However, you could script that too.

I’m shocked to report that this worked first time.

Examples

I start the jail, everything is mounted:

[23:50 r730-03 dvl ~] % sudo service jail start bacula-sd-04                                                      
Starting jails: bacula-sd-04.
[23:51 r730-03 dvl ~] % zfs get -r -t filesystem mounted data01/bacula-volumes
NAME                                      PROPERTY  VALUE    SOURCE
data01/bacula-volumes                     mounted   yes      -
data01/bacula-volumes/DiffFile            mounted   yes      -
data01/bacula-volumes/FullFile            mounted   yes      -
data01/bacula-volumes/FullFileNoNextPool  mounted   yes      -
data01/bacula-volumes/IncrFile            mounted   yes      -
[23:51 r730-03 dvl ~] % 

I stop the jail, everything is unmounted:

[23:51 r730-03 dvl ~] % zfs get -r -t filesystem mounted data01/bacula-volumes
NAME                                      PROPERTY  VALUE    SOURCE
data01/bacula-volumes                     mounted   no       -
data01/bacula-volumes/DiffFile            mounted   no       -
data01/bacula-volumes/FullFile            mounted   no       -
data01/bacula-volumes/FullFileNoNextPool  mounted   no       -
data01/bacula-volumes/IncrFile            mounted   no       -
[23:52 r730-03 dvl ~] % 

With the jail, stopped, I can manipulate the jail dataset:

[23:52 r730-03 dvl ~] % sudo zfs umount data01/jails/bacula-sd-04             
[0:00 r730-03 dvl ~] % sudo zfs mount data01/jails/bacula-sd-04 

Profit!

Oh wait, there’s more

I hit this problem:

[0:05 r730-03 dvl ~] % sudo service jail start bacula-sd-04
Starting jails: cannot start jail  "bacula-sd-04": 
mount: /jails/bacula-sd-04/usr/local/bacula/volumes/DiffFile: No such file or directory
mount: /jails/bacula-sd-04/usr/local/bacula/volumes/FullFile: No such file or directory
mount: /jails/bacula-sd-04/usr/local/bacula/volumes/FullFileNoNextPool: No such file or directory
mount: /jails/bacula-sd-04/usr/local/bacula/volumes/IncrFile: No such file or directory
fstab: /dev/stdin:6: Inappropriate file type or format
jail: bacula-sd-04: /bin/sh -c mount -F /dev/stdin -a -v <<- 'EOF'
     data01/bacula-volumes                    /jails/bacula-sd-04/usr/local/bacula/volumes                    zfs   rw,noatime        0 0
     data01/bacula-volumes/DiffFile           /jails/bacula-sd-04/usr/local/bacula/volumes/DiffFile           zfs   rw,noatime        0 0
     data01/bacula-volumes/FullFile           /jails/bacula-sd-04/usr/local/bacula/volumes/FullFile           zfs   rw,noatime        0 0
     data01/bacula-volumes/FullFileNoNextPool /jails/bacula-sd-04/usr/local/bacula/volumes/FullFileNoNextPool zfs   rw,noatime        0 0
     data01/bacula-volumes/IncrFile           /jails/bacula-sd-04/usr/local/bacula/volumes/IncrFile           zfs   rw,noatime        0 0
     EOF: failed
.

I fixed it by creating the directories into the top level location.

[0:06 r730-03 dvl ~] % su
Password:
root@r730-03:/home/dvl # cd /jails/bacula-sd-04/usr/local/bacula/volumes
root@r730-03:/jails/bacula-sd-04/usr/local/bacula/volumes # sudo mkdir DiffFile FullFile FullFileNoNextPool IncrFile
root@r730-03:/jails/bacula-sd-04/usr/local/bacula/volumes # cd -
root@r730-03:/home/dvl # exit

Then it worked as expected:

[0:07 r730-03 dvl ~] % sudo service jail start bacula-sd-04
Starting jails: bacula-sd-04.
[0:07 r730-03 dvl ~] % sudo service jail stop bacula-sd-04 
Stopping jails: bacula-sd-04.
[0:07 r730-03 dvl ~] % sudo service jail start bacula-sd-04
Starting jails: bacula-sd-04.
[0:07 r730-03 dvl ~] % sudo service jail stop bacula-sd-04 
Stopping jails: bacula-sd-04.
[0:07 r730-03 dvl ~] % zfs get -r -t filesystem mounted data01/bacula-volumes
NAME                                      PROPERTY  VALUE    SOURCE
data01/bacula-volumes                     mounted   no       -
data01/bacula-volumes/DiffFile            mounted   no       -
data01/bacula-volumes/FullFile            mounted   no       -
data01/bacula-volumes/FullFileNoNextPool  mounted   no       -
data01/bacula-volumes/IncrFile            mounted   no       -
[0:07 r730-03 dvl ~] % 

In the end

I'm not sure how/why this might be better/worse than something the following. However, I know the above solution keeps the jail configuration all in one location. I think I like that better.

bacula-sd-04 {
    persist;
    ip4.addr = "$NIC|10.55.0.7";
    mount.fstab = "/etc/fstab.$name"
}

Where {{/etc/fstab.bacula-sd-04}} contains:

data01/bacula-volumes                    /jails/bacula-sd-04/usr/local/bacula/volumes                    zfs   rw,noatime        0 0
data01/bacula-volumes/DiffFile           /jails/bacula-sd-04/usr/local/bacula/volumes/DiffFile           zfs   rw,noatime        0 0
data01/bacula-volumes/FullFile           /jails/bacula-sd-04/usr/local/bacula/volumes/FullFile           zfs   rw,noatime        0 0
data01/bacula-volumes/FullFileNoNextPool /jails/bacula-sd-04/usr/local/bacula/volumes/FullFileNoNextPool zfs   rw,noatime        0 0
data01/bacula-volumes/IncrFile           /jails/bacula-sd-04/usr/local/bacula/volumes/IncrFile           zfs   rw,noatime        0 0

I know it's better than running these scripts:

[0:07 r730-03 dvl ~] % cat ~/bin/zfs-mount-bacula-sd-04-bacula-volumes
#!/bin/sh

zfs mount data01/bacula-volumes/DiffFile
zfs mount data01/bacula-volumes/IncrFile
zfs mount data01/bacula-volumes/FullFile
zfs mount data01/bacula-volumes/FullFileNoNextPool
[0:12 r730-03 dvl ~] % cat ~/bin/zfs-umount-bacula-sd-04-bacula-volumes 
#!/bin/sh

zfs umount data01/bacula-volumes/DiffFile
zfs umount data01/bacula-volumes/IncrFile
zfs umount data01/bacula-volumes/FullFile
zfs umount data01/bacula-volumes/FullFileNoNextPool
Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive

Leave a Comment

Scroll to Top