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 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * The dlmgmtd daemon is started by the datalink-management SMF service.
29 * This daemon is used to manage <link name, linkid> mapping and the
30 * persistent datalink configuration.
31 *
32 * Today, the <link name, linkid> mapping and the persistent configuration
33 * of datalinks is kept in /etc/dladm/datalink.conf, and the daemon keeps
34 * a copy of the datalinks in the memory (see dlmgmt_id_avl and
35 * dlmgmt_name_avl). The active <link name, linkid> mapping is kept in
36 * /etc/svc/volatile/dladm cache file, so that the mapping can be recovered
37 * when dlmgmtd exits for some reason (e.g., when dlmgmtd is accidentally
38 * killed).
39 */
40
41 #include <assert.h>
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <priv.h>
114 static void
115 dlmgmt_door_fini(void)
116 {
117 if (dlmgmt_door_fd == -1)
118 return;
119
120 if (door_revoke(dlmgmt_door_fd) == -1) {
121 dlmgmt_log(LOG_WARNING, "door_revoke(%s) failed: %s",
122 DLMGMT_DOOR, strerror(errno));
123 }
124 (void) dlmgmt_set_doorfd(B_FALSE);
125 dlmgmt_door_fd = -1;
126 }
127
128 int
129 dlmgmt_door_attach(zoneid_t zoneid, char *rootdir)
130 {
131 int fd;
132 int err = 0;
133 char doorpath[MAXPATHLEN];
134
135 (void) snprintf(doorpath, sizeof (doorpath), "%s%s", rootdir,
136 DLMGMT_DOOR);
137
138 /*
139 * Create the door file for dlmgmtd.
140 */
141 if ((fd = open(doorpath, O_CREAT|O_RDONLY, 0644)) == -1) {
142 err = errno;
143 dlmgmt_log(LOG_ERR, "open(%s) failed: %s", doorpath,
144 strerror(err));
145 return (err);
146 }
147 (void) close(fd);
148 if (chown(doorpath, UID_DLADM, GID_NETADM) == -1)
149 return (errno);
150
151 /*
152 * fdetach first in case a previous daemon instance exited
153 * ungracefully.
154 */
155 (void) fdetach(doorpath);
156 if (fattach(dlmgmt_door_fd, doorpath) != 0) {
175 int
176 dlmgmt_zone_init(zoneid_t zoneid)
177 {
178 char rootdir[MAXPATHLEN], tmpfsdir[MAXPATHLEN];
179 int err;
180 struct stat statbuf;
181
182 if (zoneid == GLOBAL_ZONEID) {
183 rootdir[0] = '\0';
184 } else if (zone_getattr(zoneid, ZONE_ATTR_ROOT, rootdir,
185 sizeof (rootdir)) < 0) {
186 return (errno);
187 }
188
189 /*
190 * Create the DLMGMT_TMPFS_DIR directory.
191 */
192 (void) snprintf(tmpfsdir, sizeof (tmpfsdir), "%s%s", rootdir,
193 DLMGMT_TMPFS_DIR);
194 if (stat(tmpfsdir, &statbuf) < 0) {
195 if (mkdir(tmpfsdir, (mode_t)0755) < 0)
196 return (errno);
197 } else if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
198 return (ENOTDIR);
199 }
200
201 if ((chmod(tmpfsdir, 0755) < 0) ||
202 (chown(tmpfsdir, UID_DLADM, GID_NETADM) < 0)) {
203 return (EPERM);
204 }
205
206 if ((err = dlmgmt_db_init(zoneid)) != 0)
207 return (err);
208 return (dlmgmt_door_attach(zoneid, rootdir));
209 }
210
211 /*
212 * Initialize each running zone.
213 */
214 static int
215 dlmgmt_allzones_init(void)
216 {
217 int err, i;
218 zoneid_t *zids = NULL;
219 uint_t nzids, nzids_saved;
220
221 if (zone_list(NULL, &nzids) != 0)
222 return (errno);
223 again:
224 nzids *= 2;
225 if ((zids = malloc(nzids * sizeof (zoneid_t))) == NULL)
226 return (errno);
245 static int
246 dlmgmt_init(void)
247 {
248 int err;
249 char *fmri, *c;
250 char filename[MAXPATHLEN];
251
252 if (dladm_open(&dld_handle) != DLADM_STATUS_OK) {
253 dlmgmt_log(LOG_ERR, "dladm_open() failed");
254 return (EPERM);
255 }
256
257 if (signal(SIGTERM, dlmgmtd_exit) == SIG_ERR ||
258 signal(SIGINT, dlmgmtd_exit) == SIG_ERR) {
259 err = errno;
260 dlmgmt_log(LOG_ERR, "signal() for SIGTERM/INT failed: %s",
261 strerror(err));
262 return (err);
263 }
264
265 /*
266 * First derive the name of the cache file from the FMRI name. This
267 * cache name is used to keep active datalink configuration.
268 */
269 if (debug) {
270 (void) snprintf(cachefile, MAXPATHLEN, "%s/%s%s",
271 DLMGMT_TMPFS_DIR, progname, ".debug.cache");
272 } else {
273 if ((fmri = getenv("SMF_FMRI")) == NULL) {
274 dlmgmt_log(LOG_ERR, "dlmgmtd is an smf(5) managed "
275 "service and should not be run from the command "
276 "line.");
277 return (EINVAL);
278 }
279
280 /*
281 * The FMRI name is in the form of
282 * svc:/service/service:instance. We need to remove the
283 * prefix "svc:/" and replace '/' with '-'. The cache file
284 * name is in the form of "service:instance.cache".
|
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 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2014 Joyent, Inc. All rights reserved.
26 */
27
28 /*
29 * The dlmgmtd daemon is started by the datalink-management SMF service.
30 * This daemon is used to manage <link name, linkid> mapping and the
31 * persistent datalink configuration.
32 *
33 * Today, the <link name, linkid> mapping and the persistent configuration
34 * of datalinks is kept in /etc/dladm/datalink.conf, and the daemon keeps
35 * a copy of the datalinks in the memory (see dlmgmt_id_avl and
36 * dlmgmt_name_avl). The active <link name, linkid> mapping is kept in
37 * /etc/svc/volatile/dladm cache file, so that the mapping can be recovered
38 * when dlmgmtd exits for some reason (e.g., when dlmgmtd is accidentally
39 * killed).
40 */
41
42 #include <assert.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <priv.h>
115 static void
116 dlmgmt_door_fini(void)
117 {
118 if (dlmgmt_door_fd == -1)
119 return;
120
121 if (door_revoke(dlmgmt_door_fd) == -1) {
122 dlmgmt_log(LOG_WARNING, "door_revoke(%s) failed: %s",
123 DLMGMT_DOOR, strerror(errno));
124 }
125 (void) dlmgmt_set_doorfd(B_FALSE);
126 dlmgmt_door_fd = -1;
127 }
128
129 int
130 dlmgmt_door_attach(zoneid_t zoneid, char *rootdir)
131 {
132 int fd;
133 int err = 0;
134 char doorpath[MAXPATHLEN];
135 struct stat statbuf;
136
137 /* Handle running in a non-native branded zone (i.e. has /native) */
138 (void) snprintf(doorpath, sizeof (doorpath), "%s/native%s",
139 rootdir, DLMGMT_TMPFS_DIR);
140 if (stat(doorpath, &statbuf) == 0) {
141 (void) snprintf(doorpath, sizeof (doorpath), "%s/native%s",
142 rootdir, DLMGMT_DOOR);
143 } else {
144 (void) snprintf(doorpath, sizeof (doorpath), "%s%s",
145 rootdir, DLMGMT_DOOR);
146 }
147
148 /*
149 * Create the door file for dlmgmtd.
150 */
151 if ((fd = open(doorpath, O_CREAT|O_RDONLY, 0644)) == -1) {
152 err = errno;
153 dlmgmt_log(LOG_ERR, "open(%s) failed: %s", doorpath,
154 strerror(err));
155 return (err);
156 }
157 (void) close(fd);
158 if (chown(doorpath, UID_DLADM, GID_NETADM) == -1)
159 return (errno);
160
161 /*
162 * fdetach first in case a previous daemon instance exited
163 * ungracefully.
164 */
165 (void) fdetach(doorpath);
166 if (fattach(dlmgmt_door_fd, doorpath) != 0) {
185 int
186 dlmgmt_zone_init(zoneid_t zoneid)
187 {
188 char rootdir[MAXPATHLEN], tmpfsdir[MAXPATHLEN];
189 int err;
190 struct stat statbuf;
191
192 if (zoneid == GLOBAL_ZONEID) {
193 rootdir[0] = '\0';
194 } else if (zone_getattr(zoneid, ZONE_ATTR_ROOT, rootdir,
195 sizeof (rootdir)) < 0) {
196 return (errno);
197 }
198
199 /*
200 * Create the DLMGMT_TMPFS_DIR directory.
201 */
202 (void) snprintf(tmpfsdir, sizeof (tmpfsdir), "%s%s", rootdir,
203 DLMGMT_TMPFS_DIR);
204 if (stat(tmpfsdir, &statbuf) < 0) {
205 if (mkdir(tmpfsdir, (mode_t)0755) < 0) {
206 /*
207 * Handle running in a non-native branded zone
208 * (i.e. has /native)
209 */
210 (void) snprintf(tmpfsdir, sizeof (tmpfsdir),
211 "%s/native%s", rootdir, DLMGMT_TMPFS_DIR);
212 if (mkdir(tmpfsdir, (mode_t)0755) < 0)
213 return (errno);
214 }
215 } else if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
216 return (ENOTDIR);
217 }
218
219 if ((chmod(tmpfsdir, 0755) < 0) ||
220 (chown(tmpfsdir, UID_DLADM, GID_NETADM) < 0)) {
221 return (EPERM);
222 }
223
224 if ((err = dlmgmt_db_init(zoneid, rootdir)) != 0)
225 return (err);
226 return (dlmgmt_door_attach(zoneid, rootdir));
227 }
228
229 /*
230 * Initialize each running zone.
231 */
232 static int
233 dlmgmt_allzones_init(void)
234 {
235 int err, i;
236 zoneid_t *zids = NULL;
237 uint_t nzids, nzids_saved;
238
239 if (zone_list(NULL, &nzids) != 0)
240 return (errno);
241 again:
242 nzids *= 2;
243 if ((zids = malloc(nzids * sizeof (zoneid_t))) == NULL)
244 return (errno);
263 static int
264 dlmgmt_init(void)
265 {
266 int err;
267 char *fmri, *c;
268 char filename[MAXPATHLEN];
269
270 if (dladm_open(&dld_handle) != DLADM_STATUS_OK) {
271 dlmgmt_log(LOG_ERR, "dladm_open() failed");
272 return (EPERM);
273 }
274
275 if (signal(SIGTERM, dlmgmtd_exit) == SIG_ERR ||
276 signal(SIGINT, dlmgmtd_exit) == SIG_ERR) {
277 err = errno;
278 dlmgmt_log(LOG_ERR, "signal() for SIGTERM/INT failed: %s",
279 strerror(err));
280 return (err);
281 }
282
283 (void) unlink(ZONE_LOCK);
284
285 /*
286 * First derive the name of the cache file from the FMRI name. This
287 * cache name is used to keep active datalink configuration.
288 */
289 if (debug) {
290 (void) snprintf(cachefile, MAXPATHLEN, "%s/%s%s",
291 DLMGMT_TMPFS_DIR, progname, ".debug.cache");
292 } else {
293 if ((fmri = getenv("SMF_FMRI")) == NULL) {
294 dlmgmt_log(LOG_ERR, "dlmgmtd is an smf(5) managed "
295 "service and should not be run from the command "
296 "line.");
297 return (EINVAL);
298 }
299
300 /*
301 * The FMRI name is in the form of
302 * svc:/service/service:instance. We need to remove the
303 * prefix "svc:/" and replace '/' with '-'. The cache file
304 * name is in the form of "service:instance.cache".
|