migrating data02/freshports/dev-nginx01 to data04

This post will be short on detail. I’m writing it for myself, to document what I’m doing.

I suspect Migrating data02/freshports/dev-ingress01 to another zpool will be more useful to you.

In this post:

  • FreeBSD 15.0

I stopped the jail:

[15:30 r730-01 dvl ~] % sudo service jail stop dev-nginx01
Stopping jails: dev-nginx01.

I took dev.freshports.org offline via:

[15:32 r720-02-proxy01 dvl ~] % ~/bin/offline dev.freshports.org "$(date -R -v +2H)" "Offline for filesystem migration"
<html>
<head>
<title>Error 503 Service Unavailable</title>
<style>
<style>
      body { text-align: center; padding: 20px; font: 25px Helvetica, sans-serif; color: #efe8e8; background-color:#2e2929}
      @media (min-width: 768px){
        body{ padding-top: 150px; }
      }
      h1 { font-size: 50px; }
      h2 { font-size: 35px; }
      h3 { font-size: 28px; }
      article { display: block; text-align: left; max-width: 650px; margin: 0 auto; }
      td { font-size: 25px; line-height: 1.5; margin: 20px 0; }
    </style>
</style>
</head>
<body>
<h1>Server is offline for maintenance</h1>
<h2>503 Service Unavailable</h2>

<h3>Offline for filesystem migration</h3>
<table>
<tr>
<td>Started at:</td><td>Mon, 20 Apr 2026 15:32:42 +0000</td>
</tr>
<tr>
<td>Please retry after:</td><td> Mon, 20 Apr 2026 17:32:42 +0000</td>
</tr>
</table>
</body>
</html>

The source

[15:29 r730-01 dvl ~] % zfs list -r data02/freshports/dev-nginx01
NAME                                            USED  AVAIL  REFER  MOUNTPOINT
data02/freshports/dev-nginx01                  54.7M   338G    96K  none
data02/freshports/dev-nginx01/www              54.6M   338G    96K  /jails/dev-nginx01/usr/local/www
data02/freshports/dev-nginx01/www/freshports   51.8M   338G  51.8M  /jails/dev-nginx01/usr/local/www/freshports
data02/freshports/dev-nginx01/www/freshsource  2.71M   338G  2.71M  /jails/dev-nginx01/usr/local/www/freshsource

[15:33 r730-01 dvl ~] % zfs get -t filesystem mountpoint -r data02/freshports/dev-nginx01 | grep -v no
NAME                                           PROPERTY    VALUE                                         SOURCE
data02/freshports/dev-nginx01/www              mountpoint  /jails/dev-nginx01/usr/local/www              received
data02/freshports/dev-nginx01/www/freshports   mountpoint  /jails/dev-nginx01/usr/local/www/freshports   inherited from data02/freshports/dev-nginx01/www
data02/freshports/dev-nginx01/www/freshsource  mountpoint  /jails/dev-nginx01/usr/local/www/freshsource  inherited from data02/freshports/dev-nginx01/www

[15:34 r730-01 dvl ~] % zfs get -t filesystem canmount -r data02/freshports/dev-nginx01 | grep -v on
NAME                                           PROPERTY  VALUE     SOURCE
data02/freshports/dev-nginx01/www              canmount  off       received
data02/freshports/dev-nginx01/www/freshports   canmount  noauto    received
data02/freshports/dev-nginx01/www/freshsource  canmount  noauto    received

[15:35 r730-01 dvl ~] % zfs get -t filesystem mounted -r data02/freshports/dev-nginx01 | grep -v yes
NAME                                           PROPERTY  VALUE    SOURCE
data02/freshports/dev-nginx01                  mounted   no       -
data02/freshports/dev-nginx01/www              mounted   no       -
data02/freshports/dev-nginx01/www/freshports   mounted   no       -
data02/freshports/dev-nginx01/www/freshsource  mounted   no       -

Now, you might look at that, and wonder why the filesystems are offline.

This is why:

[15:30 r730-01 dvl ~] % cat /etc/jail.conf.d/dev-nginx01.conf 
dev-nginx01 {

  #
  # start of standard settings for each jail
  #

  $bridge = "bridge0";

  exec.start = "/bin/sh /etc/rc";
  exec.stop  = "/bin/sh /etc/rc.shutdown";
  exec.clean;
  mount.devfs;
  path = /jails/$name;

  allow.raw_sockets;
  #securelevel = 2;

  host.hostname = "$name.int.unixathome.org";
  exec.consolelog="/var/tmp/jail-console-$name.log";

  persist;

  #
  # end of standard settings for each jail
  #

    ip4.addr = "$bridge|10.55.0.39";

    allow.mount=true;
    allow.mount.zfs=true;
    enforce_statfs=1;
    devfs_ruleset=5;

    mount.fstab="/etc/fstab.$name";

    # because want to mount zfs, we do that before the rc start up
    # not sure if we MUST do it in that order.
    exec.start="zfs mount -a";
    exec.start+="/bin/sh /etc/rc";

    mount.fstab="/etc/fstab.$name";

    # jail all the things.
    exec.created+="zfs set jailed=on data02/freshports/jailed/dev-nginx01/cache";
    exec.created+="zfs set jailed=on data02/freshports/jailed/dev-nginx01/cache/categories";
    exec.created+="zfs set jailed=on data02/freshports/jailed/dev-nginx01/cache/commits";
    exec.created+="zfs set jailed=on data02/freshports/jailed/dev-nginx01/cache/daily";
    exec.created+="zfs set jailed=on data02/freshports/jailed/dev-nginx01/cache/general";
    exec.created+="zfs set jailed=on data02/freshports/jailed/dev-nginx01/cache/news";
    exec.created+="zfs set jailed=on data02/freshports/jailed/dev-nginx01/cache/packages";
    exec.created+="zfs set jailed=on data02/freshports/jailed/dev-nginx01/cache/pages";
    exec.created+="zfs set jailed=on data02/freshports/jailed/dev-nginx01/cache/ports";
    exec.created+="zfs set jailed=on data02/freshports/jailed/dev-nginx01/cache/spooling";

    exec.created+="zfs jail $name data02/freshports/jailed/dev-nginx01/cache";

    # mount things
    exec.created+="zfs mount data02/freshports/dev-nginx01/www/freshports";
    exec.created+="zfs mount data02/freshports/dev-nginx01/www/freshsource";




    # unjail and umount so we can get access to the underlying mount points
    # when required/
    exec.poststop+="zfs set jailed=off data02/freshports/jailed/dev-nginx01/cache";
    exec.poststop+="zfs set jailed=off data02/freshports/jailed/dev-nginx01/cache/categories";
    exec.poststop+="zfs set jailed=off data02/freshports/jailed/dev-nginx01/cache/commits";
    exec.poststop+="zfs set jailed=off data02/freshports/jailed/dev-nginx01/cache/daily";
    exec.poststop+="zfs set jailed=off data02/freshports/jailed/dev-nginx01/cache/general";
    exec.poststop+="zfs set jailed=off data02/freshports/jailed/dev-nginx01/cache/news";
    exec.poststop+="zfs set jailed=off data02/freshports/jailed/dev-nginx01/cache/packages";
    exec.poststop+="zfs set jailed=off data02/freshports/jailed/dev-nginx01/cache/pages";
    exec.poststop+="zfs set jailed=off data02/freshports/jailed/dev-nginx01/cache/ports";
    exec.poststop+="zfs set jailed=off data02/freshports/jailed/dev-nginx01/cache/spooling";

    exec.poststop+="zfs umount data02/freshports/jailed/dev-nginx01/cache";
    exec.poststop+="zfs umount data02/freshports/jailed/dev-nginx01/cache/categories";
    exec.poststop+="zfs umount data02/freshports/jailed/dev-nginx01/cache/commits";
    exec.poststop+="zfs umount data02/freshports/jailed/dev-nginx01/cache/daily";
    exec.poststop+="zfs umount data02/freshports/jailed/dev-nginx01/cache/general";
    exec.poststop+="zfs umount data02/freshports/jailed/dev-nginx01/cache/news";
    exec.poststop+="zfs umount data02/freshports/jailed/dev-nginx01/cache/packages";
    exec.poststop+="zfs umount data02/freshports/jailed/dev-nginx01/cache/pages";
    exec.poststop+="zfs umount data02/freshports/jailed/dev-nginx01/cache/ports";
    exec.poststop+="zfs umount data02/freshports/jailed/dev-nginx01/cache/spooling";


    exec.poststop+="zfs umount data02/freshports/dev-nginx01/www/freshports";
    exec.poststop+="zfs umount data02/freshports/dev-nginx01/www/freshsource";
}

Start/stop the jail, and the filesystems are mounted/umounted.

Why? So I can manipulate the filesystems without having to umount them manually.

The snapshot and copy

Snapshot:

[15:35 r730-01 dvl ~] % sudo zfs snapshot -r data02/freshports/dev-nginx01@for.data04.0
[15:38 r730-01 dvl ~] % 

Send:

root@r730-01:/home/dvl # zfs send -R data02/freshports/dev-nginx01@for.data04.0 | zfs receive data04/freshports/dev-nginx01
root@r730-01:/home/dvl # 

Received:

root@r730-01:/home/dvl # zfs list -r data04/freshports/dev-nginx01
NAME                                            USED  AVAIL  REFER  MOUNTPOINT
data04/freshports/dev-nginx01                  92.7M  15.0T   205K  /data04/freshports/dev-nginx01
data04/freshports/dev-nginx01/www              92.5M  15.0T   205K  /jails/dev-nginx01/usr/local/www
data04/freshports/dev-nginx01/www/freshports   87.1M  15.0T  87.1M  /jails/dev-nginx01/usr/local/www/freshports
data04/freshports/dev-nginx01/www/freshsource  5.17M  15.0T  5.17M  /jails/dev-nginx01/usr/local/www/freshsource

Why does the destination take so much more space?

root@r730-01:/home/dvl # zfs get compression data02/freshports/dev-nginx01 data04/freshports/dev-nginx01
NAME                           PROPERTY     VALUE           SOURCE
data02/freshports/dev-nginx01  compression  zstd            inherited from data02
data04/freshports/dev-nginx01  compression  zstd            inherited from data04
root@r730-01:/home/dvl # zfs get recordsize data02/freshports/dev-nginx01 data04/freshports/dev-nginx01
NAME                           PROPERTY    VALUE    SOURCE
data02/freshports/dev-nginx01  recordsize  32K      inherited from data02/freshports
data04/freshports/dev-nginx01  recordsize  128K     inherited from data04
root@r730-01:/home/dvl # zfs get -r -t filesystem recordsize data02/freshports/dev-nginx01 data04/freshports/dev-nginx01
NAME                                           PROPERTY    VALUE    SOURCE
data02/freshports/dev-nginx01                  recordsize  32K      inherited from data02/freshports
data02/freshports/dev-nginx01/www              recordsize  128K     received
data02/freshports/dev-nginx01/www/freshports   recordsize  128K     received
data02/freshports/dev-nginx01/www/freshsource  recordsize  128K     received
data04/freshports/dev-nginx01                  recordsize  128K     inherited from data04
data04/freshports/dev-nginx01/www              recordsize  128K     received
data04/freshports/dev-nginx01/www/freshports   recordsize  128K     received
data04/freshports/dev-nginx01/www/freshsource  recordsize  128K     received
root@r730-01:/home/dvl # 

I don’t know. Nothing clear in there to me.

Turning off the old filesystem

Set canmount:

root@r730-01:/home/dvl # zfs list -Hr data02/freshports/dev-nginx01 | cut -f 1 -w | tail -r | xargs -n 1 sudo zfs set canmount=off
root@r730-01:/home/dvl # 

rename:

root@r730-01:/home/dvl # zfs rename data02/freshports/dev-nginx01 data02/freshports/dev-nginx01.DELETE.ME.after.2026.05.15

Start the webserver

root@r730-01:/home/dvl # service jail start dev-nginx01
Starting jails: dev-nginx01.
root@r730-01:/home/dvl # 

Put the site back online.

[15:58 r720-02-proxy01 dvl ~] % sudo rm /usr/local/www/offline/dev.freshports.org-maintenance.html 
[16:01 r720-02-proxy01 dvl ~] % 

Done. Looks good to me.

Edits

This was done to keep sanoid working with the new filesystems, not the old (and now renamed):

[16:03 r730-01 dvl ~] % sudoedit /usr/local/etc/sanoid/sanoid.conf

Old snapshots

Here go the old snapshots:

[16:08 r730-01 dvl ~] % zfs list -H -o name -r -t snapshot data02/freshports/dev-nginx01.DELETE.ME.after.2026.05.15 | grep -v for.data04.0 | xargs -n 1 sudo zfs destroy     

and now we have:

[16:09 r730-01 dvl ~] % zfs list -r data02/freshports/dev-nginx01.DELETE.ME.after.2026.05.15
NAME                                                                       USED  AVAIL  REFER  MOUNTPOINT
data02/freshports/dev-nginx01.DELETE.ME.after.2026.05.15                  54.7M   338G    96K  none
data02/freshports/dev-nginx01.DELETE.ME.after.2026.05.15/www              54.6M   338G    96K  /jails/dev-nginx01/usr/local/www
data02/freshports/dev-nginx01.DELETE.ME.after.2026.05.15/www/freshports   51.8M   338G  51.8M  /jails/dev-nginx01/usr/local/www/freshports
data02/freshports/dev-nginx01.DELETE.ME.after.2026.05.15/www/freshsource  2.71M   338G  2.71M  /jails/dev-nginx01/usr/local/www/freshsource
Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive

Leave a Comment

Scroll to Top