|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +make_fs () { |
| 4 | + # If file system = to ext4 use mkfs.ext4, if xfs use mkfs.xfs |
| 5 | + if [ -z "$1" ]; then |
| 6 | + echo "Error: No file system type provided." |
| 7 | + echo "Usage: make_fs <file system type [ xfs | ext4 ]> <target_volume_id>" |
| 8 | + exit 1 |
| 9 | + fi |
| 10 | + |
| 11 | + if [ -z "$2" ]; then |
| 12 | + echo "Error: No target volume ID provided." |
| 13 | + echo "Usage: make_fs <file system type [ xfs | ext4 ]> <target_volume_id>" |
| 14 | + exit 1 |
| 15 | + fi |
| 16 | + |
| 17 | + local file_system=$1 |
| 18 | + local volume_id=$2 |
| 19 | + if [ "$file_system" == "ext4" ]; then |
| 20 | + mkfs -t ext4 "$volume_id" |
| 21 | + return "$?" |
| 22 | + else |
| 23 | + mkfs.xfs -f "$volume_id" |
| 24 | + return "$?" |
| 25 | + fi |
| 26 | +} |
| 27 | + |
| 28 | +# We need an nvme disk that is not mounted and not partitioned |
| 29 | +get_all_empty_nvme_disks () { |
| 30 | + local all_not_mounted_nvme_disks |
| 31 | + local all_mounted_nvme_partitions |
| 32 | + local unmounted_nvme_disks=() |
| 33 | + local sorted_unmounted_nvme_disks |
| 34 | + |
| 35 | + #The disk will only be mounted when the nvme disk is larger than 100GB to avoid storing blockchain node data directly on the root EBS disk (which is 46GB by default) |
| 36 | + all_not_mounted_nvme_disks=$(lsblk -lnb | awk '{if ($7 == "" && $4 > 100000000) {print $1}}' | grep nvme) |
| 37 | + all_mounted_nvme_partitions=$(mount | awk '{print $1}' | grep /dev/nvme) |
| 38 | + for disk in ${all_not_mounted_nvme_disks[*]}; do |
| 39 | + if [[ ! "${all_mounted_nvme_partitions[*]}" =~ $disk ]]; then |
| 40 | + unmounted_nvme_disks+=("$disk") |
| 41 | + fi |
| 42 | + done |
| 43 | + # Sort the array |
| 44 | + sorted_unmounted_nvme_disks=($(printf '%s\n' "${unmounted_nvme_disks[*]}" | sort)) |
| 45 | + echo "${sorted_unmounted_nvme_disks[*]}" |
| 46 | +} |
| 47 | + |
| 48 | +get_next_empty_nvme_disk () { |
| 49 | + local sorted_unmounted_nvme_disks |
| 50 | + sorted_unmounted_nvme_disks=($(get_all_empty_nvme_disks)) |
| 51 | + # Return the first unmounted nvme disk |
| 52 | + echo "/dev/${sorted_unmounted_nvme_disks[0]}" |
| 53 | +} |
| 54 | + |
| 55 | +# Add input as command line parameters for name of the directory to mount |
| 56 | +if [ -n "$1" ]; then |
| 57 | + DIR_NAME=$1 |
| 58 | +else |
| 59 | + echo "Error: No data file system mount path is provided." |
| 60 | + echo "Usage: instance/storage/setup.sh <file_system_mount_path> <file_system_type [ xfs | ext4 ]> <target_volume_size_in_bytes> " |
| 61 | + echo "Default file system type is ext4" |
| 62 | + echo "If you skip <target_volume_size_in_bytes>, script will try to use the first unformatted volume ID." |
| 63 | + echo "Usage example: instance/storage/setup.sh /data ext4 300000000000000" |
| 64 | + exit 1 |
| 65 | +fi |
| 66 | + |
| 67 | +# Case input for $2 between ext4 and xfs, use ext4 as default |
| 68 | +case $2 in |
| 69 | + ext4) |
| 70 | + echo "File system set to ext4" |
| 71 | + FILE_SYSTEM="ext4" |
| 72 | + FS_CONFIG="defaults" |
| 73 | + ;; |
| 74 | + xfs) |
| 75 | + echo "File system set to xfs" |
| 76 | + FILE_SYSTEM="xfs" |
| 77 | + FS_CONFIG="noatime,nodiratime,nodiscard" # See more: https://cdrdv2-public.intel.com/686417/rocksdb-benchmark-tuning-guide-on-xeon.pdf |
| 78 | + ;; |
| 79 | + *) |
| 80 | + echo "File system set to ext4" |
| 81 | + FILE_SYSTEM="ext4" |
| 82 | + FS_CONFIG="defaults" |
| 83 | + ;; |
| 84 | +esac |
| 85 | + |
| 86 | +if [ -n "$3" ]; then |
| 87 | + VOLUME_SIZE=$3 |
| 88 | +else |
| 89 | + echo "The size of volume for $DIR_NAME is not specified. Will try to guess volume ID." |
| 90 | +fi |
| 91 | + |
| 92 | + echo "Checking if $DIR_NAME is mounted, and dont do anything if it is" |
| 93 | + if [ $(df --output=target | grep -c "$DIR_NAME") -lt 1 ]; then |
| 94 | + |
| 95 | + if [ -n "$VOLUME_SIZE" ]; then |
| 96 | + VOLUME_ID=/dev/$(lsblk -lnb | awk -v VOLUME_SIZE_BYTES="$VOLUME_SIZE" '{if ($4== VOLUME_SIZE_BYTES) {print $1}}') |
| 97 | + echo "Data volume size defined, use respective volume id: $VOLUME_ID" |
| 98 | + else |
| 99 | + VOLUME_ID=$(get_next_empty_nvme_disk) |
| 100 | + echo "Data volume size undefined, trying volume id: $VOLUME_ID" |
| 101 | + fi |
| 102 | + |
| 103 | + make_fs $FILE_SYSTEM "$VOLUME_ID" |
| 104 | + |
| 105 | + sleep 10 |
| 106 | + VOLUME_UUID=$(lsblk -fn -o UUID "$VOLUME_ID") |
| 107 | + VOLUME_FSTAB_CONF="UUID=$VOLUME_UUID $DIR_NAME $FILE_SYSTEM $FS_CONFIG 0 2" |
| 108 | + echo "VOLUME_ID=$VOLUME_ID" |
| 109 | + echo "VOLUME_UUID=$VOLUME_UUID" |
| 110 | + echo "VOLUME_FSTAB_CONF=$VOLUME_FSTAB_CONF" |
| 111 | + |
| 112 | + # Check if data disc is already in fstab and replace the line if it is with the new disc UUID |
| 113 | + echo "Checking fstab for volume $DIR_NAME" |
| 114 | + if [ $(grep -c "$DIR_NAME" /etc/fstab) -gt 0 ]; then |
| 115 | + SED_REPLACEMENT_STRING="$(grep -n "$DIR_NAME" /etc/fstab | cut -d: -f1)s#.*#$VOLUME_FSTAB_CONF#" |
| 116 | + # if file exists, delete it |
| 117 | + if [ -f /etc/fstab.bak ]; then |
| 118 | + rm /etc/fstab.bak |
| 119 | + fi |
| 120 | + cp /etc/fstab /etc/fstab.bak |
| 121 | + sed -i "$SED_REPLACEMENT_STRING" /etc/fstab |
| 122 | + else |
| 123 | + echo "$VOLUME_FSTAB_CONF" | tee -a /etc/fstab |
| 124 | + fi |
| 125 | + |
| 126 | + mount -a |
| 127 | + chown -R bcuser:bcuser "$DIR_NAME" |
| 128 | + else |
| 129 | + echo "$DIR_NAME volume is mounted, nothing changed" |
| 130 | + fi |
0 commit comments