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