xref: /titanic_41/usr/src/cmd/lvm/metassist/common/volume_nvpair.c (revision ea8dc4b6d2251b437950c0056bc626b311c73c27)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <libintl.h>
30 #include <string.h>
31 #include "volume_nvpair.h"
32 #include "volume_error.h"
33 
34 /*
35  * ******************************************************************
36  *
37  * Function prototypes
38  *
39  * ******************************************************************
40  */
41 
42 static nvpair_t *nvlist_walk_nvpair(nvlist_t *nvl,
43     const char *name, data_type_t type, nvpair_t *nvp);
44 
45 /*
46  * ******************************************************************
47  *
48  * External functions
49  *
50  * ******************************************************************
51  */
52 
53 /*
54  * Get the named uint16 from the given nvlist_t.
55  *
56  * @param       attrs
57  *              the nvlist_t to search
58  *
59  * @param       which
60  *              the string key for this element in the list
61  *
62  * @param       val
63  *              RETURN: the value of the requested uint16
64  *
65  * @return      0
66  *              if successful
67  *
68  * @return      ENOENT
69  *              if no matching name-value pair is found
70  */
71 int
72 get_uint16(
73 	nvlist_t *attrs,
74 	char *which,
75 	uint16_t *val)
76 {
77 	int error;
78 	nvpair_t *match =
79 	    nvlist_walk_nvpair(attrs, which, DATA_TYPE_UINT16, NULL);
80 
81 	if (match == NULL) {
82 	    error = ENOENT;
83 	} else {
84 	    error = nvpair_value_uint16(match, val);
85 	}
86 
87 	return (error);
88 }
89 
90 /*
91  * Set the named uint16 in the given nvlist_t.
92  *
93  * @param       attrs
94  *              the nvlist_t to search
95  *
96  * @param       which
97  *              the string key for this element in the list
98  *
99  * @param       val
100  *              the value to set
101  *
102  * @return      0
103  *              if successful
104  *
105  * @return      EINVAL
106  *              if there is an invalid argument
107  *
108  * @return      ENOMEM
109  *              if there is insufficient memory
110  */
111 int
112 set_uint16(
113 	nvlist_t *attrs,
114 	char *which,
115 	uint16_t val)
116 {
117 	int error = 0;
118 
119 	if ((error = nvlist_add_uint16(attrs, which, val)) != 0) {
120 	    volume_set_error(
121 		gettext("nvlist_add_int16(%s) failed: %d\n"), which, error);
122 	}
123 
124 	return (error);
125 }
126 
127 /*
128  * Get the named uint32 from the given nvlist_t.
129  *
130  * @param       attrs
131  *              the nvlist_t to search
132  *
133  * @param       which
134  *              the string key for this element in the list
135  *
136  * @param       val
137  *              RETURN: the value of the requested uint32
138  *
139  * @return      0
140  *              if successful
141  *
142  * @return      ENOENT
143  *              if no matching name-value pair is found
144  */
145 int
146 get_uint32(
147 	nvlist_t *attrs,
148 	char *which,
149 	uint32_t *val)
150 {
151 	int error;
152 	nvpair_t *match =
153 	    nvlist_walk_nvpair(attrs, which, DATA_TYPE_UINT32, NULL);
154 
155 	if (match == NULL) {
156 	    error = ENOENT;
157 	} else {
158 	    error = nvpair_value_uint32(match, val);
159 	}
160 
161 	return (error);
162 }
163 
164 /*
165  * Set the named uint32 in the given nvlist_t.
166  *
167  * @param       attrs
168  *              the nvlist_t to search
169  *
170  * @param       which
171  *              the string key for this element in the list
172  *
173  * @param       val
174  *              the value to set
175  *
176  * @return      0
177  *              if successful
178  *
179  * @return      EINVAL
180  *              if there is an invalid argument
181  *
182  * @return      ENOMEM
183  *              if there is insufficient memory
184  */
185 int
186 set_uint32(
187 	nvlist_t *attrs,
188 	char *which,
189 	uint32_t val)
190 {
191 	int error = 0;
192 
193 	if ((error = nvlist_add_uint32(attrs, which, val)) != 0) {
194 	    volume_set_error(
195 		gettext("nvlist_add_int32(%s) failed: %d\n"), which, error);
196 	}
197 
198 	return (error);
199 }
200 
201 /*
202  * Get the named uint64 from the given nvlist_t.
203  *
204  * @param       attrs
205  *              the nvlist_t to search
206  *
207  * @param       which
208  *              the string key for this element in the list
209  *
210  * @param       val
211  *              RETURN: the value of the requested uint64
212  *
213  * @return      0
214  *              if successful
215  *
216  * @return      ENOENT
217  *              if no matching name-value pair is found
218  */
219 int
220 get_uint64(
221 	nvlist_t *attrs,
222 	char *which,
223 	uint64_t *val)
224 {
225 	int error;
226 	nvpair_t *match =
227 	    nvlist_walk_nvpair(attrs, which, DATA_TYPE_UINT64, NULL);
228 
229 	if (match == NULL) {
230 	    error = ENOENT;
231 	} else {
232 	    error = nvpair_value_uint64(match, val);
233 	}
234 
235 	return (error);
236 }
237 
238 /*
239  * Set the named uint64 in the given nvlist_t.
240  *
241  * @param       attrs
242  *              the nvlist_t to search
243  *
244  * @param       which
245  *              the string key for this element in the list
246  *
247  * @param       val
248  *              the value to set
249  *
250  * @return      0
251  *              if successful
252  *
253  * @return      EINVAL
254  *              if there is an invalid argument
255  *
256  * @return      ENOMEM
257  *              if there is insufficient memory
258  */
259 int
260 set_uint64(
261 	nvlist_t *attrs,
262 	char *which,
263 	uint64_t val)
264 {
265 	int error = 0;
266 
267 	if ((error = nvlist_add_uint64(attrs, which, val)) != 0) {
268 	    volume_set_error(
269 		gettext("nvlist_add_int64(%s) failed: %d\n"), which, error);
270 	}
271 
272 	return (error);
273 }
274 
275 /*
276  * Set the named boolean in the given nvlist_t.
277  *
278  * @param       attrs
279  *              the nvlist_t to search
280  *
281  * @param       which
282  *              the string key for this element in the list
283  *
284  * @param       val
285  *              the value to set
286  *
287  * @return      0
288  *              if successful
289  *
290  * @return      EINVAL
291  *              if there is an invalid argument
292  *
293  * @return      ENOMEM
294  *              if there is insufficient memory
295  */
296 int
297 set_boolean(
298 	nvlist_t *attrs,
299 	char *which,
300 	boolean_t val)
301 {
302 	/*
303 	 * Use set_uint16 to distinguish "attr = B_FALSE" from
304 	 * "attribute unset".
305 	 */
306 	return (set_uint16(attrs, which, val == B_TRUE ? 1 : 0));
307 }
308 
309 /*
310  * Get the named boolean from the given nvlist_t.
311  *
312  * @param       attrs
313  *              the nvlist_t to search
314  *
315  * @param       which
316  *              the string key for this element in the list
317  *
318  * @param       boolval
319  *              RETURN: the value of the requested boolean
320  *
321  * @return      0
322  *              if successful
323  *
324  * @return      ENOENT
325  *              if no matching name-value pair is found
326  */
327 int
328 get_boolean(
329 	nvlist_t *attrs,
330 	char *which,
331 	boolean_t *boolval)
332 {
333 	int error;
334 	uint16_t val;
335 
336 	/*
337 	 * Use get_uint16 to distinguish "attr = B_FALSE" from
338 	 * "attribute unset".
339 	 */
340 	if ((error = get_uint16(attrs, which, &val)) == 0) {
341 	    *boolval = (val ? B_TRUE : B_FALSE);
342 	}
343 
344 	return (error);
345 }
346 
347 /*
348  * Get the named string from the given nvlist_t.
349  *
350  * @param       attrs
351  *              the nvlist_t to search
352  *
353  * @param       which
354  *              the string key for this element in the list
355  *
356  * @param       str
357  *              RETURN: the requested string
358  *
359  * @return      0
360  *              if successful
361  *
362  * @return      ENOENT
363  *              if no matching name-value pair is found
364  */
365 int
366 get_string(
367 	nvlist_t *attrs,
368 	char *which,
369 	char **str)
370 {
371 	int error;
372 	nvpair_t *match =
373 	    nvlist_walk_nvpair(attrs, which, DATA_TYPE_STRING, NULL);
374 
375 	if (match == NULL) {
376 	    error = ENOENT;
377 	} else {
378 	    error = nvpair_value_string(match, str);
379 	}
380 
381 	return (error);
382 }
383 
384 /*
385  * Set the named string in the given nvlist_t.
386  *
387  * @param       attrs
388  *              the nvlist_t to search
389  *
390  * @param       which
391  *              the string key for this element in the list
392  *
393  * @param       val
394  *              the value to set
395  *
396  * @return      0
397  *              if successful
398  *
399  * @return      EINVAL
400  *              if there is an invalid argument
401  *
402  * @return      ENOMEM
403  *              if there is insufficient memory
404  */
405 int
406 set_string(
407 	nvlist_t *attrs,
408 	char *which,
409 	char *val)
410 {
411 	int error = 0;
412 
413 	if ((error = nvlist_add_string(attrs, which, val)) != 0) {
414 	    volume_set_error(
415 		gettext("nvlist_add_string(%s) failed: %d\n"), which, error);
416 	}
417 
418 	return (error);
419 }
420 
421 /*
422  * Get the named uint16 array from the given nvlist_t.
423  *
424  * @param       attrs
425  *              the nvlist_t to search
426  *
427  * @param       which
428  *              the string key for this element in the list
429  *
430  * @param       val
431  *              RETURN: the value of the requested uint16 array
432  *
433  * @param       nelem
434  *              RETURN: the number of elements in the array
435  *
436  * @return      0
437  *              if successful
438  *
439  * @return      ENOENT
440  *              if no matching name-value pair is found
441  */
442 int
443 get_uint16_array(
444 	nvlist_t *attrs,
445 	char *which,
446 	uint16_t **val,
447 	uint_t *nelem)
448 {
449 	int error;
450 	nvpair_t *match =
451 	    nvlist_walk_nvpair(attrs, which, DATA_TYPE_UINT16_ARRAY, NULL);
452 
453 	if (match == NULL) {
454 	    error = ENOENT;
455 	} else {
456 	    error = nvpair_value_uint16_array(match, val, nelem);
457 	}
458 
459 	return (error);
460 }
461 
462 /*
463  * Set the named uint16 array from the given nvlist_t.
464  *
465  * @param       attrs
466  *              the nvlist_t to search
467  *
468  * @param       which
469  *              the string key for this element in the list
470  *
471  * @param       val
472  *              the value of the requested uint16 array
473  *
474  * @param       nelem
475  *              the number of elements in the array
476  *
477  * @return      0
478  *              if successful
479  *
480  * @return      EINVAL
481  *              if there is an invalid argument
482  *
483  * @return      ENOMEM
484  *              if there is insufficient memory
485  */
486 int
487 set_uint16_array(
488 	nvlist_t *attrs,
489 	char *which,
490 	uint16_t *val,
491 	uint_t nelem)
492 {
493 	int error = 0;
494 
495 	if ((error = nvlist_add_uint16_array(
496 	    attrs, which, val, nelem)) != 0) {
497 	    volume_set_error(
498 		gettext("nvlist_add_uint16_array(%s) failed: %d.\n"),
499 		which, error);
500 	}
501 
502 	return (error);
503 }
504 
505 /*
506  * Get the named uint64 array from the given nvlist_t.
507  *
508  * @param       attrs
509  *              the nvlist_t to search
510  *
511  * @param       which
512  *              the string key for this element in the list
513  *
514  * @param       val
515  *              RETURN: the value of the requested uint64 array
516  *
517  * @param       nelem
518  *              RETURN: the number of elements in the array
519  *
520  * @return      0
521  *              if successful
522  *
523  * @return      ENOENT
524  *              if no matching name-value pair is found
525  */
526 int
527 get_uint64_array(
528 	nvlist_t *attrs,
529 	char *which,
530 	uint64_t **val,
531 	uint_t *nelem)
532 {
533 	int error;
534 	nvpair_t *match =
535 	    nvlist_walk_nvpair(attrs, which, DATA_TYPE_UINT64_ARRAY, NULL);
536 
537 	if (match == NULL) {
538 	    error = ENOENT;
539 	} else {
540 	    error = nvpair_value_uint64_array(match, val, nelem);
541 	}
542 
543 	return (error);
544 }
545 
546 /*
547  * Set the named uint64 array from the given nvlist_t.
548  *
549  * @param       attrs
550  *              the nvlist_t to search
551  *
552  * @param       which
553  *              the string key for this element in the list
554  *
555  * @param       val
556  *              the value of the requested uint64 array
557  *
558  * @param       nelem
559  *              the number of elements in the array
560  *
561  * @return      0
562  *              if successful
563  *
564  * @return      EINVAL
565  *              if there is an invalid argument
566  *
567  * @return      ENOMEM
568  *              if there is insufficient memory
569  */
570 int
571 set_uint64_array(
572 	nvlist_t *attrs,
573 	char *which,
574 	uint64_t *val,
575 	uint_t nelem)
576 {
577 	int error = 0;
578 
579 	if ((error = nvlist_add_uint64_array(
580 	    attrs, which, val, nelem)) != 0) {
581 	    volume_set_error(
582 		gettext("nvlist_add_uint64_array(%s) failed: %d.\n"),
583 		which, error);
584 	}
585 
586 	return (error);
587 }
588 
589 /*
590  * Get the named string array from the given nvlist_t.
591  *
592  * @param       attrs
593  *              the nvlist_t to search
594  *
595  * @param       which
596  *              the string key for this element in the list
597  *
598  * @param       val
599  *              RETURN: the value of the requested string array
600  *
601  * @param       nelem
602  *              RETURN: the number of elements in the array
603  *
604  * @return      0
605  *              if successful
606  *
607  * @return      ENOENT
608  *              if no matching name-value pair is found
609  */
610 int
611 get_string_array(
612 	nvlist_t *attrs,
613 	char *which,
614 	char ***val,
615 	uint_t *nelem)
616 {
617 	int error;
618 	nvpair_t *match =
619 	    nvlist_walk_nvpair(attrs, which, DATA_TYPE_STRING_ARRAY, NULL);
620 
621 	if (match == NULL) {
622 	    error = ENOENT;
623 	} else {
624 	    error = nvpair_value_string_array(match, val, nelem);
625 	}
626 
627 	return (error);
628 }
629 
630 /*
631  * Set the named string array from the given nvlist_t.
632  *
633  * @param       attrs
634  *              the nvlist_t to search
635  *
636  * @param       which
637  *              the string key for this element in the list
638  *
639  * @param       val
640  *              the value of the requested string array
641  *
642  * @param       nelem
643  *              the number of elements in the array
644  *
645  * @return      0
646  *              if successful
647  *
648  * @return      EINVAL
649  *              if there is an invalid argument
650  *
651  * @return      ENOMEM
652  *              if there is insufficient memory
653  */
654 int
655 set_string_array(
656 	nvlist_t *attrs,
657 	char *which,
658 	char **val,
659 	uint_t nelem)
660 {
661 	int error = 0;
662 
663 	if ((error = nvlist_add_string_array(
664 	    attrs, which, val, nelem)) != 0) {
665 	    volume_set_error(
666 		gettext("nvlist_add_string_array(%s) failed: %d.\n"),
667 		which, error);
668 	}
669 
670 	return (error);
671 }
672 
673 /*
674  * ******************************************************************
675  *
676  * Static functions
677  *
678  * ******************************************************************
679  */
680 
681 /*
682  * Get a handle to the next nvpair with the specified name and data
683  * type in the list following the given nvpair.
684  *
685  * Some variation of this function will likely appear in the libnvpair
686  * library per 4981923.
687  *
688  * @param       nvl
689  *              the nvlist_t to search
690  *
691  * @param       name
692  *              the string key for the pair to find in the list, or
693  *              NULL to match any name
694  *
695  * @param       type
696  *              the data type for the pair to find in the list, or
697  *              DATA_TYPE_UNKNOWN to match any type
698  *
699  * @param       nvp
700  *              the pair to search from in the list, or NULL to search
701  *              from the beginning of the list
702  *
703  * @return      the next nvpair in the list matching the given
704  *              criteria, or NULL if no matching nvpair is found
705  */
706 static nvpair_t *
707 nvlist_walk_nvpair(
708 	nvlist_t *nvl,
709 	const char *name,
710 	data_type_t type,
711 	nvpair_t *nvp)
712 {
713 	/* For each nvpair in the list following nvp... */
714 	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
715 
716 	    /* Does this pair's name match the given name? */
717 	    if ((name == NULL || strcmp(nvpair_name(nvp), name) == 0) &&
718 
719 		/* Does this pair's type match the given type? */
720 		(type == DATA_TYPE_UNKNOWN || type == nvpair_type(nvp))) {
721 		return (nvp);
722 	    }
723 	}
724 
725 	return (NULL);
726 }
727