@ -130,8 +130,9 @@ auto_partition() {
find_partitions( ) {
PARTITIONS = ""
NUMBER_PARTITIONS = 0
# get the list of partitions and also include the zvols since it is common to mount filesystems directly on them. It should be safe to include them here since they present as block devices.
partition_list = $( lsblk -lno NAME,SIZE,TYPE | grep $INCLUDE_PART | sed 's/part$/\/dev\//g' | sed 's/lvm$\|crypt$/\/dev\/mapper\//g' | \
awk '{print $3$1 " " $2}' | awk '!/mapper/{a[++i]=$0;next}1;END{while(x<length(a))print a[++x]}' )
awk '{print $3$1 " " $2}' | awk '!/mapper/{a[++i]=$0;next}1;END{while(x<length(a))print a[++x]}' ; zfs list -Ht volume -o name,volsize 2>/dev/null | awk '{printf "/dev/zvol/%s %s\n", $1, $2}' )
for i in ${ partition_list } ; do
PARTITIONS = " ${ PARTITIONS } ${ i } "
@ -235,6 +236,9 @@ select_filesystem() {
fs_opts = ""
CHK_NUM = 0
# zfs legacy filesystems can't be formatted, always have a zfs filesystem and store their mount options in metadata
[ [ $( zfs_list_datasets legacy | grep " ^ ${ PARTITION } $" ) ] ] && return
DIALOG " $_FSTitle " --menu " \n $_FSBody \n " 0 0 10 \
" $_FSSkip " "-" \
"btrfs" "mkfs.btrfs -f" \
@ -356,8 +360,11 @@ mount_current_partition() {
# Get mounting options for appropriate filesystems
[ [ $fs_opts != "" ] ] && mount_opts
# Use special mounting options if selected, else standard mount
if [ [ $( cat ${ MOUNT_OPTS } ) != "" ] ] ; then
# Check for zfs, use special mounting options if selected, else standard mount
if [ [ $( zfs_list_datasets legacy | grep " ^ ${ PARTITION } $" ) ] ] ; then
check_for_error " mount ${ PARTITION } "
mount -t zfs ${ PARTITION } ${ MOUNTPOINT } ${ MOUNT } 2>>$LOGFILE
elif [ [ $( cat ${ MOUNT_OPTS } ) != "" ] ] ; then
check_for_error " mount ${ PARTITION } $( cat ${ MOUNT_OPTS } ) "
mount -o $( cat ${ MOUNT_OPTS } ) ${ PARTITION } ${ MOUNTPOINT } ${ MOUNT } 2>>$LOGFILE
else
@ -882,10 +889,23 @@ lvm_del_all() {
}
# returns a list of devices containing zfs members
list_zfs _devs( ) {
zfs_ list_devs( ) {
zpool status -PL 2>/dev/null | awk '{print $1}' | grep "^/"
}
zfs_list_datasets( ) {
case $1 in
"zvol" )
zfs list -Ht volume -o name,volsize 2>/dev/null
; ;
"legacy" )
zfs list -Ht filesystem -o name,mountpoint 2>/dev/null | grep " ^.*/.*legacy $" | awk '{print $1}'
; ;
*)
zfs list -H -o name 2>/dev/null | grep "/"
esac
}
# creates a new zpool on an existing partition
zfs_create_zpool( ) {
# LVM Detection. If detected, activate.
@ -896,6 +916,7 @@ zfs_create_zpool() {
find_partitions
list_mounted > /tmp/.ignore_part
zfs_list_devs >> /tmp/.ignore_part
list_containing_crypt >> /tmp/.ignore_part
check_for_error " ignore crypted: $( list_containing_crypt) "
@ -908,7 +929,7 @@ zfs_create_zpool() {
PARTITION = $( cat ${ ANSWER } )
# We need to get a name for the zpool
declare -i loopmenu = 1
local -i loopmenu = 1
ZFSMENUTEXT = $_zfsZpoolCBody
while ( ( loopmenu) ) ; do
DIALOG " $_zfsZpoolCTitle " --inputbox " \n $ZFSMENUTEXT \n " 0 0 "zpmanjaro" 2>${ ANSWER } || return 1
@ -941,11 +962,11 @@ zfs_create_zpool() {
# Creates a zfs filesystem, the first parameter is the ZFS path and the second is the mount path
zfs_create_dataset( ) {
local ZPATH= $ZFS_ZPOOL_NAME / $1
local ZMOUNT = $2
local zpath= $1
local zmount = $2
zfs create -o mountpoint = $ ZMOUNT $ZPATH 2>$ERR
check_for_error " Creating zfs dataset ${ ZPATH} with mountpoint ${ ZMOUNT } "
zfs create -o mountpoint = $ zmount $zpath 2>$ERR
check_for_error " Creating zfs dataset ${ zpath} with mountpoint ${ zmount } "
}
# Automated configuration of zfs. Creates a new zpool and a default set of filesystems
@ -959,12 +980,12 @@ zfs_auto() {
fi
# next create the datasets including their parents
zfs_create_dataset " data" "none"
zfs_create_dataset " ROOT" "none"
zfs_create_dataset " ROOT/manjaro" "none"
zfs_create_dataset " ROOT/manjaro/root" "/"
zfs_create_dataset " data/home" "/home"
zfs_create_dataset " ROOT/manjaro/paccache" "/var/cache/pacman"
zfs_create_dataset " ${ ZFS_ZPOOL_NAME } / data " "none"
zfs_create_dataset " ${ ZFS_ZPOOL_NAME } / ROOT " "none"
zfs_create_dataset " ${ ZFS_ZPOOL_NAME } / ROOT/manjaro " "none"
zfs_create_dataset " ${ ZFS_ZPOOL_NAME } / ROOT/manjaro/root " "/"
zfs_create_dataset " ${ ZFS_ZPOOL_NAME } / data/home " "/home"
zfs_create_dataset " ${ ZFS_ZPOOL_NAME } / ROOT/manjaro/paccache " "/var/cache/pacman"
# set the rootfs
zpool set bootfs = ${ ZFS_ZPOOL_NAME } /ROOT/manjaro/root ${ ZFS_ZPOOL_NAME } 2>$ERR
@ -973,11 +994,131 @@ zfs_auto() {
# provide confirmation to the user
DIALOG " $_zfsZpoolCTitle " --infobox " \n $_zfsAutoComplete \n " 0 0
sleep 3
}
zfs_import_pool( ) {
local zplist
local zpoolitem
for zpoolitem in $( zpool import 2>/dev/null | grep "^[[:space:]]*pool" | awk -F : '{print $2}' | awk '{$1=$1};1' ) ; do
zplist = " ${ zplist } ${ zpoolitem } - "
done
if [ [ ${ zplist } ] ] ; then
DIALOG " $_zfsZpoolImportMenuTitle " --menu " \n $_zfsZpoolImportMenuBody \n " 0 0 12 ${ zplist } 2>${ ANSWER } || return 0
zpool import -R ${ MOUNTPOINT } $( cat ${ ANSWER } ) 2>$ERR
check_for_error " Import zpool $( cat ${ ANSWER } ) "
ZFS = 1
else
DIALOG " $_zfsZpoolImportMenuTitle " --infobox " \n $_zfsZpoolNoPool \n " 0 0
sleep 3
fi
}
# return a list of imported zpools
zfs_list_pools( ) {
zpool list -H 2>/dev/null | awk '{print $1}'
}
zfs_new_ds( ) {
local zplist
local zmount = $1
local zpoolitem
for zpoolitem in ` zfs_list_pools` ; do
zplist = " ${ zplist } ${ zpoolitem } - "
done
if [ [ ${ zplist } ] ] ; then
# select a zpool
DIALOG " $_zfsSelectZpoolMenuTitle " --menu " \n $_zfsSelectZpoolMenuBody \n " 0 0 12 ${ zplist } 2>${ ANSWER } || return 0
local zpool = $( cat ${ ANSWER } )
else
# no imported zpools
DIALOG " $_zfsSelectZpoolMenuTitle " --infobox " \n $_zfsZpoolNoPool \n " 0 0
return 0
fi
# enter a name for the dataset
local -i loopmenu = 1
local zfsmenubody = $_zfsDSMenuNameBody
while ( ( loopmenu) ) ; do
DIALOG " $_zfsDSMenuNameTitle " --inputbox " \n $zfsmenubody \n " 0 0 "" 2>${ ANSWER } || return 1
# validation
[ [ ! $( cat ${ ANSWER } ) = ~ ^[ a-zA-Z] [ a-zA-Z0-9.:_-] *$ ] ] && zfsmenubody = $_zfsZpoolCValidation1 || loopmenu = 0
done
local zname = $( cat ${ ANSWER } )
case $zmount in
"legacy" )
zfs_create_dataset ${ zpool } /${ zname } ${ zmount } 2>$ERR
; ;
"zvol" )
# get the size of the zvol
loopmenu = 1
zfsmenubody = $_zfsZvolSizeMenuBody
while ( ( loopmenu) ) ; do
DIALOG " $_zfsZvolSizeMenuTitle " --inputbox " \n $zfsmenubody \n " 0 0 "" 2>${ ANSWER } || return 1
# validation
[ [ $( cat ${ ANSWER } ) = ~ ^[ 0-9] *$ ] ] && loopmenu = 0 || zfsmenubody = $_zfsZvolSizeMenuValidation
done
local zsize = $( cat ${ ANSWER } )
zfs create -V ${ zsize } M ${ zpool } /${ zname } 2>$ERR
; ;
*)
# select a mount point
loopmenu = 1
zfsmenubody = $_zfsMountMenuBody
while ( ( loopmenu) ) ; do
DIALOG " $_zfsMountMenuTitle " --inputbox " \n $zfsmenubody \n " 0 0 "" 2>${ ANSWER } || return 0
zmount = $( cat ${ ANSWER } )
zfsmenubody = $_zfsMountMenuBody
# validation
[ [ $( findmnt -n ${ MOUNTPOINT } /${ zmount } ) ] ] && zfsmenubody = $_zfsMountMenuInUse
[ [ ! $zmount = ~ ^/ ] ] && zfsmenubody = $_zfsMountMenuNotValid
[ [ $zfsmenubody = = $_zfsMountMenuBody ] ] && loopmenu = 0
done
zfs_create_dataset ${ zpool } /${ zname } ${ zmount } 2>$ERR
; ;
esac
check_for_error " new zfs dataset ${ zpool } / ${ zname } on ${ zmount } "
}
zfs_destroy_dataset( ) {
local zlist
# get dataset list and format for the menu
local zds
for zds in $( zfs_list_datasets) ; do
zlist = " ${ zlist } ${ zds } - "
done
# select the dataset to destroy
if [ [ ${ zlist } ] ] ; then
DIALOG " $_zfsDestroyMenuTitle " --menu " \n $_zfsDestroyMenuBody \n " 0 0 12 ${ zlist } 2>${ ANSWER } || return 0
local zdataset = $( cat ${ ANSWER } )
else
# no available datasets
DIALOG " $_zfsDestroyMenuTitle " --infobox " \n $_zfsDatasetNotFound \n " 0 0
return 0
fi
# better confirm this one
DIALOG --defaultno --yesno " $_zfsDestroyMenuConfirm1 ${ zdataset } $_zfsDestroyMenuConfirm2 " 0 0
if [ $? ] ; then
zfs destroy -r ${ zdataset }
check_for_error " zfs destroy ${ zdataset } "
fi
}
zfs_menu_manual( ) {
declare -i loopmenu = 1
local -i loopmenu = 1
while ( ( loopmenu) ) ; do
DIALOG " $_zfsManualMenuTitle " --menu " \n $_zfsManualMenuBody \n " 22 60 7 \
" $_zfsManualMenuOptCreate " "" \
@ -991,15 +1132,15 @@ zfs_menu_manual() {
case $( cat ${ ANSWER } ) in
" $_zfsManualMenuOptCreate " ) zfs_create_zpool
; ;
" $_zfsManualMenuOptImport " ) return 0
" $_zfsManualMenuOptImport " ) zfs_import_pool
; ;
" $_zfsManualMenuOptNewFile " ) return 0
" $_zfsManualMenuOptNewFile " ) zfs_new_ds
; ;
" $_zfsManualMenuOptNewLegacy " ) return 0
" $_zfsManualMenuOptNewLegacy " ) zfs_new_ds "legacy"
; ;
" $_zfsManualMenuOptNewZvol " ) return 0
" $_zfsManualMenuOptNewZvol " ) zfs_new_ds "zvol"
; ;
" $_zfsManualMenuOptDestroy " ) return 0
" $_zfsManualMenuOptDestroy " ) zfs_destroy_dataset
; ;
*) loopmenu = 0
return 0
@ -1096,9 +1237,16 @@ mount_partitions() {
# Get list of available partitions
find_partitions
# Add legacy zfs filesystems to the list - these can be mounted but not formatted
for i in $( zfs_list_datasets "legacy" ) ; do
PARTITIONS = " ${ PARTITIONS } ${ i } "
PARTITIONS = " ${ PARTITIONS } zfs "
NUMBER_PARTITIONS = $(( NUMBER_PARTITIONS + 1 ))
done
# Filter out partitions that have already been mounted and partitions that just contain crypt or zfs devices
list_mounted > /tmp/.ignore_part
list_zfs_devs >> /tmp/.ignore_part
zfs_ list_devs >> /tmp/.ignore_part
list_containing_crypt >> /tmp/.ignore_part
check_for_error " ignore crypted: $( list_containing_crypt) "
@ -1106,7 +1254,7 @@ mount_partitions() {
delete_partition_in_list $part
done
# check to see if we already have a zfs root device mounted
# check to see if we already have a zfs root mounted
if [ $( findmnt -ln -o FSTYPE ${ MOUNTPOINT } ) = = "zfs" ] ; then
DIALOG " $_PrepMntPart " --infobox " \n $_zfsFoundRoot \n " 0 0
sleep 3
@ -1141,9 +1289,27 @@ mount_partitions() {
fi
fi
# We need to remove legacy zfs partitions before make_swap since they can't hold swap
local zlegacy
for zlegacy in $( zfs_list_datasets "legacy" ) ; do
delete_partition_in_list ${ zlegacy }
done
# Identify and create swap, if applicable
make_swap
# Now that swap is done we put the legacy partitions back, unless they are already mounted
for i in $( zfs_list_datasets "legacy" ) ; do
PARTITIONS = " ${ PARTITIONS } ${ i } "
PARTITIONS = " ${ PARTITIONS } zfs "
NUMBER_PARTITIONS = $(( NUMBER_PARTITIONS + 1 ))
done
for part in $( list_mounted) ; do
delete_partition_in_list $part
done
# All other partitions
while [ [ $NUMBER_PARTITIONS > 0 ] ] ; do
DIALOG " $_PrepMntPart " --menu " \n $_ExtPartBody \n " 0 0 12 " $_Done " $"-" ${ PARTITIONS } 2>${ ANSWER } || return 0