From ab3271838f86141ebfe7b1eef2b5147524cbca36 Mon Sep 17 00:00:00 2001 From: Andrew Innes Date: Tue, 14 Nov 2023 13:16:00 +0800 Subject: [PATCH] sh --- cmd/zed/zed.d/snapshot_mount.sh | 30 ++ cmd/zed/zed.d/snapshot_unmount.sh | 1 + cmd/zed/zed.d/zvol_create.sh | 28 ++ cmd/zed/zed.d/zvol_remove.sh | 23 ++ contrib/macOS/product-scripts/poolcheck.sh | 11 + contrib/macOS/product-scripts/zevocheck.sh | 18 + scripts/load_macos.sh | 16 + scripts/pkg_macos.sh | 460 +++++++++++++++++++++ scripts/zfs-tests.sh | 75 +++- 9 files changed, 661 insertions(+), 1 deletion(-) create mode 100644 cmd/zed/zed.d/snapshot_mount.sh create mode 100644 cmd/zed/zed.d/snapshot_unmount.sh create mode 100644 cmd/zed/zed.d/zvol_create.sh create mode 100644 cmd/zed/zed.d/zvol_remove.sh create mode 100644 contrib/macOS/product-scripts/poolcheck.sh create mode 100644 contrib/macOS/product-scripts/zevocheck.sh create mode 100644 scripts/load_macos.sh create mode 100644 scripts/pkg_macos.sh diff --git a/cmd/zed/zed.d/snapshot_mount.sh b/cmd/zed/zed.d/snapshot_mount.sh new file mode 100644 index 000000000000..111b692cea2f --- /dev/null +++ b/cmd/zed/zed.d/snapshot_mount.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# shellcheck disable=SC2154 +# +# Helper to mount and unmount snapshots when asked to by kernel. +# +# Mostly used in macOS. +# +set -ef + +[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc" +. "${ZED_ZEDLET_DIR}/zed-functions.sh" + +[ -n "${ZEVENT_SNAPSHOT_NAME}" ] || exit 1 +[ -n "${ZEVENT_SUBCLASS}" ] || exit 2 + +if [ "${ZEVENT_SUBCLASS}" = "snapshot_mount" ]; then + action="mount" +elif [ "${ZEVENT_SUBCLASS}" = "snapshot_unmount" ]; then + action="unmount" +else + zed_log_err "unsupported event class \"${ZEVENT_SUBCLASS}\"" + exit 3 +fi + +zed_exit_if_ignoring_this_event +zed_check_cmd "${ZFS}" || exit 4 + +"${ZFS}" "${action}" "${ZEVENT_SNAPSHOT_NAME}" + +finished diff --git a/cmd/zed/zed.d/snapshot_unmount.sh b/cmd/zed/zed.d/snapshot_unmount.sh new file mode 100644 index 000000000000..9f74a29e61f4 --- /dev/null +++ b/cmd/zed/zed.d/snapshot_unmount.sh @@ -0,0 +1 @@ +snapshot_mount.sh \ No newline at end of file diff --git a/cmd/zed/zed.d/zvol_create.sh b/cmd/zed/zed.d/zvol_create.sh new file mode 100644 index 000000000000..99f3370e3eab --- /dev/null +++ b/cmd/zed/zed.d/zvol_create.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# shellcheck disable=SC2154 +# +# Log the zevent via syslog. +# + +# Given POOL and DATASET name for ZVOL +# DEVICE_NAME for /dev/disk* +# RAW_DEVICE_NAME for /dev/rdisk* +# Create symlink in +# /var/run/zfs/zvol/dsk/POOL/DATASET -> /dev/disk* +# /var/run/zfs/zvol/rdsk/POOL/DATASET -> /dev/rdisk* + +ZVOL_ROOT="/var/run/zfs/zvol" + +mkdir -p "$(dirname "${ZVOL_ROOT}/rdsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}")" "$(dirname "${ZVOL_ROOT}/dsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}")" + +# Remove them if they already exist. (ln -f is not portable) +rm -f "${ZVOL_ROOT}/rdsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}" "${ZVOL_ROOT}/dsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}" + +ln -s "/dev/${ZEVENT_DEVICE_NAME}" "${ZVOL_ROOT}/dsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}" +ln -s "/dev/${ZEVENT_RAW_NAME}" "${ZVOL_ROOT}/rdsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}" + +logger -t "${ZED_SYSLOG_TAG:=zed}" -p "${ZED_SYSLOG_PRIORITY:=daemon.notice}" \ + eid="${ZEVENT_EID}" class="${ZEVENT_SUBCLASS}" \ + "${ZEVENT_POOL:+pool=$ZEVENT_POOL}/${ZEVENT_VOLUME} symlinked ${ZEVENT_DEVICE_NAME}" + +echo 0 diff --git a/cmd/zed/zed.d/zvol_remove.sh b/cmd/zed/zed.d/zvol_remove.sh new file mode 100644 index 000000000000..1de53af38b68 --- /dev/null +++ b/cmd/zed/zed.d/zvol_remove.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# shellcheck disable=SC2154 +# +# Log the zevent via syslog. +# + +# Given POOL and DATASET name for ZVOL +# DEVICE_NAME for /dev/disk* +# RAW_DEVICE_NAME for /dev/rdisk* +# Create symlink in +# /var/run/zfs/zvol/dsk/POOL/DATASET -> /dev/disk* +# /var/run/zfs/zvol/rdsk/POOL/DATASET -> /dev/rdisk* + +ZVOL_ROOT="/var/run/zfs/zvol" + +rm -f "${ZVOL_ROOT}/rdsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}" "${ZVOL_ROOT}/dsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}" +rmdir "$(dirname "${ZVOL_ROOT}/rdsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}")" "$(dirname "${ZVOL_ROOT}/dsk/${ZEVENT_POOL}/${ZEVENT_VOLUME}")" + +logger -t "${ZED_SYSLOG_TAG:=zed}" -p "${ZED_SYSLOG_PRIORITY:=daemon.notice}" \ + eid="${ZEVENT_EID}" class="${ZEVENT_SUBCLASS}" \ + "${ZEVENT_POOL:+pool=$ZEVENT_POOL}/${ZEVENT_VOLUME} removed symlink" + +echo 0 diff --git a/contrib/macOS/product-scripts/poolcheck.sh b/contrib/macOS/product-scripts/poolcheck.sh new file mode 100644 index 000000000000..c7a989fbe87d --- /dev/null +++ b/contrib/macOS/product-scripts/poolcheck.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +#exit code 1 means no zfs file systems mounted + +echo "Mounted ZFS file system(s) check" +myvar="$(2>/dev/null /usr/bin/lsvfs zfs | /usr/bin/tail -1 | /usr/bin/awk '{print $2}')" +[ ! -z "${myvar##*[!0-9]*}" ] || exit 1 +[ $myvar -ne 0 ] && exit 0 +sysctl -n kstat.zfs.darwin.ldi.handle_count || exit 1 +if [ x"$(sysctl -n kstat.zfs.darwin.ldi.handle_count)" != x"0" ]; then exit 0; fi +exit 1 diff --git a/contrib/macOS/product-scripts/zevocheck.sh b/contrib/macOS/product-scripts/zevocheck.sh new file mode 100644 index 000000000000..be541693774d --- /dev/null +++ b/contrib/macOS/product-scripts/zevocheck.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +#exit code 1 means ZEVO is neither installed nor just uninstalled without reboot + +echo "ZEVO files check" +ls /System/Library/Extensions/ZFSDriver.kext/ &>/dev/null && exit 0 +ls /System/Library/Extensions/ZFSFilesystem.kext/ &>/dev/null && exit 0 +ls /Library/LaunchDaemons/com.getgreenbytes* &>/dev/null && exit 0 + +echo "ZEVO launchctl check" +/bin/launchctl list | grep greenbytes &>/dev/null +[ $? -eq 0 ] && exit 0 + +echo "ZEVO kextstat check" +/usr/sbin/kextstat | grep greenbytes &>/dev/null +[ $? -eq 0 ] && exit 0 + +exit 1 diff --git a/scripts/load_macos.sh b/scripts/load_macos.sh new file mode 100644 index 000000000000..36d2c9bc5338 --- /dev/null +++ b/scripts/load_macos.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# +# Expected to be run from the root of the source tree, as root; +# ./scripts/load_macos.sh +# +# Copies compiled zfs.kext to /tmp/ and prepares the requirements +# for load. +# + +rsync -ar module/os/macos/zfs.kext/ /tmp/zfs.kext/ + +chown -R root:wheel /tmp/zfs.kext + +kextload -v /tmp/zfs.kext || kextutil /tmp/zfs.kext + +# log stream --source --predicate 'sender == "zfs"' --style compact diff --git a/scripts/pkg_macos.sh b/scripts/pkg_macos.sh new file mode 100644 index 000000000000..6b5e761678fa --- /dev/null +++ b/scripts/pkg_macos.sh @@ -0,0 +1,460 @@ +#!/usr/bin/env bash + +# +# CDDL HEADER START +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# CDDL HEADER END +# + +# Copyright (c) 2020 by ilovezfs +# Copyright (c) 2020 by Jorgen Lundman + +# +# A script to produce an installable .pkg for macOS. +# +# Environment variables: +# +# $PKG_CODESIGN_KEY: Set to name of certificate for codesigning, +# as named in Keychain. For example; +# "Developer ID Application: Joergen Lundman (735AM5QEU3)" +# +# $PKG_NOTARIZE_KEY: Set to the notarize key you can create on +# Apple developer pages. For example; +# "awvz-fqoi-cxag-tymn" +# +# $PKG_INSTALL_KEY: Set to the name of certificate for installer +# signing, as named in Keychain, For example; +# "Developer ID Installer: Joergen Lundman (735AM5QEU3)" +# + +BASE_DIR=$(dirname "$0") +SCRIPT_COMMON=common.sh +if [ -f "${BASE_DIR}/${SCRIPT_COMMON}" ]; then + . "${BASE_DIR}/${SCRIPT_COMMON}" +else + echo "Missing helper script ${SCRIPT_COMMON}" && exit 1 +fi + +WORKNAME="macos-root" +WORKDIR="/private/var/tmp/${WORKNAME}" + +# If there are two dots "10.15.4", eat it +OS=$(sw_vers | awk '{if ($1 == "ProductVersion:") print $2;}') +OS=$(echo "$OS" | awk -F . '{if ($1 == 10) print $1"."$2; else print $1}') +RC=$(grep Release: META | awk '$2 ~ /rc/ { print $2}') + +function usage +{ + echo "$0: Create installable pkg for macOS" + echo "" + echo " Options:" + echo " -l skip make install step, using a folder of a previous run" + echo " -L copy and fix external libraries" + exit +} + +while getopts "hlL" opt; do + case $opt in + l ) skip_install=1 ;; + L ) fix_libraries=1 ;; + h ) usage + exit 2 + ;; + * ) echo "Invalid argument: -$OPTARG"; + usage + exit 1 + esac +done + +case ${OS} in + 10.8|10.9|10.10|10.11|10.12|10.13) + unset PKG_NOTARIZE_KEY + echo "No notarize for OS $OS" + ;; +esac + +# pass remaining arguments on +shift $((OPTIND - 1)) + + +echo "" +echo "Creating pkg for macOS installation... " +echo "" + +if [ -z "$PKG_CODESIGN_KEY" ]; then + echo "\$PKG_CODESIGN_KEY not set to certificate name, skipping codesign." +fi + +if [ -z "$PKG_NOTARIZE_KEY" ]; then + echo "\$PKG_NOTARIZE_KEY not set to pass-key, skipping notarize." +fi + +if [ -z "$PKG_INSTALL_KEY" ]; then + echo "\$PKG_INSTALL_KEY not set to certificate name, skipping pkg install signing." +fi + +version=$(awk < META '{if ($1 == "Version:") print $2;}') +prefix="/usr/local" +if [ -f "${BASE_DIR}/../config.status" ]; then + prefix=$(grep 'S\["prefix"\]' "${BASE_DIR}/../config.status" | tr '=' ' ' | awk '{print $2;}' | tr -d '"') +fi + +echo "Version is $version" +echo "Prefix set to $prefix" +echo "RC, if set: $RC" +echo "" + +sleep 3 + +if [ -z $skip_install ]; then + rm -rf ${WORKDIR} || true + + mkdir -p ${WORKDIR} || fail "Unable to create $WORKDIR" + + echo "Running \"make install DESTDIR=$WORKDIR\" ... " + make install DESTDIR="${WORKDIR}" || fail "Make install failed." +fi + +echo "" +echo "make install completed." +echo "" + +# Make an attempt to figure out where "zpool" is installed to, +# repo default is /usr/local/sbin/ but macOS prefers /usr/local/bin +pushd $WORKDIR || fail "failed to create workdir" +file=$(find usr -type f -name zpool) +bindir=$(dirname "$file") +popd || fail "failed to popd" + +codesign_dirs=" +${WORKDIR}/Library/Extensions/zfs.kext/ +" +codesign_files=" +${WORKDIR}/${bindir}/zdb +${WORKDIR}/${bindir}/zed +${WORKDIR}/${bindir}/zfs +${WORKDIR}/${bindir}/zhack +${WORKDIR}/${bindir}/zinject +${WORKDIR}/${bindir}/zpool +${WORKDIR}/${bindir}/zstream +${WORKDIR}/${bindir}/ztest +${WORKDIR}/${bindir}/zfs_ids_to_path +${WORKDIR}/${bindir}/InvariantDisks +${WORKDIR}/${bindir}/zfs_util +${WORKDIR}/${bindir}/zconfigd +${WORKDIR}/${bindir}/zsysctl +${WORKDIR}/${bindir}/mount_zfs +${WORKDIR}/${prefix}/libexec/zfs/zpool_influxdb +${WORKDIR}/${prefix}/lib/libnvpair.a +${WORKDIR}/${prefix}/lib/libuutil.a +${WORKDIR}/${prefix}/lib/libzfs.a +${WORKDIR}/${prefix}/lib/libzpool.a +${WORKDIR}/${prefix}/lib/libzfs_core.a +${WORKDIR}/${prefix}/lib/librt.so.1 +${WORKDIR}/${prefix}/lib/libnvpair.?.dylib +${WORKDIR}/${prefix}/lib/libuutil.?.dylib +${WORKDIR}/${prefix}/lib/libzfs.?.dylib +${WORKDIR}/${prefix}/lib/libzpool.?.dylib +${WORKDIR}/${prefix}/lib/libzfs_core.?.dylib +${WORKDIR}/${prefix}/lib/libzfsbootenv.?.dylib +${WORKDIR}/Library/Filesystems/zfs.fs/Contents/Resources/zfs_util +${WORKDIR}/Library/Filesystems/zfs.fs/Contents/Resources/mount_zfs +" + +codesign_all="$codesign_files $codesign_dirs" + +function fail +{ + echo "$@" + exit 1 +} + +function do_unlock +{ + cert=$1 + + echo "Looking for certificate ${cert} ..." + + keychain=$(security find-certificate -c "${cert}" | awk '{if ($1 == "keychain:") print $2;}'|tr -d '"') + + echo "Unlocking keychain $keychain ..." + security unlock-keychain "${keychain}" || fail "Unable to unlock keychain" + + retval=${keychain} +} + +function do_codesign +{ + failures=0 + + echo "" + + do_unlock "${PKG_CODESIGN_KEY}" + + echo "OS $OS" + if [ x"$OS" == x"10.12" ] || + [ x"$OS" == x"10.11" ] || + [ x"$OS" == x"10.10" ] || + [ x"$OS" == x"10.9" ]; then + extra="" + else + extra="--options runtime" + fi + + for file in ${codesign_all} + do + echo "$file" + codesign --timestamp ${extra} -fvs "${PKG_CODESIGN_KEY}" "${file}" || failures=$((failures+1)) + done + + if [ "$failures" -ne 0 ]; then + echo "codesign phase had $failures issues ..." + exit 1 + fi + + # Look into where mount_zfs umount_zfs fsck_zfs went .. + # also: InvariantDisks +} + +# Delete everything in a directory, keeping a list +# of files. +# argument 1: directory path "/tmp/dir" +# argument 2: keep list "(item1|item2|tem3)" +function delete_and_keep +{ + # Keep only commands that apply to macOS + directory="$1" + keep="$2" + + pushd "${directory}" || fail "Unable to cd to ${directory}" + + shopt -s extglob + + for file in * + do + # shellcheck disable=SC2254 + case "${file}" in + !${keep}) + echo "Deleting non macOS file \"$file\"" + rm -f "${file}" + ;; + *) + # echo "Not deleting $file" + esac + done + shopt -u extglob + popd || fail "failed to popd" +} + +function do_prune +{ + + delete_and_keep "${WORKDIR}/${bindir}/" "(zfs|zpool|zdb|zed|zhack|zinject|zstream|zstreamdump|ztest|InvariantDisks|zfs_util|zconfigd|arc_summary|arcstat|dbufstat|fsck.zfs|zilstat|zfs_ids_to_path|zpool_influxdb|zsysctl|mount_zfs)" + + pushd "${WORKDIR}" || fail "Unable to cd to ${WORKDIR}" + + # Using relative paths here for safety + rm -rf \ +"./${prefix}/share/zfs-macos/runfiles" \ +"./${prefix}/share/zfs-macos/test-runner" \ +"./${prefix}/share/zfs-macos/zfs-tests" \ +"./${prefix}/src" + + popd || fail "failed to popd" +} + +# Find any libraries we link with outside of zfs (and system). +# For example, /usr/local/opt/openssl/lib/libssl.1.1.0.dylib +# and copy them into /usr/local/zfs/lib - then update the paths to +# those libraries in all cmds and libraries. +# To do, handle "/usr/local/zfs/" from ./configure arguments (--prefix) +function copy_fix_libraries +{ + echo "Fixing external libraries ... " + fixlib=$(otool -L ${codesign_files} | egrep '/usr/local/opt/|/opt/local/lib/' |awk '{print $1;}' | grep '\.dylib$' | sort | uniq) + + # Add the libs into codesign list - both to be codesigned, and updated + # between themselves (libssl depends on libcrypt) + # copy over, build array of relative paths to add. + fixlib_relative="" + for lib in $fixlib + do + dir=$(dirname "$lib") + name=$(basename "$lib" .dylib) + echo " working on ${name}.dylib ..." + rsync -ar --include "${name}*" --exclude="*" "${dir}/" "${WORKDIR}/${prefix}/lib/" + fixlib_relative="${fixlib_relative} ${WORKDIR}/${prefix}/lib/${name}.dylib" + done + + echo "Adding in new libraries: " + echo "${fixlib_relative}" + + # Add new libraries + codesign_files="${codesign_files} ${fixlib_relative}" + codesign_all="${codesign_all} ${fixlib_relative}" + + # Fix up paths between binaries and libraries + for lib in $fixlib + do + dir=$(dirname "$lib") + name=$(basename "$lib" .dylib) + + # We could just change $lib into $prefix, which will work for + # zfs libraries. But libssl having libcrypto might have a different + # path, so lookup the source path each time. + for file in $codesign_files + do + chmod u+w "${file}" + src=$(otool -L "$file" | awk '{print $1;}' | grep "${name}.dylib") + install_name_tool -change "${src}" "${prefix}/lib/${name}.dylib" "${file}" + done + done +} + +# Upload .pkg file +# Staple .pkg file +function do_notarize +{ + echo "Uploading PKG to Apple ..." + + TFILE="out-altool.xml" + RFILE="req-altool.xml" + xcrun altool --notarize-app -f my_package_new.pkg --primary-bundle-id org.openzfsonosx.zfs -u lundman@lundman.net -p "$PKG_NOTARIZE_KEY" --output-format xml > ${TFILE} + + GUID=$(/usr/libexec/PlistBuddy -c "Print :notarization-upload:RequestUUID" ${TFILE}) + echo "Uploaded. GUID ${GUID}" + echo "Waiting for Apple to notarize..." + while true + do + sleep 10 + echo "Querying Apple." + + xcrun altool --notarization-info "${GUID}" -u lundman@lundman.net -p "$PKG_NOTARIZE_KEY" --output-format xml > ${RFILE} + status=$(/usr/libexec/PlistBuddy -c "Print :notarization-info:Status" ${RFILE}) + if [ "$status" != "in progress" ]; then + echo "Status: $status ." + break + fi + echo "Status: $status - sleeping ..." + sleep 30 + done + + echo "Stapling PKG ..." + xcrun stapler staple my_package_new.pkg + ret=$? + xcrun stapler validate -v my_package_new.pkg + + if [ $ret != 0 ]; then + echo "Failed to notarize: $ret" + grep "https://" ${RFILE} + exit 1 + fi + +} + +echo "Pruning install area ..." +do_prune + +if [ -n "$fix_libraries" ]; then + copy_fix_libraries + copy_fix_libraries +fi + +if [ -n "$PKG_CODESIGN_KEY" ]; then + do_codesign +fi + +sleep 1 + +echo "Creating pkg ... " + +sign=() + +if [ -n "$PKG_INSTALL_KEY" ]; then + do_unlock "${PKG_INSTALL_KEY}" + #sign=(--sign "$PKG_INSTALL_KEY" --keychain "$retval" --keychain ~/Library/Keychains/login.keychain-db) + echo sign=--sign "$PKG_INSTALL_KEY" --keychain "$retval" + sign=(--sign "$PKG_INSTALL_KEY" --keychain "$retval") +fi + +rm -f my_package.pkg +pkgbuild --root "${WORKDIR}" --identifier org.openzfsonosx.zfs --version "${version}" --scripts "${BASE_DIR}/../contrib/macOS/pkg-scripts/" "${sign[@]}" my_package.pkg + +ret=$? + +echo "pkgbuild result $ret" + +if [ $ret != 0 ]; then + fail "pkgbuild failed" +fi + +friendly=$(awk '/SOFTWARE LICENSE AGREEMENT FOR macOS/' '/System/Library/CoreServices/Setup Assistant.app/Contents/Resources/en.lproj/OSXSoftwareLicense.rtf' | awk -F 'macOS ' '{print $NF}' | tr -d '\\') +if [ -z "$friendly" ]; then + friendly=$(awk '/SOFTWARE LICENSE AGREEMENT FOR OS X/' '/System/Library/CoreServices/Setup Assistant.app/Contents/Resources/en.lproj/OSXSoftwareLicense.rtf' | awk -F 'OS X ' '{print $NF}' | awk '{print substr($0, 0, length($0)-1)}') +fi + +friendly=$(echo "$friendly" | tr ' ' '.') + +# Now fiddle with pkg to make it nicer +productbuild --synthesize --package ./my_package.pkg distribution.xml + +sed < distribution.xml > distribution_new.xml -e \ +"s## Open ZFS on OsX ${version} - ${friendly}-${OS}\\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ + \\ +\\ +\\ +\\ +\\ +#g" + +sed -i "" \ + -e "/SCRIPT_REPLACE/{r ${BASE_DIR}/../contrib/macOS/resources/javascript.js" \ + -e 'd' -e '}' \ + distribution_new.xml + +rm -f my_package_new.pkg +productbuild --distribution distribution_new.xml --resources "${BASE_DIR}/../contrib/macOS/resources/" --scripts "${BASE_DIR}/../contrib/macOS/product-scripts" "${sign[@]}" --package-path ./my_package.pkg my_package_new.pkg + +if [ -n "$PKG_NOTARIZE_KEY" ]; then + SECONDS=0 + do_notarize + echo "Notarize took $SECONDS seconds to complete" +fi + +arch=$(uname -m) +if [ x"$arch" == x"arm64" ]; then + name="OpenZFSonOsX-${version}${RC}-${friendly}-${OS}-${arch}.pkg" +else + name="OpenZFSonOsX-${version}${RC}-${friendly}-${OS}.pkg" +fi + +mv my_package_new.pkg "${name}" +ls -l "${name}" + +# Cleanup +rm -f my_package.pkg distribution.xml distribution_new.xml req-altool.xml out-altool.xml + +echo "All done." diff --git a/scripts/zfs-tests.sh b/scripts/zfs-tests.sh index 179e24d7a0ef..6d99c8e73d4d 100755 --- a/scripts/zfs-tests.sh +++ b/scripts/zfs-tests.sh @@ -57,6 +57,10 @@ if [ "$UNAME" = "FreeBSD" ] ; then TESTFAIL_CALLBACKS=${TESTFAIL_CALLBACKS:-"$ZFS_DMESG"} LOSETUP=/sbin/mdconfig DMSETUP=/sbin/gpart +elif [ "$UNAME" = "Darwin" ] ; then + TESTFAIL_CALLBACKS=${TESTFAIL_CALLBACKS:-"$ZFS_DMESG"} + LOSETUP=/usr/bin/hdiutil + DMSETUP=/sbin/something2 else ZFS_MMP="$STF_SUITE/callbacks/zfs_mmp.ksh" TESTFAIL_CALLBACKS=${TESTFAIL_CALLBACKS:-"$ZFS_DBGMSG:$ZFS_DMESG:$ZFS_MMP"} @@ -91,6 +95,16 @@ cleanup_freebsd_loopback() { done } +cleanup_macos_loopback() { + for TEST_LOOPBACK in ${LOOPBACKS}; do + sudo "$ZPOOL" export -a + if [ -b "${TEST_LOOPBACK}" ]; then + sudo "${LOSETUP}" detach "${TEST_LOOPBACK}" || + echo "Failed to destroy: ${TEST_LOOPBACK}" + fi + done +} + cleanup_linux_loopback() { for TEST_LOOPBACK in ${LOOPBACKS}; do LOOP_DEV="${TEST_LOOPBACK##*/}" @@ -123,6 +137,8 @@ cleanup() { if [ "$LOOPBACK" = "yes" ]; then if [ "$UNAME" = "FreeBSD" ] ; then cleanup_freebsd_loopback + elif [ "$UNAME" = "Darwin" ] ; then + cleanup_macos_loopback else cleanup_linux_loopback fi @@ -147,6 +163,8 @@ cleanup_all() { TEST_POOLS=$(ASAN_OPTIONS=detect_leaks=false "$ZPOOL" list -Ho name | grep testpool) if [ "$UNAME" = "FreeBSD" ] ; then TEST_LOOPBACKS=$(sudo "${LOSETUP}" -l) + elif [ "$UNAME" = "Darwin" ] ; then + TEST_LOOPBACKS=$(sudo "${LOSETUP}" info|grep /dev/disk) else TEST_LOOPBACKS=$("${LOSETUP}" -a | awk -F: '/file-vdev/ {print $1}') fi @@ -171,6 +189,8 @@ cleanup_all() { for TEST_LOOPBACK in $TEST_LOOPBACKS; do if [ "$UNAME" = "FreeBSD" ] ; then sudo "${LOSETUP}" -d -u "${TEST_LOOPBACK}" + elif [ "$UNAME" = "Darwin" ] ; then + sudo "${LOSETUP}" detach "${TEST_LOOPBACK}" else sudo "${LOSETUP}" -d "${TEST_LOOPBACK}" fi @@ -282,6 +302,8 @@ constrain_path() { SYSTEM_FILES="$SYSTEM_FILES_COMMON" if [ "$UNAME" = "FreeBSD" ] ; then SYSTEM_FILES="$SYSTEM_FILES $SYSTEM_FILES_FREEBSD" + elif [ "$UNAME" = "Darwin" ] ; then + SYSTEM_FILES="$SYSTEM_FILES $SYSTEM_FILES_MACOS" else SYSTEM_FILES="$SYSTEM_FILES $SYSTEM_FILES_LINUX" fi @@ -295,6 +317,20 @@ constrain_path() { ln -fs "$STF_PATH/gunzip" "$STF_PATH/uncompress" elif [ "$UNAME" = "FreeBSD" ] ; then ln -fs /usr/local/bin/ksh93 "$STF_PATH/ksh" + elif [ "$UNAME" = "Darwin" ] ; then + [ -f "/usr/local/bin/gdd" ] && ln -fs /usr/local/bin/gdd "$STF_PATH/dd" + [ -f "/usr/local/bin/gsed" ] && ln -fs /usr/local/bin/gsed "$STF_PATH/gsed" + ln -fs /bin/ksh "$STF_PATH/ksh" + ln -fs /sbin/fsck_hfs "$STF_PATH/fsck" + ln -fs /sbin/newfs_hfs "$STF_PATH/newfs_hfs" + ln -fs /sbin/mount_hfs "$STF_PATH/mount" + ln -fs /usr/local/bin/gtruncate "$STF_PATH/truncate" + ln -fs /usr/sbin/sysctl "$STF_PATH/sysctl" + ln -fs /usr/bin/dscl "$STF_PATH/dscl" + ln -fs /usr/bin/xxd "$STF_PATH/xxd" + ln -fs /usr/sbin/dseditgroup "$STF_PATH/dseditgroup" + ln -fs /usr/bin/xattr "$STF_PATH/xattr" + ln -fs /usr/sbin/createhomedir "$STF_PATH/createhomedir" fi } @@ -521,6 +557,17 @@ fi [ -e "$STF_SUITE/include/default.cfg" ] || fail \ "Missing $STF_SUITE/include/default.cfg file." +if [ "$UNAME" = "Darwin" ]; then + DYLD_LIBRARY_PATH=$STF_SUITE/cmd/librt/.libs:$DYLD_LIBRARY_PATH + export DYLD_LIBRARY_PATH + # Tell ZFS to not to use /Volumes + __ZFS_MAIN_MOUNTPOINT_DIR=/ + export __ZFS_MAIN_MOUNTPOINT_DIR + # Catalina and up has root as read/only. + # BigSur gets even harder. + sudo /sbin/mount -uw / + export SHELL=ksh +fi # # Verify the ZFS module stack is loaded. # @@ -579,8 +626,15 @@ if [ -z "${DISKS}" ]; then # for TEST_FILE in ${FILES}; do [ -f "$TEST_FILE" ] && fail "Failed file exists: ${TEST_FILE}" - truncate -s "${FILESIZE}" "${TEST_FILE}" || + + if [ "$UNAME" = "Darwin" ] ; then + mkfile -n "${FILESIZE}" "${TEST_FILE}" || fail "Failed creating: ${TEST_FILE} ($?)" + else + truncate -s "${FILESIZE}" "${TEST_FILE}" || + fail "Failed creating: ${TEST_FILE} ($?)" + fi + done # @@ -597,6 +651,21 @@ if [ -z "${DISKS}" ]; then fi DISKS="$DISKS $MDDEVICE" LOOPBACKS="$LOOPBACKS $MDDEVICE" + elif [ "$UNAME" = "Darwin" ] ; then + MDDEVICE=$(sudo "${LOSETUP}" attach -imagekey diskimage-class=CRawDiskImage -nomount "${TEST_FILE}") + if [ -z "$MDDEVICE" ] ; then + fail "Failed: ${TEST_FILE} -> loopback" + fi + LOOPBACKS="${LOOPBACKS}${MDDEVICE} " + BASEMDDEVICE=$(basename "$MDDEVICE") + if [ -z "$DISKS" ]; then + DISKS="$BASEMDDEVICE" + else + DISKS="$DISKS $BASEMDDEVICE" + fi + # If we use attached disk, remove the file-vdev + # from list. + DISKS=${DISKS:-"$TEST_FILE"} else TEST_LOOPBACK=$(sudo "${LOSETUP}" --show -f "${TEST_FILE}") || fail "Failed: ${TEST_FILE} -> ${TEST_LOOPBACK}" @@ -621,6 +690,8 @@ if [ "$TAGS" != "perf" ]; then [ "$NUM_DISKS" -lt 3 ] && fail "Not enough disks ($NUM_DISKS/3 minimum)" fi +echo "Finished with DISKS $DISKS" + # # Disable SELinux until the ZFS Test Suite has been updated accordingly. # @@ -667,6 +738,8 @@ export TESTFAIL_CALLBACKS mktemp_file() { if [ "$UNAME" = "FreeBSD" ]; then mktemp -u "${FILEDIR}/$1.XXXXXX" + elif [ "$UNAME" = "Darwin" ]; then + mktemp -u "${FILEDIR}/$1.XXXXXX" else mktemp -ut "$1.XXXXXX" -p "$FILEDIR" fi