Deleted Added
full compact
geom.subr (280921) geom.subr (298884)
1if [ ! "$_GEOM_SUBR" ]; then _GEOM_SUBR=1
2#
3# Copyright (c) 2012-2014 Devin Teske
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
1if [ ! "$_GEOM_SUBR" ]; then _GEOM_SUBR=1
2#
3# Copyright (c) 2012-2014 Devin Teske
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD: head/usr.sbin/bsdconfig/share/geom.subr 280921 2015-03-31 21:34:42Z dteske $
27# $FreeBSD: head/usr.sbin/bsdconfig/share/geom.subr 298884 2016-05-01 16:38:12Z pfg $
28#
29############################################################ INCLUDES
30
31BSDCFG_SHARE="/usr/share/bsdconfig"
32. $BSDCFG_SHARE/common.subr || exit 1
33f_dprintf "%s: loading includes..." geom.subr
34f_include $BSDCFG_SHARE/strings.subr
35f_include $BSDCFG_SHARE/struct.subr
36
37############################################################ GLOBALS
38
39NGEOM_CLASSES=0 # Set by f_geom_get_all()/f_geom_reset()
40
41#
42# GEOM classes for use with f_geom_find()
43#
44# NB: Since $GEOM_CLASS_ANY is the NULL string, make sure you quote it whenever
45# you put arguments after it.
46#
47setvar GEOM_CLASS_ANY "any"
48setvar GEOM_CLASS_DEV "DEV"
49setvar GEOM_CLASS_DISK "DISK"
50setvar GEOM_CLASS_ELI "ELI"
51setvar GEOM_CLASS_FD "FD"
52setvar GEOM_CLASS_LABEL "LABEL"
53setvar GEOM_CLASS_MD "MD"
54setvar GEOM_CLASS_NOP "NOP"
55setvar GEOM_CLASS_PART "PART"
56setvar GEOM_CLASS_RAID "RAID"
57setvar GEOM_CLASS_SWAP "SWAP"
58setvar GEOM_CLASS_VFS "VFS"
59setvar GEOM_CLASS_ZFS_VDEV "ZFS::VDEV"
60setvar GEOM_CLASS_ZFS_ZVOL "ZFS::ZVOL"
61
62#
63# GEOM structure definitions
64#
65f_struct_define GEOM_CLASS \
66 id name ngeoms
67f_struct_define GEOM_GEOM \
68 id class_ref config name nconsumers nproviders rank
69 # Also consumerN where N is 1 through nconsumers
70 # Also providerN where N is 1 through nproviders
71f_struct_define GEOM_CONSUMER \
72 id geom_ref config mode provider_ref
73f_struct_define GEOM_PROVIDER \
74 id geom_ref config mode name mediasize
75
76# The config property of GEOM_GEOM struct is defined as this
77f_struct_define GEOM_GEOM_CONFIG \
78 entries first fwheads fwsectors last modified scheme state
79
80# The config property of GEOM_PROVIDER struct is defined as this
81f_struct_define GEOM_PROVIDER_CONFIG \
82 descr file fwheads fwsectors ident length type unit
83
84#
85# Default behavior is to call f_geom_get_all() automatically when loaded.
86#
87: ${GEOM_SELF_SCAN_ALL=1}
88
89############################################################ FUNCTIONS
90
91# f_geom_get_all
92#
93# Parse sysctl(8) `kern.geom.confxml' data into a series of structs. GEOM
28#
29############################################################ INCLUDES
30
31BSDCFG_SHARE="/usr/share/bsdconfig"
32. $BSDCFG_SHARE/common.subr || exit 1
33f_dprintf "%s: loading includes..." geom.subr
34f_include $BSDCFG_SHARE/strings.subr
35f_include $BSDCFG_SHARE/struct.subr
36
37############################################################ GLOBALS
38
39NGEOM_CLASSES=0 # Set by f_geom_get_all()/f_geom_reset()
40
41#
42# GEOM classes for use with f_geom_find()
43#
44# NB: Since $GEOM_CLASS_ANY is the NULL string, make sure you quote it whenever
45# you put arguments after it.
46#
47setvar GEOM_CLASS_ANY "any"
48setvar GEOM_CLASS_DEV "DEV"
49setvar GEOM_CLASS_DISK "DISK"
50setvar GEOM_CLASS_ELI "ELI"
51setvar GEOM_CLASS_FD "FD"
52setvar GEOM_CLASS_LABEL "LABEL"
53setvar GEOM_CLASS_MD "MD"
54setvar GEOM_CLASS_NOP "NOP"
55setvar GEOM_CLASS_PART "PART"
56setvar GEOM_CLASS_RAID "RAID"
57setvar GEOM_CLASS_SWAP "SWAP"
58setvar GEOM_CLASS_VFS "VFS"
59setvar GEOM_CLASS_ZFS_VDEV "ZFS::VDEV"
60setvar GEOM_CLASS_ZFS_ZVOL "ZFS::ZVOL"
61
62#
63# GEOM structure definitions
64#
65f_struct_define GEOM_CLASS \
66 id name ngeoms
67f_struct_define GEOM_GEOM \
68 id class_ref config name nconsumers nproviders rank
69 # Also consumerN where N is 1 through nconsumers
70 # Also providerN where N is 1 through nproviders
71f_struct_define GEOM_CONSUMER \
72 id geom_ref config mode provider_ref
73f_struct_define GEOM_PROVIDER \
74 id geom_ref config mode name mediasize
75
76# The config property of GEOM_GEOM struct is defined as this
77f_struct_define GEOM_GEOM_CONFIG \
78 entries first fwheads fwsectors last modified scheme state
79
80# The config property of GEOM_PROVIDER struct is defined as this
81f_struct_define GEOM_PROVIDER_CONFIG \
82 descr file fwheads fwsectors ident length type unit
83
84#
85# Default behavior is to call f_geom_get_all() automatically when loaded.
86#
87: ${GEOM_SELF_SCAN_ALL=1}
88
89############################################################ FUNCTIONS
90
91# f_geom_get_all
92#
93# Parse sysctl(8) `kern.geom.confxml' data into a series of structs. GEOM
94# classes are at the top of the heirarchy and are stored as numbered structs
94# classes are at the top of the hierarchy and are stored as numbered structs
95# from 1 to $NGEOM_CLASSES (set by this function) named `geom_class_C'. GEOM
96# objects within each class are stored as numbered structs from 1 to `ngeoms'
97# (a property of the GEOM class struct) named `geom_class_C_geom_N' (where C
98# is the class number and N is the geom number).
99#
100# Use the function f_geom_find() to get a list of geoms (execute without
101# arguments) or find specific geoms by class or name.
102#
103f_geom_get_all()
104{
105 eval "$( sysctl -n kern.geom.confxml | awk '
106 BEGIN {
107 struct_count["class"] = 0
108 struct_count["geom"] = 0
109 struct_count["consumer"] = 0
110 struct_count["provider"] = 0
111 }
112 ############################################### FUNCTIONS
113 function set_value(prop, value)
114 {
115 if (!struct_stack[cur_struct]) return
116 printf "%s set %s \"%s\"\n",
117 struct_stack[cur_struct], prop, value
118 }
119 function create(type, id)
120 {
121 if (struct = created[type "_" id])
122 print "f_struct_free", struct
123 else {
124 struct = struct_stack[cur_struct]
125 struct = struct ( struct ? "" : "geom" )
126 struct = struct "_" type "_" ++struct_count[type]
127 created[type "_" id] = struct
128 }
129 print "debug= f_struct_new GEOM_" toupper(type), struct
130 cur_struct++
131 struct_stack[cur_struct] = struct
132 type_stack[cur_struct] = type
133 set_value("id", id)
134 }
135 function create_config()
136 {
137 struct = struct_stack[cur_struct]
138 struct = struct ( struct ? "" : "geom" )
139 struct = struct "_config"
140 set_value("config", struct)
141 type = type_stack[cur_struct]
142 print "debug= f_struct_new GEOM_" toupper(type) "_CONFIG", \
143 struct
144 cur_struct++
145 struct_stack[cur_struct] = struct
146 type_stack[cur_struct] = type "_config"
147 }
148 function extract_attr(field, attr)
149 {
150 if (match(field, attr "=\"0x[[:xdigit:]]+\"")) {
151 len = length(attr)
152 return substr($2, len + 3, RLENGTH - len - 3)
153 }
154 }
155 function extract_data(type)
156 {
157 data = $0
158 sub("^[[:space:]]*<" type ">", "", data)
159 sub("</" type ">.*$", "", data)
160 return data
161 }
162 ############################################### OPENING PATTERNS
163 $1 == "<mesh>" { mesh = 1 }
164 $1 ~ /^<(class|geom)$/ && mesh {
165 prop = substr($1, 2)
166 if ((ref = extract_attr($2, "ref")) != "")
167 set_value(prop "_ref", ref)
168 else if ((id = extract_attr($2, "id")) != "")
169 create(prop, id)
170 }
171 $1 ~ /^<(consumer|provider)$/ && mesh {
172 prop = substr($1, 2)
173 if ((ref = extract_attr($2, "ref")) != "")
174 set_value(prop "_ref", ref)
175 else if ((id = extract_attr($2, "id")) != "") {
176 create(prop, id)
177 cur_struct--
178 propn = struct_count[prop]
179 set_value(prop propn, struct_stack[cur_struct+1])
180 cur_struct++
181 }
182 }
183 $1 == "<config>" && mesh { create_config() }
184 ############################################### PROPERTIES
185 $1 ~ /^<[[:alnum:]]+>/ {
186 prop = $1
187 sub(/^</, "", prop); sub(/>.*/, "", prop)
188 set_value(prop, extract_data(prop))
189 }
190 ############################################### CLOSING PATTERNS
191 $1 ~ "^</(consumer|provider|config)>$" { cur_struct-- }
192 $1 == "</geom>" {
193 set_value("nconsumers", struct_count["consumer"])
194 set_value("nproviders", struct_count["provider"])
195 cur_struct--
196 struct_count["consumer"] = 0
197 struct_count["provider"] = 0
198 }
199 $1 == "</class>" {
200 set_value("ngeoms", struct_count["geom"])
201 cur_struct--
202 struct_count["consumer"] = 0
203 struct_count["provider"] = 0
204 struct_count["geom"] = 0
205 }
206 $1 == "</mesh>" {
207 printf "NGEOM_CLASSES=%u\n", struct_count["class"]
208 delete struct_count
209 mesh = 0
210 }' )"
211}
212
213# f_geom_reset
214#
215# Reset the registered GEOM chain.
216#
217f_geom_reset()
218{
219 local classn=1 class ngeoms geomn geom
220 while [ $classn -le ${NGEOM_CLASSES:-0} ]; do
221 class=geom_class_$classn
222 $class get ngeoms ngeoms
223 geomn=1
224 while [ $geomn -le $ngeoms ]; do
225 f_struct_free ${class}_geom_$geomn
226 geomn=$(( $geomn + 1 ))
227 done
228 classn=$(( $classn + 1 ))
229 done
230 NGEOM_CLASSES=0
231}
232
233# f_geom_rescan
234#
235# Rescan all GEOMs - convenience function.
236#
237f_geom_rescan()
238{
239 f_geom_reset
240 f_geom_get_all
241}
242
243# f_geom_find $name [$type [$var_to_set]]
244#
245# Find one or more registered GEOMs by name, type, or both. Returns a space-
246# separated list of GEOMs matching the search criterion. The $type argument
247# should be the GEOM class (see $GEOM_CLASS_* variables in GLOBALS above).
248#
249# If $var_to_set is missing or NULL, the GEOM name(s) are printed to standard
250# out for capturing in a sub-shell (which is less-recommended because of
251# performance degredation; for example, when called in a loop).
252#
253f_geom_find()
254{
255 local __name="$1" __type="${2:-$GEOM_CLASS_ANY}" __var_to_set="$3"
256 local __classn=1 __class __class_name __ngeoms
257 local __geomn __geom __geom_name __found=
258 while [ $__classn -le ${NGEOM_CLASSES:-0} ]; do
259 __class=geom_class_$__classn
260 $__class get name __class_name
261 if [ "$__type" != "$GEOM_CLASS_ANY" -a \
262 "$__type" != "$__class_name" ]
263 then
264 __classn=$(( $__classn + 1 ))
265 continue
266 fi
267
268 __geomn=1
269 $__class get ngeoms __ngeoms || __ngeoms=0
270 while [ $__geomn -le $__ngeoms ]; do
271 __geom=${__class}_geom_$__geomn
272 $__geom get name __geom_name
273 [ "$__name" = "$__geom_name" -o ! "$__name" ] &&
274 __found="$__found $__geom"
275 __geomn=$(( $__geomn + 1 ))
276 done
277 __classn=$(( $__classn + 1 ))
278 done
279 if [ "$__var_to_set" ]; then
280 setvar "$__var_to_set" "${__found# }"
281 else
282 echo $__found
283 fi
284 [ "$__found" ] # Return status
285}
286
287# f_geom_find_by $prop $find [$type [$var_to_set]]
288#
289# Find GEOM-related struct where $prop of the struct is equal to $find. Returns
290# NULL or the name of the first GEOM struct to match. The $type argument should
291# be one of the following:
292#
293# NULL Find any of the below
294# class Find GEOM_CLASS struct
295# geom Find GEOM_GEOM struct
296# consumer Find GEOM_CONSUMER struct
297# provider Find GEOM_PROVIDER struct
298#
299# The $prop argument can be any property of the given type of struct. Some
300# properties are common to all types (such as id) so the $type argument is
301# optional (allowing you to return any struct whose property matches $find).
302#
303# If $var_to_set is missing or NULL, the GEOM struct name is printed to
304# standard out for capturing in a sub-shell (which is less-recommended because
305# of performance degredation; for example when called in a loop).
306#
307f_geom_find_by()
308{
309 local __prop="$1" __find="$2" __type="$3" __var_to_set="$4"
310 local __classn=1 __class __ngeoms
311 local __geomn __geom __nitems
312 local __itype __itemn __item
313 local __value __found=
314
315 if [ ! "$__prop" ]; then
316 [ "$__var_to_set" ] && setvar "$__var_to_set" ""
317 return $FAILURE
318 fi
319
320 case "$__type" in
321 "") : OK ;;
322 class|GEOM_CLASS) __type=class ;;
323 geom|GEOM_GEOM) __type=geom ;;
324 consumer|GEOM_CONSUMER) __type=consumer ;;
325 provider|GEOM_PROVIDER) __type=provider ;;
326 *)
327 [ "$__var_to_set" ] && setvar "$__var_to_set" ""
328 return $FAILURE
329 esac
330
331 while [ $__classn -le ${NGEOM_CLASSES:-0} ]; do
332 __class=geom_class_$__classn
333
334 if [ "${__type:-class}" = "class" ]; then
335 $__class get "$__prop" __value || __value=
336 [ "$__value" = "$__find" ] && __found="$__class" break
337 [ "$__type" ] && __classn=$(( $__classn + 1 )) continue
338 fi
339
340 __geomn=1
341 $__class get ngeoms __ngeoms || __ngeoms=0
342 while [ $__geomn -le $__ngeoms ]; do
343 __geom=${__class}_geom_$__geomn
344
345 if [ "${__type:-geom}" = "geom" ]; then
346 $__geom get "$__prop" __value || __value=
347 [ "$__value" = "$__find" ] &&
348 __found="$__geom" break
349 [ "$__type" ] &&
350 __geomn=$(( $__geomn + 1 )) continue
351 fi
352
353 for __itype in ${__type:-consumer provider}; do
354 $__geom get n${__itype}s __nitems || continue
355 __itemn=1
356 while [ $__itemn -le $__nitems ]; do
357 __item=${__geom}_${__itype}_$__itemn
358
359 $__item get "$__prop" __value ||
360 __value=
361 [ "$__value" = "$__find" ] &&
362 __found="$__item" break
363 __itemn=$(( $__itemn + 1 ))
364 done
365 [ "$__found" ] && break
366 done
367 [ "$__found" ] && break
368 __geomn=$(( $__geomn + 1 ))
369 done
370 [ "$__found" ] && break
371 __classn=$(( $__classn + 1 ))
372 done
373 if [ "$__var_to_set" ]; then
374 setvar "$__var_to_set" "$__found"
375 else
376 [ "$__found" ] && echo "$__found"
377 fi
378 [ "$__found" ] # Return status
379}
380
381# f_geom_parent $geom|$consumer|$provider|$config [$var_to_set]
382#
383# Get the GEOM class associated with one of $geom, $consumer, $provider or
384# $config.
385#
386# If $var_to_set is missing or NULL, the GEOM class name is printed to standard
387# out for capturing in a sub-shell (which is less-recommended because of
388# performance degredation; for example when called in a loop).
389#
390f_geom_parent()
391{
392 local __struct="$1" __var_to_set="$2"
393 # NB: Order of pattern matches below is important
394 case "$__struct" in
395 *_config*) __struct="${__struct%_config*}" ;;
396 *_consumer_*) __struct="${__struct%_consumer_[0-9]*}" ;;
397 *_provider_*) __struct="${__struct%_provider_[0-9]*}" ;;
398 *_geom_*) __struct="${__struct%_geom_[0-9]*}" ;;
399 *) __struct=
400 esac
401 if [ "$__var_to_set" ]; then
402 setvar "$__var_to_set" "$__struct"
403 else
404 echo "$__struct"
405 fi
406 f_struct "$__struct" # Return status
407}
408
409############################################################ MAIN
410
411#
412# Parse GEOM configuration unless requested otherwise
413#
414f_dprintf "%s: GEOM_SELF_SCAN_ALL=[%s]" geom.subr "$GEOM_SELF_SCAN_ALL"
415case "$GEOM_SELF_SCAN_ALL" in
416""|0|[Nn][Oo]|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee]) : do nothing ;;
417*)
418 f_geom_get_all
419 if [ "$debug" ]; then
420 debug= f_geom_find "" "$GEOM_CLASS_ANY" geoms
421 f_count ngeoms $geoms
422 f_dprintf "%s: Initialized %u geom devices in %u classes." \
423 geom.subr "$ngeoms" "$NGEOM_CLASSES"
424 unset geoms ngeoms
425 fi
426esac
427
428f_dprintf "%s: Successfully loaded." geom.subr
429
430fi # ! $_GEOM_SUBR
95# from 1 to $NGEOM_CLASSES (set by this function) named `geom_class_C'. GEOM
96# objects within each class are stored as numbered structs from 1 to `ngeoms'
97# (a property of the GEOM class struct) named `geom_class_C_geom_N' (where C
98# is the class number and N is the geom number).
99#
100# Use the function f_geom_find() to get a list of geoms (execute without
101# arguments) or find specific geoms by class or name.
102#
103f_geom_get_all()
104{
105 eval "$( sysctl -n kern.geom.confxml | awk '
106 BEGIN {
107 struct_count["class"] = 0
108 struct_count["geom"] = 0
109 struct_count["consumer"] = 0
110 struct_count["provider"] = 0
111 }
112 ############################################### FUNCTIONS
113 function set_value(prop, value)
114 {
115 if (!struct_stack[cur_struct]) return
116 printf "%s set %s \"%s\"\n",
117 struct_stack[cur_struct], prop, value
118 }
119 function create(type, id)
120 {
121 if (struct = created[type "_" id])
122 print "f_struct_free", struct
123 else {
124 struct = struct_stack[cur_struct]
125 struct = struct ( struct ? "" : "geom" )
126 struct = struct "_" type "_" ++struct_count[type]
127 created[type "_" id] = struct
128 }
129 print "debug= f_struct_new GEOM_" toupper(type), struct
130 cur_struct++
131 struct_stack[cur_struct] = struct
132 type_stack[cur_struct] = type
133 set_value("id", id)
134 }
135 function create_config()
136 {
137 struct = struct_stack[cur_struct]
138 struct = struct ( struct ? "" : "geom" )
139 struct = struct "_config"
140 set_value("config", struct)
141 type = type_stack[cur_struct]
142 print "debug= f_struct_new GEOM_" toupper(type) "_CONFIG", \
143 struct
144 cur_struct++
145 struct_stack[cur_struct] = struct
146 type_stack[cur_struct] = type "_config"
147 }
148 function extract_attr(field, attr)
149 {
150 if (match(field, attr "=\"0x[[:xdigit:]]+\"")) {
151 len = length(attr)
152 return substr($2, len + 3, RLENGTH - len - 3)
153 }
154 }
155 function extract_data(type)
156 {
157 data = $0
158 sub("^[[:space:]]*<" type ">", "", data)
159 sub("</" type ">.*$", "", data)
160 return data
161 }
162 ############################################### OPENING PATTERNS
163 $1 == "<mesh>" { mesh = 1 }
164 $1 ~ /^<(class|geom)$/ && mesh {
165 prop = substr($1, 2)
166 if ((ref = extract_attr($2, "ref")) != "")
167 set_value(prop "_ref", ref)
168 else if ((id = extract_attr($2, "id")) != "")
169 create(prop, id)
170 }
171 $1 ~ /^<(consumer|provider)$/ && mesh {
172 prop = substr($1, 2)
173 if ((ref = extract_attr($2, "ref")) != "")
174 set_value(prop "_ref", ref)
175 else if ((id = extract_attr($2, "id")) != "") {
176 create(prop, id)
177 cur_struct--
178 propn = struct_count[prop]
179 set_value(prop propn, struct_stack[cur_struct+1])
180 cur_struct++
181 }
182 }
183 $1 == "<config>" && mesh { create_config() }
184 ############################################### PROPERTIES
185 $1 ~ /^<[[:alnum:]]+>/ {
186 prop = $1
187 sub(/^</, "", prop); sub(/>.*/, "", prop)
188 set_value(prop, extract_data(prop))
189 }
190 ############################################### CLOSING PATTERNS
191 $1 ~ "^</(consumer|provider|config)>$" { cur_struct-- }
192 $1 == "</geom>" {
193 set_value("nconsumers", struct_count["consumer"])
194 set_value("nproviders", struct_count["provider"])
195 cur_struct--
196 struct_count["consumer"] = 0
197 struct_count["provider"] = 0
198 }
199 $1 == "</class>" {
200 set_value("ngeoms", struct_count["geom"])
201 cur_struct--
202 struct_count["consumer"] = 0
203 struct_count["provider"] = 0
204 struct_count["geom"] = 0
205 }
206 $1 == "</mesh>" {
207 printf "NGEOM_CLASSES=%u\n", struct_count["class"]
208 delete struct_count
209 mesh = 0
210 }' )"
211}
212
213# f_geom_reset
214#
215# Reset the registered GEOM chain.
216#
217f_geom_reset()
218{
219 local classn=1 class ngeoms geomn geom
220 while [ $classn -le ${NGEOM_CLASSES:-0} ]; do
221 class=geom_class_$classn
222 $class get ngeoms ngeoms
223 geomn=1
224 while [ $geomn -le $ngeoms ]; do
225 f_struct_free ${class}_geom_$geomn
226 geomn=$(( $geomn + 1 ))
227 done
228 classn=$(( $classn + 1 ))
229 done
230 NGEOM_CLASSES=0
231}
232
233# f_geom_rescan
234#
235# Rescan all GEOMs - convenience function.
236#
237f_geom_rescan()
238{
239 f_geom_reset
240 f_geom_get_all
241}
242
243# f_geom_find $name [$type [$var_to_set]]
244#
245# Find one or more registered GEOMs by name, type, or both. Returns a space-
246# separated list of GEOMs matching the search criterion. The $type argument
247# should be the GEOM class (see $GEOM_CLASS_* variables in GLOBALS above).
248#
249# If $var_to_set is missing or NULL, the GEOM name(s) are printed to standard
250# out for capturing in a sub-shell (which is less-recommended because of
251# performance degredation; for example, when called in a loop).
252#
253f_geom_find()
254{
255 local __name="$1" __type="${2:-$GEOM_CLASS_ANY}" __var_to_set="$3"
256 local __classn=1 __class __class_name __ngeoms
257 local __geomn __geom __geom_name __found=
258 while [ $__classn -le ${NGEOM_CLASSES:-0} ]; do
259 __class=geom_class_$__classn
260 $__class get name __class_name
261 if [ "$__type" != "$GEOM_CLASS_ANY" -a \
262 "$__type" != "$__class_name" ]
263 then
264 __classn=$(( $__classn + 1 ))
265 continue
266 fi
267
268 __geomn=1
269 $__class get ngeoms __ngeoms || __ngeoms=0
270 while [ $__geomn -le $__ngeoms ]; do
271 __geom=${__class}_geom_$__geomn
272 $__geom get name __geom_name
273 [ "$__name" = "$__geom_name" -o ! "$__name" ] &&
274 __found="$__found $__geom"
275 __geomn=$(( $__geomn + 1 ))
276 done
277 __classn=$(( $__classn + 1 ))
278 done
279 if [ "$__var_to_set" ]; then
280 setvar "$__var_to_set" "${__found# }"
281 else
282 echo $__found
283 fi
284 [ "$__found" ] # Return status
285}
286
287# f_geom_find_by $prop $find [$type [$var_to_set]]
288#
289# Find GEOM-related struct where $prop of the struct is equal to $find. Returns
290# NULL or the name of the first GEOM struct to match. The $type argument should
291# be one of the following:
292#
293# NULL Find any of the below
294# class Find GEOM_CLASS struct
295# geom Find GEOM_GEOM struct
296# consumer Find GEOM_CONSUMER struct
297# provider Find GEOM_PROVIDER struct
298#
299# The $prop argument can be any property of the given type of struct. Some
300# properties are common to all types (such as id) so the $type argument is
301# optional (allowing you to return any struct whose property matches $find).
302#
303# If $var_to_set is missing or NULL, the GEOM struct name is printed to
304# standard out for capturing in a sub-shell (which is less-recommended because
305# of performance degredation; for example when called in a loop).
306#
307f_geom_find_by()
308{
309 local __prop="$1" __find="$2" __type="$3" __var_to_set="$4"
310 local __classn=1 __class __ngeoms
311 local __geomn __geom __nitems
312 local __itype __itemn __item
313 local __value __found=
314
315 if [ ! "$__prop" ]; then
316 [ "$__var_to_set" ] && setvar "$__var_to_set" ""
317 return $FAILURE
318 fi
319
320 case "$__type" in
321 "") : OK ;;
322 class|GEOM_CLASS) __type=class ;;
323 geom|GEOM_GEOM) __type=geom ;;
324 consumer|GEOM_CONSUMER) __type=consumer ;;
325 provider|GEOM_PROVIDER) __type=provider ;;
326 *)
327 [ "$__var_to_set" ] && setvar "$__var_to_set" ""
328 return $FAILURE
329 esac
330
331 while [ $__classn -le ${NGEOM_CLASSES:-0} ]; do
332 __class=geom_class_$__classn
333
334 if [ "${__type:-class}" = "class" ]; then
335 $__class get "$__prop" __value || __value=
336 [ "$__value" = "$__find" ] && __found="$__class" break
337 [ "$__type" ] && __classn=$(( $__classn + 1 )) continue
338 fi
339
340 __geomn=1
341 $__class get ngeoms __ngeoms || __ngeoms=0
342 while [ $__geomn -le $__ngeoms ]; do
343 __geom=${__class}_geom_$__geomn
344
345 if [ "${__type:-geom}" = "geom" ]; then
346 $__geom get "$__prop" __value || __value=
347 [ "$__value" = "$__find" ] &&
348 __found="$__geom" break
349 [ "$__type" ] &&
350 __geomn=$(( $__geomn + 1 )) continue
351 fi
352
353 for __itype in ${__type:-consumer provider}; do
354 $__geom get n${__itype}s __nitems || continue
355 __itemn=1
356 while [ $__itemn -le $__nitems ]; do
357 __item=${__geom}_${__itype}_$__itemn
358
359 $__item get "$__prop" __value ||
360 __value=
361 [ "$__value" = "$__find" ] &&
362 __found="$__item" break
363 __itemn=$(( $__itemn + 1 ))
364 done
365 [ "$__found" ] && break
366 done
367 [ "$__found" ] && break
368 __geomn=$(( $__geomn + 1 ))
369 done
370 [ "$__found" ] && break
371 __classn=$(( $__classn + 1 ))
372 done
373 if [ "$__var_to_set" ]; then
374 setvar "$__var_to_set" "$__found"
375 else
376 [ "$__found" ] && echo "$__found"
377 fi
378 [ "$__found" ] # Return status
379}
380
381# f_geom_parent $geom|$consumer|$provider|$config [$var_to_set]
382#
383# Get the GEOM class associated with one of $geom, $consumer, $provider or
384# $config.
385#
386# If $var_to_set is missing or NULL, the GEOM class name is printed to standard
387# out for capturing in a sub-shell (which is less-recommended because of
388# performance degredation; for example when called in a loop).
389#
390f_geom_parent()
391{
392 local __struct="$1" __var_to_set="$2"
393 # NB: Order of pattern matches below is important
394 case "$__struct" in
395 *_config*) __struct="${__struct%_config*}" ;;
396 *_consumer_*) __struct="${__struct%_consumer_[0-9]*}" ;;
397 *_provider_*) __struct="${__struct%_provider_[0-9]*}" ;;
398 *_geom_*) __struct="${__struct%_geom_[0-9]*}" ;;
399 *) __struct=
400 esac
401 if [ "$__var_to_set" ]; then
402 setvar "$__var_to_set" "$__struct"
403 else
404 echo "$__struct"
405 fi
406 f_struct "$__struct" # Return status
407}
408
409############################################################ MAIN
410
411#
412# Parse GEOM configuration unless requested otherwise
413#
414f_dprintf "%s: GEOM_SELF_SCAN_ALL=[%s]" geom.subr "$GEOM_SELF_SCAN_ALL"
415case "$GEOM_SELF_SCAN_ALL" in
416""|0|[Nn][Oo]|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee]) : do nothing ;;
417*)
418 f_geom_get_all
419 if [ "$debug" ]; then
420 debug= f_geom_find "" "$GEOM_CLASS_ANY" geoms
421 f_count ngeoms $geoms
422 f_dprintf "%s: Initialized %u geom devices in %u classes." \
423 geom.subr "$ngeoms" "$NGEOM_CLASSES"
424 unset geoms ngeoms
425 fi
426esac
427
428f_dprintf "%s: Successfully loaded." geom.subr
429
430fi # ! $_GEOM_SUBR