#!/bin/sh
# -*- coding: latin-1 -*-

# Copyright © 2019, Trond Endrestøl <Trond.Endrestol@ximalas.info>
# All rights reserved.

# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:

# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.

# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Ideally, this script should be run after running initdb and after
# renaming the directory /var/db/postgres/dataNN to
# /var/db/postgres/dataNN.new.
#
# After running this script, move all files and directories within
# /var/db/postgres/dataNN.new to /var/db/postgres/dataNN, and finally
# delete /var/db/postgres/dataNN.new.

if [ -z "${DATAPOOL}" ]; then
  echo "${0}: you must set the environment variable DATAPOOL to the name of your data pool" >/dev/stderr
  echo "${0}: e.g. export DATAPOOL=zdata" >/dev/stderr
  exit 69
fi

if ! zpool list "${DATAPOOL}" >/dev/null 2>&1; then
  echo "${0}: data pool ${DATAPOOL} does not exist" >/dev/stderr
  echo "${0}: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${DATAPOOL} ..." >/dev/stderr
  exit 69
fi;

# DESTDIR is only used with the chown and chmod operations toward the end of this script.
if [ -z "${DESTDIR}" ]; then
  echo "${0}: although not needed, you might want to set the environment variable DESTDIR to the destination directory" >/dev/stderr
  echo "${0}: e.g. export DESTDIR=/tmp/zroot" >/dev/stderr
  echo "${0}:   or export DESTDIR=/"          >/dev/stderr
  echo || exit
  #exit 69
fi

PGSQL_VERSION=12

# The optimizations for MySQL and PostgreSQL are due to Allan Jude &
# Michael W. Lucas and their book "FreeBSD Mastery: Advanced ZFS".
# Also see their article in the Winter 2016 issue (Vol. 41, No. 4) of USENIX ";login:".
# https://www.usenix.org/publications/login/winter2016
# https://www.usenix.org/publications/login/winter2016/jude
# https://www.usenix.org/system/files/login/articles/login_winter16_09_jude.pdf

# These datasets exists solely for classification purposes and for providing base mountpoints for their children.
if ! zfs list ${DATAPOOL}/var >/dev/null 2>&1; then
  zfs create ${DATAPOOL}/var || exit
  zfs set canmount=off ${DATAPOOL}/var || exit
fi

if ! zfs list ${DATAPOOL}/var/db >/dev/null 2>&1; then
  zfs create ${DATAPOOL}/var/db || exit
  zfs set canmount=off ${DATAPOOL}/var/db || exit
fi

# Database files could potentially be stored on a dedicated zpool.
if ! zfs list ${DATAPOOL}/var/db/postgres >/dev/null 2>&1; then
  zfs create ${DATAPOOL}/var/db/postgres || exit # From PostgreSQL 9.6 onward, see ports/head r421360
fi

if ! zfs list ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION} >/dev/null 2>&1; then
  zfs create ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION} || exit
fi

if ! zfs list ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION}/base >/dev/null 2>&1; then
  zfs create ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION}/base || exit

  zfs set logbias=throughput ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION}/base || exit
  zfs set primarycache=metadata ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION}/base || exit
  zfs set recordsize=8K ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION}/base || exit
  zfs set redundant_metadata=most ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION}/base || exit
fi

if ! zfs list ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION}/pg_wal >/dev/null 2>&1; then
  zfs create ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION}/pg_wal || exit

  zfs set logbias=throughput ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION}/pg_wal || exit
  zfs set primarycache=metadata ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION}/pg_wal || exit
  zfs set recordsize=8K ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION}/pg_wal || exit
  zfs set redundant_metadata=most ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION}/pg_wal || exit
fi

chown -R 770:770 ${DESTDIR}/var/db/postgres || exit
chmod -R 0700 ${DESTDIR}/var/db/postgres/data* || exit

zfs list -rt all ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION} || exit
echo || exit
zfs get -r creation ${DATAPOOL}/var/db/postgres/data${PGSQL_VERSION} || exit

# EOF
