1*3c5e027bSEric Taylor /*
2*3c5e027bSEric Taylor  * CDDL HEADER START
3*3c5e027bSEric Taylor  *
4*3c5e027bSEric Taylor  * The contents of this file are subject to the terms of the
5*3c5e027bSEric Taylor  * Common Development and Distribution License (the "License").
6*3c5e027bSEric Taylor  * You may not use this file except in compliance with the License.
7*3c5e027bSEric Taylor  *
8*3c5e027bSEric Taylor  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*3c5e027bSEric Taylor  * or http://www.opensolaris.org/os/licensing.
10*3c5e027bSEric Taylor  * See the License for the specific language governing permissions
11*3c5e027bSEric Taylor  * and limitations under the License.
12*3c5e027bSEric Taylor  *
13*3c5e027bSEric Taylor  * When distributing Covered Code, include this CDDL HEADER in each
14*3c5e027bSEric Taylor  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*3c5e027bSEric Taylor  * If applicable, add the following below this CDDL HEADER, with the
16*3c5e027bSEric Taylor  * fields enclosed by brackets "[]" replaced with your own identifying
17*3c5e027bSEric Taylor  * information: Portions Copyright [yyyy] [name of copyright owner]
18*3c5e027bSEric Taylor  *
19*3c5e027bSEric Taylor  * CDDL HEADER END
20*3c5e027bSEric Taylor  */
21*3c5e027bSEric Taylor /*
22*3c5e027bSEric Taylor  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*3c5e027bSEric Taylor  * Use is subject to license terms.
24*3c5e027bSEric Taylor  */
25*3c5e027bSEric Taylor 
26*3c5e027bSEric Taylor #include <stdio.h>
27*3c5e027bSEric Taylor #include <strings.h>
28*3c5e027bSEric Taylor #include <unistd.h>
29*3c5e027bSEric Taylor #include <stdarg.h>
30*3c5e027bSEric Taylor #include <fcntl.h>
31*3c5e027bSEric Taylor #include <stdlib.h>
32*3c5e027bSEric Taylor #include <libnvpair.h>
33*3c5e027bSEric Taylor #include <libdevinfo.h>
34*3c5e027bSEric Taylor #include <syslog.h>
35*3c5e027bSEric Taylor #include <sys/param.h>
36*3c5e027bSEric Taylor #include <errno.h>
37*3c5e027bSEric Taylor #include <assert.h>
38*3c5e027bSEric Taylor #include <sys/systeminfo.h>
39*3c5e027bSEric Taylor #include <sys/modctl.h>
40*3c5e027bSEric Taylor #include <sys/fs/sdev_impl.h>
41*3c5e027bSEric Taylor 
42*3c5e027bSEric Taylor /*
43*3c5e027bSEric Taylor  * Private interfaces for non-global /dev profile
44*3c5e027bSEric Taylor  */
45*3c5e027bSEric Taylor 
46*3c5e027bSEric Taylor /*
47*3c5e027bSEric Taylor  * Allocate opaque data structure for passing profile to the kernel for
48*3c5e027bSEric Taylor  * the given mount point.
49*3c5e027bSEric Taylor  *
50*3c5e027bSEric Taylor  * Note that this interface returns an empty, initialized, profile.
51*3c5e027bSEric Taylor  * It does not return what may have been previously committed.
52*3c5e027bSEric Taylor  */
53*3c5e027bSEric Taylor int
di_prof_init(const char * mountpt,di_prof_t * profp)54*3c5e027bSEric Taylor di_prof_init(const char *mountpt, di_prof_t *profp)
55*3c5e027bSEric Taylor {
56*3c5e027bSEric Taylor 	nvlist_t	*nvl;
57*3c5e027bSEric Taylor 
58*3c5e027bSEric Taylor 	if (nvlist_alloc(&nvl, 0, 0))
59*3c5e027bSEric Taylor 		return (-1);
60*3c5e027bSEric Taylor 
61*3c5e027bSEric Taylor 	if (nvlist_add_string(nvl, SDEV_NVNAME_MOUNTPT, mountpt)) {
62*3c5e027bSEric Taylor 		nvlist_free(nvl);
63*3c5e027bSEric Taylor 		return (-1);
64*3c5e027bSEric Taylor 	}
65*3c5e027bSEric Taylor 
66*3c5e027bSEric Taylor 	*profp = (di_prof_t)nvl;
67*3c5e027bSEric Taylor 	return (0);
68*3c5e027bSEric Taylor }
69*3c5e027bSEric Taylor 
70*3c5e027bSEric Taylor /*
71*3c5e027bSEric Taylor  * Free space allocated by di_prof_init().
72*3c5e027bSEric Taylor  */
73*3c5e027bSEric Taylor void
di_prof_fini(di_prof_t prof)74*3c5e027bSEric Taylor di_prof_fini(di_prof_t prof)
75*3c5e027bSEric Taylor {
76*3c5e027bSEric Taylor 	nvlist_free((nvlist_t *)prof);
77*3c5e027bSEric Taylor }
78*3c5e027bSEric Taylor 
79*3c5e027bSEric Taylor /*
80*3c5e027bSEric Taylor  * Sends profile to the kernel.
81*3c5e027bSEric Taylor  */
82*3c5e027bSEric Taylor int
di_prof_commit(di_prof_t prof)83*3c5e027bSEric Taylor di_prof_commit(di_prof_t prof)
84*3c5e027bSEric Taylor {
85*3c5e027bSEric Taylor 	char	*buf = NULL;
86*3c5e027bSEric Taylor 	size_t	buflen = 0;
87*3c5e027bSEric Taylor 	int	rv;
88*3c5e027bSEric Taylor 
89*3c5e027bSEric Taylor 	if (nvlist_pack((nvlist_t *)prof, &buf, &buflen, NV_ENCODE_NATIVE, 0))
90*3c5e027bSEric Taylor 		return (-1);
91*3c5e027bSEric Taylor 	rv = modctl(MODDEVNAME, MODDEVNAME_PROFILE, buf, buflen);
92*3c5e027bSEric Taylor 	free(buf);
93*3c5e027bSEric Taylor 	return (rv);
94*3c5e027bSEric Taylor }
95*3c5e027bSEric Taylor 
96*3c5e027bSEric Taylor /*
97*3c5e027bSEric Taylor  * Add a device or directory to profile's include list.
98*3c5e027bSEric Taylor  *
99*3c5e027bSEric Taylor  * Note that there is no arbitration between conflicting
100*3c5e027bSEric Taylor  * include and exclude profile entries, most recent
101*3c5e027bSEric Taylor  * is the winner.
102*3c5e027bSEric Taylor  */
103*3c5e027bSEric Taylor int
di_prof_add_dev(di_prof_t prof,const char * dev)104*3c5e027bSEric Taylor di_prof_add_dev(di_prof_t prof, const char *dev)
105*3c5e027bSEric Taylor {
106*3c5e027bSEric Taylor 	if (nvlist_add_string((nvlist_t *)prof, SDEV_NVNAME_INCLUDE, dev))
107*3c5e027bSEric Taylor 		return (-1);
108*3c5e027bSEric Taylor 	return (0);
109*3c5e027bSEric Taylor }
110*3c5e027bSEric Taylor 
111*3c5e027bSEric Taylor /*
112*3c5e027bSEric Taylor  * Add a device or directory to profile's exclude list.
113*3c5e027bSEric Taylor  * This can effectively remove a previously committed device.
114*3c5e027bSEric Taylor  */
115*3c5e027bSEric Taylor int
di_prof_add_exclude(di_prof_t prof,const char * dev)116*3c5e027bSEric Taylor di_prof_add_exclude(di_prof_t prof, const char *dev)
117*3c5e027bSEric Taylor {
118*3c5e027bSEric Taylor 	if (nvlist_add_string((nvlist_t *)prof, SDEV_NVNAME_EXCLUDE, dev))
119*3c5e027bSEric Taylor 		return (-1);
120*3c5e027bSEric Taylor 	return (0);
121*3c5e027bSEric Taylor }
122*3c5e027bSEric Taylor 
123*3c5e027bSEric Taylor /*
124*3c5e027bSEric Taylor  * Add a symlink to profile.
125*3c5e027bSEric Taylor  */
126*3c5e027bSEric Taylor int
di_prof_add_symlink(di_prof_t prof,const char * linkname,const char * target)127*3c5e027bSEric Taylor di_prof_add_symlink(di_prof_t prof, const char *linkname, const char *target)
128*3c5e027bSEric Taylor {
129*3c5e027bSEric Taylor 	nvlist_t	*nvl = (nvlist_t *)prof;
130*3c5e027bSEric Taylor 	char		*syml[2];
131*3c5e027bSEric Taylor 
132*3c5e027bSEric Taylor 	syml[0] = (char *)linkname;	/* 1st entry must be the symlink */
133*3c5e027bSEric Taylor 	syml[1] = (char *)target;	/* 2nd entry must be the target */
134*3c5e027bSEric Taylor 	if (nvlist_add_string_array(nvl, SDEV_NVNAME_SYMLINK, syml, 2))
135*3c5e027bSEric Taylor 		return (-1);
136*3c5e027bSEric Taylor 	return (0);
137*3c5e027bSEric Taylor }
138*3c5e027bSEric Taylor 
139*3c5e027bSEric Taylor /*
140*3c5e027bSEric Taylor  * Add a name mapping to profile.
141*3c5e027bSEric Taylor  */
142*3c5e027bSEric Taylor int
di_prof_add_map(di_prof_t prof,const char * source,const char * target)143*3c5e027bSEric Taylor di_prof_add_map(di_prof_t prof, const char *source, const char *target)
144*3c5e027bSEric Taylor {
145*3c5e027bSEric Taylor 	nvlist_t	*nvl = (nvlist_t *)prof;
146*3c5e027bSEric Taylor 	char		*map[2];
147*3c5e027bSEric Taylor 
148*3c5e027bSEric Taylor 	map[0] = (char *)source;	/* 1st entry must be the source */
149*3c5e027bSEric Taylor 	map[1] = (char *)target;	/* 2nd entry must be the target */
150*3c5e027bSEric Taylor 	if (nvlist_add_string_array(nvl, SDEV_NVNAME_MAP, map, 2))
151*3c5e027bSEric Taylor 		return (-1);
152*3c5e027bSEric Taylor 	return (0);
153*3c5e027bSEric Taylor }
154