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.
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.
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]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * bridged - bridging control daemon.
39 #include <sys/types.h>
49 const char *instance_name
= "default";
51 struct pollfd
*fdarray
;
53 dladm_handle_t dlhandle
;
55 boolean_t shutting_down
;
57 static pthread_t sighand
;
60 * engine_lock is held while the main loop is busy calling librstp functions.
61 * Door threads take the lock to protect the library from reentrancy.
63 static pthread_mutex_t engine_lock
= PTHREAD_MUTEX_INITIALIZER
;
66 * These wrapper functions allow the other components in the daemon to remain
67 * ignorant of pthreads details.
72 return (pthread_mutex_lock(&engine_lock
));
78 (void) pthread_mutex_unlock(&engine_lock
);
82 * Utility function for STREAMS ioctls.
85 strioctl(int fd
, int cmd
, void *buf
, size_t buflen
)
94 if ((retv
= ioctl(fd
, I_STR
, &ic
)) != 0)
106 * A little bit of magic here. By the first fork+setsid, we
107 * disconnect from our current controlling terminal and become
108 * a session group leader. By forking again without calling
109 * setsid again, we make certain that we are not the session
110 * group leader and can never reacquire a controlling terminal.
112 if ((pid
= fork()) == (pid_t
)-1) {
113 syslog(LOG_ERR
, "fork 1 failed");
120 if (setsid() == (pid_t
)-1) {
121 syslog(LOG_ERR
, "setsid");
124 if ((pid
= fork()) == (pid_t
)-1) {
125 syslog(LOG_ERR
, "fork 2 failed");
135 sighandler(void *arg
)
139 int sigfd
= (int)(uintptr_t)arg
;
141 (void) sigfillset(&sigset
);
144 sig
= sigwait(&sigset
);
147 (void) write(sigfd
, "", 1);
152 syslog(LOG_NOTICE
, "%s signal, shutting down",
154 shutting_down
= B_TRUE
;
158 /* if we're shutting down, exit this thread */
165 init_signalhandling(void)
172 if ((fdarray
= malloc(FDOFFSET
* sizeof (struct pollfd
))) == NULL
) {
173 syslog(LOG_ERR
, "unable to allocate fdarray: %m");
176 if (pipe(fildes
) != 0) {
177 syslog(LOG_ERR
, "unable to create signal pipe: %m");
180 fdarray
[0].fd
= fildes
[0];
181 fdarray
[0].events
= POLLIN
;
182 assert(control_fd
!= -1);
183 fdarray
[1].fd
= control_fd
;
184 fdarray
[1].events
= POLLIN
;
186 (void) sigfillset(&new);
187 (void) pthread_sigmask(SIG_BLOCK
, &new, NULL
);
188 (void) pthread_attr_init(&attr
);
189 (void) pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
190 err
= pthread_create(&sighand
, &attr
, sighandler
,
191 (void *)(uintptr_t)fildes
[1]);
193 syslog(LOG_ERR
, "cannot create signal handling thread: %s",
197 (void) pthread_attr_destroy(&attr
);
201 main(int argc
, char **argv
)
203 dladm_status_t status
;
204 char buf
[DLADM_STRSIZE
];
206 (void) setlocale(LC_ALL
, "");
207 (void) textdomain(TEXT_DOMAIN
);
209 shutting_down
= B_FALSE
;
210 openlog("bridged", LOG_PID
| LOG_NDELAY
, LOG_DAEMON
);
213 syslog(LOG_ERR
, "instance name is required");
217 instance_name
= argv
[1];
219 if ((status
= dladm_open(&dlhandle
)) != DLADM_STATUS_OK
) {
220 syslog(LOG_ERR
, "%s: unable to open datalink control: %s",
221 instance_name
, dladm_status2str(status
, buf
));
225 status
= dladm_bridge_get_privprop(instance_name
, &debugging
,
227 if (status
!= DLADM_STATUS_OK
) {
228 syslog(LOG_ERR
, "%s: unable to read properties: %s",
229 instance_name
, dladm_status2str(status
, buf
));
233 /* Get the properties once so that we have the right initial values */
236 open_bridge_control();
240 init_signalhandling();
244 syslog(LOG_INFO
, "bridged started: instance %s", instance_name
);
247 (void) pthread_cancel(sighand
);
248 (void) pthread_join(sighand
, NULL
);