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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2006 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 <sys/types.h>
30#include <sys/time.h>
31#include <sys/nvpair.h>
32#include <cmd.h>
33#include <errno.h>
34#include <string.h>
35#include <sys/fm/util.h>
36#include <fm/fmd_api.h>
37#include <sys/fm/protocol.h>
38
39
40/*
41 * Set-up and validate the members of an hc fmri according to;
42 *
43 *	Member name		Type		Value
44 *	===================================================
45 *	version			uint8_t		0
46 *	auth			nvlist_t	<auth>
47 *	hc-name			string		<name>
48 *	hc-id			string		<id>
49 *
50 * Note that auth and hc-id are optional members.
51 */
52
53#define	HC_MAXPAIRS	20
54#define	HC_MAXNAMELEN	50
55
56static int
57cmd_fmri_hc_set_common(nvlist_t *fmri, int version, const nvlist_t *auth)
58{
59	if (version != FM_HC_SCHEME_VERSION) {
60		return (0);
61	}
62
63	if (nvlist_add_uint8(fmri, FM_VERSION, version) != 0 ||
64	    nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_HC) != 0) {
65		return (0);
66	}
67
68	if (auth != NULL && nvlist_add_nvlist(fmri, FM_FMRI_AUTHORITY,
69	    (nvlist_t *)auth) != 0) {
70		return (0);
71	}
72
73	return (1);
74}
75
76int
77cmd_fmri_hc_set(fmd_hdl_t *hdl, nvlist_t *fmri, int version,
78    const nvlist_t *auth, nvlist_t *snvl, int npairs, ...)
79{
80	nvlist_t *pairs[HC_MAXPAIRS];
81	va_list ap;
82	int err = 0;
83	int i, j;
84
85	if (!cmd_fmri_hc_set_common(fmri, version, auth))
86		return (1);
87
88	npairs = MIN(npairs, HC_MAXPAIRS);
89
90	va_start(ap, npairs);
91	for (i = 0; i < npairs; i++) {
92		const char *name = va_arg(ap, const char *);
93		uint32_t id = va_arg(ap, uint32_t);
94		char idstr[11];
95
96		(void) snprintf(idstr, sizeof (idstr), "%u", id);
97
98		if (nvlist_alloc(&pairs[i], NV_UNIQUE_NAME, 0) != 0) {
99			fmd_hdl_debug(hdl, "nvlist_alloc failed\n");
100			goto cleanup;
101		}
102
103		err |= nvlist_add_string(pairs[i], FM_FMRI_HC_NAME, name);
104		err |= nvlist_add_string(pairs[i], FM_FMRI_HC_ID, idstr);
105	}
106	va_end(ap);
107
108	err |= nvlist_add_string(fmri, FM_FMRI_HC_ROOT, "");
109	err |= nvlist_add_uint32(fmri, FM_FMRI_HC_LIST_SZ, npairs);
110	err |= nvlist_add_nvlist_array(fmri, FM_FMRI_HC_LIST, pairs, npairs);
111
112	if (snvl != NULL)
113		err |=  nvlist_add_nvlist(fmri, FM_FMRI_HC_SPECIFIC, snvl);
114
115cleanup:
116	for (j = 0; j < i; j++)
117		nvlist_free(pairs[j]);
118
119	if (err)
120		fmd_hdl_debug(hdl, "cmd_fmri_hc_set: failed to set fmri\n");
121
122	return (err);
123}
124