Rename configuration and map files
[blkdevalias.git] / blkdevalias
1 #!/bin/bash
2 #
3 #  blkdevalias - manage aliases and permissions for block devices
4 #
5 #  Bryn M. Reeves <bmr@redhat.com>
6 #
7 #  Copyright (C) Red Hat, Inc. 2012
8 #
9 #  This program is free software; you can redistribute it and/or modify
10 #  it under the terms of the GNU General Public License as published by
11 #  the Free Software Foundation; either version 2 of the License, or
12 #  (at your option) any later version.
13 #
14 #  This program is distributed in the hope that it will be useful,
15 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 #  GNU General Public License for more details.
18 #
19 #  You should have received a copy of the GNU General Public License
20 #  along with this program; if not, write to the Free Software
21 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 #
23 declare -A WWIDMAP
24 declare -A NAMEMAP
25 declare -A TYPEMAP
26
27 BA_DEBUG=yes
28 BA_DEFAULT_USER="oracle"
29 BA_DEFAULT_GROUP="oracle"
30 BA_CONF_PATH="/etc/blkdevalias"
31 BA_DEV_PATH="oracleasm/disks"
32 BA_MAP_PATH="${BA_CONF_PATH}/blkdevalias.map"
33 BA_CONF="${BA_CONF_PATH}/blkdevalias.conf"
34 BA_USER="$BA_DEFAULT_USER"
35 BA_GROUP="$BA_DEFAULT_GROUP"
36 BA_LOCK="/var/lock/blkdevalias"
37 BA_SCSI_ID="/sbin/scsi_id"
38 BA_SCSI_ID_FLAGS="-g -u"
39
40 # load config
41 . $BA_CONF
42
43 _error () {
44     echo "ERROR: $@" 1>&2
45 }
46
47 _warn () {
48     echo "WARNING: $@" 1>&2
49 }
50
51 _debug () {
52     [ "$BA_DEBUG" == "yes" ] && echo "$@" 1>&2
53 }
54
55 # debug print
56 print_wwid_mapping() {
57     local WWID=$1
58     if [ "$WWID" == "" ]; then
59         return
60     fi
61     _debug "ALIAS for WWID '$WWID' is: '${WWIDMAP[$WWID]}' (${TYPEMAP[$WWID]})"
62 }
63
64 # store the WWID map to disk
65 ba_store_wwid_map() {
66     TMP_MAP=$(mktemp --tmpdir=$BA_CONF_DIR)
67     if [ ! -f "$TMP_MAP" ]; then
68         _error "could not write temporary file"
69         exit 1
70     fi
71     for WWID in ${!WWIDMAP[@]}; do
72         echo "$WWID ${WWIDMAP[$WWID]} ${TYPEMAP[$WWID]}"
73     done  >> $TMP_MAP
74     mv $TMP_MAP $BA_MAP_PATH
75 }
76
77 # read the WWID map from disk
78 ba_load_wwid_map() {
79     if [ ! -f "$BA_MAP_PATH" ] || [ ! -r "$BA_MAP_PATH"  ]; then
80         _error "$BA_MAP_PATH does not exist or is not readable"
81         exit 1
82     fi
83     while read WWID ALIAS TYPE; do
84         if [[ $WWID == \#* ]] || [[ $WWID == "" ]]; then
85             continue
86         fi
87         WWIDMAP[$WWID]="$ALIAS"
88         NAMEMAP[$ALIAS]="$WWID"
89         TYPEMAP[$WWID]="$TYPE"
90     done < $BA_MAP_PATH
91 }
92
93 # ba_add_wwid_mapping <wwid> <alias> <sd|mpath>
94 ba_add_wwid_mapping() {
95     local WWID
96     WWID="$1"
97     ALIAS="$2"
98     TYPE="$3"
99     _debug "ba_add_wwid_mapping WWID=\"$WWID\" ALIAS=\"$ALIAS\""
100     if [ "$WWID" == "" ]; then
101         _warn "no wwid given"
102         return
103     fi
104     if [ "$ALIAS" == "" ]; then
105         _warn "no alias given"
106         return
107     fi
108     if [ "${NAMEMAP[$WWID]}" != "" ]; then
109         _warn "$WWID already mapped to alias ${NAMEMAP[$WWID]}; replacing it."
110     fi
111     WWIDMAP[$WWID]="$ALIAS"
112     NAMEMAP[$ALIAS]="$WWID"
113     TYPEMAP[$WWID]=${TYPE:-"sd"}
114 }
115
116 # ba_del_wwid_mapping <wwid>
117 ba_del_wwid_mapping() {
118     local WWID ALIAS
119     WWID="$1"
120     if [ "$WWID" == "" ]; then
121         return 1
122     fi
123     if [ "${WWIDMAP[$WWID]}" == "" ]; then
124         _warn "WARNING: $WWID does not exist; doing nothing."
125         return 1
126     fi
127     ALIAS=${WWIDMAP[$WWID]}
128     unset WWIDMAP[$WWID]
129     unset NAMEMAP[$ALIAS]
130     unset TYPEMAP[$WWID]
131 }
132
133 ba_scsi_id () {
134     local DEV=$1
135     _debug "ba_scsi_id: getting ID for device $DEV"
136     dmsetup info $DEV > /dev/null  2>&1
137     if [ $? -eq 0 ]; then
138         DEV=$(echo $DEV | sed 's/p[0-9].*//')
139     else
140         DEV=$(echo $DEV | sed 's/[0-9].*//')
141     fi
142     _debug "ba_scsi_id: calling \"$BA_SCSI_ID $BA_SCSI_ID_FLAGS $DEV\""
143     $BA_SCSI_ID $BA_SCSI_ID_FLAGS $DEV
144 }
145
146 ba_configure () {
147     cat <<EOF
148 Configuring the blkdevalias map.
149
150 This will configure persistent aliases and permissions for storage
151 devices. The current values will be shown in brackets ('[]'). Hitting
152 <ENTER> without typing an answer will keep the current value.
153
154 Ctrl-C will abort.
155
156 EOF
157
158     echo -n "Default user to own device nodes [$BA_USER]: "
159     read _BA_USER
160     if [ "$_BA_USER" != "" ]; then
161         BA_USER=$_BA_USER;
162     fi
163     echo -n "Default group to own device nodes [$BA_GROUP]: "
164     read _BA_GROUP
165     if [ "$_BA_GROUP" != "" ]; then
166         BA_GROUP=$_BA_GROUP;
167     fi
168     echo -n "Default device directory [$BA_DEV_PATH]: "
169     read _BA_DEV_PATH
170     if [ "$_BA_DEV_PATH" != "" ]; then
171         BA_DEV_PATH=$_BA_DEV_PATH;
172     fi
173     _debug "BA_DEV_PATH=\"$BA_DEV_PATH\""
174     _debug "BA_USER=\"$BA_USER\""
175     _debug "BA_GROUP=\"$BA_GROUP\""
176     echo -n "Writing wwid map configuration: "
177     TMP_CONF=$(mktemp --tmpdir=$BA_CONF_PATH)
178     if [ ! -f "$TMP_CONF" ]; then
179         echo
180         _error "could not write temporary file"
181         exit 1
182     fi
183     echo "BA_DEV_PATH=\"$BA_DEV_PATH\"" >> $TMP_CONF
184     echo "BA_USER=\"$BA_USER\"" >> $TMP_CONF
185     echo "BA_GROUP=\"$BA_GROUP\"" >> $TMP_CONF
186     mv $TMP_CONF $BA_CONF
187     if [ "$?" != 0 ]; then
188         _error "could not create configuration file $BA_CONF"
189         exit
190     fi
191     echo -e "done\n"
192 }
193
194 # createdisk <alias> <device>
195 ba_createdisk () {
196     local WWID DEV ALIAS
197     ALIAS="$1"
198     DEV="$2"
199     if [ "$DEV" == "" ] || [ "$ALIAS" == "" ]; then
200         echo "Usage: $0 createdisk <alias> <device>"
201         exit 2
202     fi
203     _debug "ba_createdisk: WWID=\"$WWID\" DEV=\"$DEV\" ALIAS=\"$ALIAS\""
204
205     WWID=$(ba_scsi_id $DEV)
206     if [ "$WWID" == "" ]; then
207         _error "could not get SCSI ID for $DEV"
208         exit 1
209     fi
210     if [[ $DEV == *mpath* ]]; then
211         TYPE=mpath
212         _debug "wm_createdisk: WWID=\"$WWID\" DEV=\"$DEV\" ALIAS=\"$ALIAS\""
213     else
214         TYPE=sd
215     fi
216  
217     ba_add_wwid_mapping $WWID $ALIAS $TYPE
218     ba_store_wwid_map
219 }
220
221 ba_deletedisk () {
222     local WWID ALIAS
223     ALIAS=$1
224     if [ "$ALIAS" == "" ]; then
225         echo "Usage: $0 deletedisk <alias>"
226         exit 2
227     fi
228     WWID=${NAMEMAP[$ALIAS]}
229     if [ "$WWID" == "" ]; then
230         _error "\"$ALIAS\" does not exist"
231         echo "Usage: $0 deletedisk <alias>"
232         exit 2
233     fi
234     echo -n "Removing wwid map disk \"$ALIAS\":"
235     ba_del_wwid_mapping $WWID \
236     && echo "                                  [  OK  ]"
237     ba_store_wwid_map
238 }
239
240 ba_list_disks () {
241     for D in ${WWIDMAP[@]}; do
242         echo $D
243     done | sort -V
244 }
245
246 ba_querydisk () {
247     local LISTDEV ONDEV WWID ALIAS
248     if [ "$1" == "-d" ]; then
249         LISTDEV=1
250         shift
251     fi
252     ALIAS=$1
253     if [ "$ALIAS" == "" ]; then
254         echo "Usage: $0 querydisk <alias>"
255         exit 2
256     fi
257     WWID=${NAMEMAP[$ALIAS]}
258     _debug "ba_querydisk: ALIAS=\"$ALIAS\" WWID=\"$WWID\" LISTDEV=\"$LISTDEV\""
259     if [ "$LISTDEV" == "1" ]; then
260         DEV="/dev/$BA_DEV_PATH/$(readlink "/dev/$BA_DEV_PATH/$ALIAS")"
261         MAJ="$[0x$(stat --format "%t" $DEV)]"
262         MIN="$[0x$(stat --format "%T" $DEV)]"
263         ONDEV="on device [$MAJ,$MIN]"
264         _debug "ba_querydisk: DEV=\"$DEV\" MAJ=\"$MAJ\" MIN=\"$MIN\""
265     fi
266     if [ "$WWID" != "" ]; then
267         echo "$ALIAS is a valid blkdevalias disk $ONDEV"
268         return
269     fi
270     exit 1
271 }
272
273 ba_scandisks () {
274     _warn "(unimplemented)"
275 }
276
277 ba_map () {
278     local WWID
279     WWID="$1"
280     if [ "$WWID" == "" ] || [ "${WWIDMAP[$WWID]}" == "" ]; then
281         echo "Usage: $0 map <wwid>" 1>&2
282         exit 2
283     fi
284     echo "BA_WWID=$WWID"
285     echo "BA_NAME=$BA_DEV_PATH/${WWIDMAP[$WWID]}"
286     echo "BA_TYPE=${TYPEMAP[$WWID]}"
287     echo "BA_USER=$BA_USER"
288     echo "BA_GROUP=$BA_GROUP"
289 }
290
291 # no point optimizing this out for configure
292 ba_load_wwid_map
293 case "$1" in
294     configure)
295         ba_configure
296         ;;
297     create*)
298         ba_createdisk $2 $3
299         ;;
300     delete*)
301         ba_deletedisk $2
302         ;;
303     list*)
304         ba_list_disks
305         ;;
306     query*)
307         ba_querydisks $2 $3
308         ;;
309     scan*)
310         ba_scandisks
311         ;;
312     map)
313         ba_map $2
314         ;;
315     *)
316         echo -n "Usage: $0 "
317         echo "{configure|createdisk|deletedisk|scandisks|querydisk|map}"
318         exit 2
319 esac
320