#!/bin/bash # License: BeeGFS EULA # constant definitions # (for configurables see below) DEFAULT_CFG_PATH="/etc/beegfs/beegfs-meta.conf" STORAGE_PATH_CFG_KEY="storeMetaDirectory" MGMTD_CFG_KEY="sysMgmtdHost" ALLOW_INIT_CFG_KEY="storeAllowFirstRunInit" FS_UUID_CFG_KEY="storeFsUUID" SERVER_NUMID_FILE="nodeNumID" FORMAT_FILENAME="format.conf" FORMAT_FILE_VERSION="4" XATTR_CFG_KEY="storeUseExtendedAttribs" print_usage() { echo echo "DESCRIPTION: Initialize metadata storage directory for beegfs-meta server daemon" echo "and update the beegfs-meta config file." echo echo "USAGE: `basename $0` -p [options]" echo echo " Mandatory Options:" echo echo " -p - Path to metadata storage directory that is to be initialized." echo " (Path will also be added to config file.)" echo echo " Recommended Options:" echo echo " -s - Assign the given numeric ID to the server of this storage" echo " directory (range 1..65535). (Default: Randomly select a free ID.)" echo echo " -m - Hostname (or IP address) of management server." echo " (Will be stored in server config file.)" echo echo " Other Options:" echo echo " -C - Do not update server config file." echo echo " -c - Path to server config file." echo " (Default: ${DEFAULT_CFG_PATH})" echo echo " -f - Force actions, ignore warnings." echo echo " -h - Print this help." echo echo " -u - Do not disable usage of uninitialized storage directory in config" echo " file and do not store the UUID of the underlying fs." echo echo " -x - Do not store metadata as extended attributes." echo echo "NOTES:" echo " * All given IDs must be unique in their service class for the whole file system" echo " instance, i.e. there can only be one beegfs-meta service with ID 2, but there" echo " can also be a beegfs-storage service with ID 2 in the file system." echo echo " * BeeGFS servers can also run without pre-initializing storage directories, if" echo " storeAllowFirstRunInit=true is set in the server config files (which is" echo " usually not recommended)." echo echo "EXAMPLES:" echo " * Numeric IDs can generally be chosen arbitrarily. However, it is usually a" echo " good idea to pick a numeric ID that matches the hostname, e.g. if the" echo " hostname is \"meta02\", you would use \"2\" as numeric ID for the beegfs-meta" echo " service on this server." echo echo " * Example 1) Initialize metadata storage directory of first metadata server and" echo " set \"storage01\" as management daemon host in config file:" echo " $ `basename $0` -p /mnt/myraid1/beegfs-meta -s 1 -m storage01" echo } # initialize storage directory (if enabled) init_storage_dir() { # check if storage path is defined if [ -z "${STORAGE_PATH}" ]; then return 0 fi # create storage path echo "Preparing storage directory: ${STORAGE_PATH}" mkdir -p "${STORAGE_PATH}" # make sure storage dir is empty if [ -z "${FORCE_ACTIONS}" ] && [ "$(ls -AI lost+found ${STORAGE_PATH} )" ]; then echo " * ERROR: Storage directory is not empty. Initialization of non-empty" \ "directories can lead to data loss or orphaned data. ('-f' disables this check.)" exit 1 fi # create format file echo " * Creating ${FORMAT_FILENAME} file..." FORMAT_FILE_PATH="${STORAGE_PATH}/${FORMAT_FILENAME}" echo "# This file was auto-generated. Do not modify it!" >> ${FORMAT_FILE_PATH} echo "version=${FORMAT_FILE_VERSION}" >> ${FORMAT_FILE_PATH} echo "xattr=${FORMAT_USE_XATTR}" >> ${FORMAT_FILE_PATH} # create ID files if [ -n "${SERVER_NUMID}" ]; then echo " * Creating server numeric ID file: ${STORAGE_PATH}/${SERVER_NUMID_FILE}" echo "${SERVER_NUMID}" > "${STORAGE_PATH}/${SERVER_NUMID_FILE}" fi } # update config file (if enabled) update_config_file() { # check if config file is defined if [ -z "${CFG_PATH}" ]; then return 0 fi echo "Updating config file: ${CFG_PATH}" if [ ! -f "${CFG_PATH}" ]; then echo " * ERROR: Config file not found: ${CFG_PATH}" exit 1 fi if [ -n "${MGMTD_HOST}" ]; then echo " * Setting management host: ${MGMTD_HOST}" sed -i "s/\(^${MGMTD_CFG_KEY}.*=\).*/\1 ${MGMTD_HOST}/" ${CFG_PATH} fi if [ -n "${STORAGE_PATH}" ]; then echo " * Setting storage directory in config file..." sed -i "s|\(^${STORAGE_PATH_CFG_KEY}.*=\).*$|\1 ${STORAGE_PATH}|" ${CFG_PATH} fi if [ -n "${DISABLE_UNINITED_TARGETS}" ] && [ -n "${STORAGE_PATH}" ]; then echo " * Disabling usage of uninitialized storage directory in config file..." sed -i "s/\(^${ALLOW_INIT_CFG_KEY}.*=\).*/\1 false/" ${CFG_PATH} echo " * Fetching the underlying device..." DEVICE=$(df "${STORAGE_PATH}" | tail -n1 | cut -d\ -f1) echo "Underlying device detected: ${DEVICE}" echo "Fetching UUID of the file system on that device..." UUID=$(blkid -s UUID ${DEVICE} | cut -d= -f2 | sed "s/\"//g") echo "Found UUID ${UUID}" echo "Writing UUID to config file..." sed -i "s|\(^${FS_UUID_CFG_KEY}.*=\).*$|\1 ${UUID}|" ${CFG_PATH} fi if [ -n "${STORAGE_PATH}" ]; then echo " * Setting usage of extended attributes to: ${FORMAT_USE_XATTR}" sed -i "s/\(^${XATTR_CFG_KEY}.*=\).*/\1 ${FORMAT_USE_XATTR}/" ${CFG_PATH} fi } ################## end of function definitions ############## # configurable values and their defaults # (for constants see above) CFG_PATH="$DEFAULT_CFG_PATH" # empty path means "don't update cfg file" FORCE_ACTIONS="" FORMAT_USE_XATTR="true" MGMTD_HOST="" SERVER_NUMID="" STORAGE_PATH="" DISABLE_UNINITED_TARGETS="1" # parse command line arguments # (see print_usage() for description of parameters) while getopts "Cc:fhm:p:S:s:ux" opt; do case $opt in C) CFG_PATH="" ;; c) CFG_PATH="$OPTARG" ;; f) FORCE_ACTIONS="1" ;; h) print_usage exit 0 ;; m) MGMTD_HOST="$OPTARG" ;; p) STORAGE_PATH="$OPTARG" ;; S) echo "WARNING: The -S flag previously used to specify a string ID been deprecated and now has no effect. Starting in BeeGFS string IDs were replaced with aliases configured using BeeGFS CTL." ;; s) SERVER_NUMID="$OPTARG" ;; u) DISABLE_UNINITED_TARGETS="" ;; x) FORMAT_USE_XATTR="false" ;; *) echo "ERROR: Invalid argument" >&2 print_usage exit 1 ;; esac done set -e # don't do anything if no arguments are provided if [ $# -eq 0 ]; then print_usage exit 1 fi # make sure storage dir is defined if [ -z "${STORAGE_PATH}" ]; then echo "ERROR: Storage directory is undefined." >&2 echo print_usage exit 1 fi # initialize storage directory init_storage_dir # update config file update_config_file echo "All done."