summaryrefslogtreecommitdiff
path: root/buildscripts/mount_drives.sh
blob: 0070d9b0abcb3c480e87f678db2a4c53ba643576 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/bin/bash
# Script used to mount /data & /log on a separate drive from root.
# This script must be invoked either by a root user or with sudo.
# Currently only supports Windows & Linux.
# See _usage_ for how this script should be invoked.

set -o errexit

# Default options
fs_type=xfs
user_group=$USER:$(id -Gn $USER | cut -f1 -d ' ')

# _usage_: Provides usage infomation
function _usage_ {
  cat << EOF
usage: $0 options
This script supports the following parameters for Windows & Linux platforms:
  -d <deviceNames>,    REQUIRED, Space separated list of devices to mount /data on,
                       i.e., "xvdb xvdc", more than one device indicates a RAID set.
                       For Windows, specify the drive letter, i.e., "d".
  -r <raidDeviceName>, REQUIRED, if more the one device is specified in <deviceNames>,
                       i.e., md0.
                       Not supported on Windows.
  -l <deviceName>,     OPTIONAL, Device name to mount /log on, i.e., "xvdd".
                       For Windows, specify the drive letter, i.e., "e".
  -t <fsType>,         File system type, defaults to '$fs_type'.
                       Not supported on Windows.
  -o <mountOptions>,   File system mount options, i.e., "-m crc=0,finobt=0".
                       Not supported on Windows.
  -u <user:group>,     User:Group to make owner of /data & /log. Defaults to '$user_group'.
EOF
}


# Parse command line options
while getopts "d:l:o:r:t:u:?" option
do
  case $option in
    d)
      data_device_names=$OPTARG
      ;;
    l)
      log_device_name=$OPTARG
      ;;
    o)
      mount_options=$OPTARG
      ;;
    r)
      data_raid_device_name=$OPTARG
        ;;
    t)
      fs_type=$OPTARG
      ;;
    u)
      user_group=$OPTARG
      ;;
    \?|*)
      _usage_
      exit 0
      ;;
  esac
done

function mount_drive {
  local root_dir=$1
  local sub_dirs=$2
  local device_names=$3
  local raid_device_name=$4
  local mount_options=$5
  local fs_type=$6
  local user_group=$7

  # Determine how many devices were specified
  local num_devices=0
  for device_name in $device_names
  do
    local devices="$devices /dev/$device_name"
    let num_devices=num_devices+1
  done

  # $OS is defined in Cygwin
  if [ "Windows_NT" = "$OS" ]; then
    if [ $num_devices -ne 1 ]; then
      echo "Must specify only one drive"
      _usage_
      exit 1
    fi

    local drive_poll_retry=0
    local drive_poll_delay=0
    local drive_retry_max=40

    local drive=$device_names
    local system_drive=c

    while true;
    do
      sleep $drive_poll_delay
      echo "Looking for drive '$drive' to mount $root_dir"
      if [ -d /cygdrive/$drive ]; then
        echo "Found drive"
        rm -rf /$root_dir
        rm -rf /cygdrive/$system_drive/$root_dir
        mkdir $drive:\\$root_dir
        cmd.exe /c mklink /J $system_drive:\\$root_dir $drive:\\$root_dir
        ln -s /cygdrive/$drive/$root_dir /$root_dir
        setfacl -s user::rwx,group::rwx,other::rwx /cygdrive/$drive/$root_dir
        for sub_dir in $sub_dirs
        do
            mkdir -p /cygdrive/$drive/$root_dir/$sub_dir
        done
        chown -R $user_group /cygdrive/$system_drive/$root_dir
        break
      fi
      let drive_poll_retry=drive_poll_retry+1
      if [ $drive_poll_retry -eq $drive_retry_max ]; then
        echo "Timed out trying to mount $root_dir drive."
        exit 1
      fi
      let drive_poll_delay=drive_poll_delay+5
    done

  elif [ $(uname | awk '{print tolower($0)}') = "linux" ]; then
    if [ $num_devices -eq 0 ]; then
      echo "Must specify atleast one device"
      _usage_
      exit 1
    elif [ $num_devices -gt 1 ]; then
      if [ -z "$raid_device_name" ]; then
        echo "Missing RAID device name"
        _usage_
        exit 1
      fi
    fi

    # Unmount the current devices, if already mounted
    umount /mnt || true
    umount $devices || true

    # Determine if we have a RAID set
    if [ ! -z "$raid_device_name" ]; then
      echo "Creating RAID set on '$raid_device_name' for devices '$devices'"
      device_name=/dev/$raid_device_name
      /sbin/udevadm control --stop-exec-queue
      yes | /sbin/mdadm --create $device_name --level=0 -c256 --raid-devices=$num_devices $devices
      /sbin/udevadm control --start-exec-queue
      /sbin/mdadm --detail --scan > /etc/mdadm.conf
      /sbin/blockdev --setra 32 $device_name
    else
      device_name="/dev/$device_names"
    fi

    # Mount the $root_dir drive(s)
    /sbin/mkfs.$fs_type $mount_options -f $device_name
    # We add an entry for the device to /etc/fstab so it is automatically mounted following a
    # machine reboot. The device is not guaranteed to be assigned the same name across restarts so
    # we use its UUID in order to identify it.
    #
    # We also specify type=$fs_type in the /etc/fstab entry because specifying type=auto on
    # Amazon Linux AMI 2018.03 leads to the drive not being mounted automatically following a
    # machine reboot.
    device_uuid=$(blkid -o value -s UUID "$device_name")
    echo "Adding entry to /etc/fstab for device '$device_name' with UUID '$device_uuid'"
    echo "UUID=$device_uuid /$root_dir $fs_type noatime 0 0" | tee -a /etc/fstab
    mkdir /$root_dir || true
    chmod 777 /$root_dir
    mount -t $fs_type "UUID=$device_uuid" /$root_dir
    for sub_dir in $sub_dirs
    do
      mkdir -p /$root_dir/$sub_dir
      chmod 1777 /$root_dir/$sub_dir
    done
    chown -R $user_group /$root_dir
  else
    echo "Unsupported OS '$(uname)'"
    exit 0
  fi
}

mount_drive data "db tmp" "$data_device_names" "$data_raid_device_name" "$mount_options" "$fs_type" "$user_group"
mount_drive log "" "$log_device_name" "" "$mount_options" "$fs_type" "$user_group"