nvme-setup.sh 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #!/bin/bash
  2. #
  3. # Assumptions:
  4. #
  5. # 1] we're on aws
  6. # 2] any ephemeral devices are ours to take
  7. # 3] if no ephemeral devices are available then there's a list
  8. # of hard-coded block devices to use for the splunk hot VG
  9. #
  10. #--------------------------------------------------------------------
  11. exec > /dev/console
  12. exec 2>&1
  13. HOT_VG_NAME="vg_splunkhot"
  14. HOT_LV_NAME="lv_splunkhot"
  15. # These are the *HARD-CODED* volumes that we will use when no
  16. # ephemeral disks are available
  17. HOT_EBS_VOLUMES="xvdg xvdh"
  18. IMDS2_TOKEN=$( curl --silent --fail -X PUT --connect-timeout 1 --max-time 2 'http://169.254.169.254/latest/api/token' -H 'X-aws-ec2-metadata-token-ttl-seconds: 90' )
  19. CURL="curl -f --connect-timeout 1 -silent"
  20. declare -A EBSMAP
  21. # Yes heavy assumption we're on AWS
  22. INSTANCE_TYPE="`${CURL} -H X-aws-ec2-metadata-token:\ ${IMDS2_TOKEN} http://169.254.169.254/latest/meta-data/instance-type`"
  23. if [[ "$INSTANCE_TYPE" == "" ]]; then
  24. echo "Could not figure out instance type, giving up"
  25. exit 1
  26. fi
  27. # Build a map of EBS NVMe disks from their AWS-API-name to their NVMe name
  28. # this makes an associative array (like a python hash) of the
  29. # sdX/xvdX name you'd set in AWS API to the corresponding nvmeX name
  30. # Thanks Fred for the awesome id-ctrl stuff I'd never seen before
  31. #
  32. # One interesting side effect observed: the id-ctrl output is different when
  33. # volumes are attached at boot time (no /dev/) versus attached after the OS
  34. # is started (includes /dev/)
  35. function make_nve_ebs_map {
  36. for DEVICE in $( lsblk -d -o NAME,MODEL -n | egrep "Elastic Block Store" | awk '{ print $1 }' ); do
  37. UNDERLYING=$( nvme id-ctrl --raw-binary /dev/${DEVICE} 2>/dev/null | cut -c 3073-3104 | tr -d ' ' | sed "s#/dev/##" )
  38. EBSMAP[$UNDERLYING]=$DEVICE
  39. UNDERLYING2=$( echo $UNDERLYING | sed "s/sd/xvd/" )
  40. EBSMAP[$UNDERLYING2]=$DEVICE
  41. done
  42. }
  43. DEVS=""
  44. # Look for ephemeral NVMe disks
  45. EPHEMERAL_DISKS=$( lsblk -d -o NAME,SIZE,TYPE,MODEL,SERIAL | egrep "Amazon EC2 NVMe Instance Storage" | awk '{ print "/dev/"$1 }' )
  46. if [[ "${EPHEMERAL_DISKS}" != "" ]]; then
  47. # We have some ephemeral disks lets use them
  48. # This is the happy path
  49. DEVS="${EPHEMERAL_DISKS}"
  50. else
  51. # Looking for the hard-coded volumes above to come attached. They
  52. # could be attached immediately, or it could take a "couple of minutes"
  53. # as they are created and attached by terraform.
  54. # Checking for both the normal attachment and the NVMe form
  55. for VOLUME in $HOT_EBS_VOLUMES; do
  56. DONE=0
  57. TRIES=0
  58. while [[ $DONE -ne 1 ]] && [[ $TRIES -lt 20 ]]; do
  59. echo "Looking for $VOLUME to come attached"
  60. make_nve_ebs_map
  61. #echo "------- current nvme/ebs map -------"
  62. #for K in "${!EBSMAP[@]}"; do echo $K = ${EBSMAP[$K]} ; done
  63. #echo "------- end current nvme/ebs map -------"
  64. if [[ -b /dev/$VOLUME ]]; then
  65. DEVS="/dev/$VOLUME $DEVS"
  66. DONE=1
  67. elif [[ -b /dev/${EBSMAP[$VOLUME]} ]]; then
  68. DEVS="/dev/${EBSMAP[$VOLUME]} $DEVS"
  69. DONE=1
  70. else
  71. sleep 10
  72. TRIES=$(( $TRIES + 1 ))
  73. fi
  74. done
  75. done
  76. fi
  77. if [[ "$DEVS" == "" ]]; then
  78. echo "Failed to enumerate possible devices, oops"
  79. exit 1
  80. fi
  81. DEVCOUNT=`echo $DEVS | wc -w`
  82. # See if the volume group already exists - if not let's make it
  83. if ! vgs --noheadings ${HOT_VG_NAME} >/dev/null 2>&1; then
  84. echo "Making VG on devices ${DEVS}"
  85. vgcreate ${HOT_VG_NAME} ${DEVS}
  86. fi
  87. # See if the logical volume already exists - if not make it
  88. # and also make the filesystem
  89. if ! lvs --noheadings ${HOT_VG_NAME}/${HOT_LV_NAME} >/dev/null 2>&1; then
  90. echo "Making LV"
  91. lvcreate -l 100%FREE --stripes $DEVCOUNT --name ${HOT_LV_NAME} ${HOT_VG_NAME}
  92. mkfs -t ext4 /dev/${HOT_VG_NAME}/${HOT_LV_NAME}
  93. fi
  94. if ! egrep -q "/dev/${HOT_VG_NAME}/${HOT_LV_NAME}" /etc/fstab; then
  95. echo "Adding to fstab"
  96. echo "/dev/vg_splunkhot/lv_splunkhot /opt/splunkdata/hot ext4 nofail,noatime 0 0" >> /etc/fstab
  97. fi
  98. if [[ ! -d /opt/splunkdata/hot ]]; then
  99. echo "Creating mount directories"
  100. mkdir -p /opt/splunkdata/hot
  101. fi
  102. if ! mountpoint /opt/splunkdata/hot >/dev/null 2>&1; then
  103. echo "Mounting it"
  104. mount /opt/splunkdata/hot
  105. fi
  106. # Looking for splunk user, trying to fix up ownerships in case they got lost
  107. # This commonly happens when an ephemeral storage box loses its ephemeral storage
  108. # but everything else survives
  109. if getent passwd splunk | egrep -q splunk; then
  110. echo "Changing ownership of /opt/splunkdata and /opt/splunkdata/hot"
  111. chown splunk:splunk /opt/splunkdata
  112. chown splunk:splunk /opt/splunkdata/hot
  113. fi