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