Ejemplo n.º 1
0
static void
smbd_sig_handler(int sigval)
{
	if (smbd.s_sigval == 0)
		(void) atomic_swap_uint(&smbd.s_sigval, sigval);

	if (sigval == SIGHUP) {
		atomic_inc_uint(&smbd.s_refreshes);
		(void) pthread_cond_signal(&refresh_cond);
	}

	if (sigval == SIGINT || sigval == SIGTERM) {
		smbd.s_shutting_down = B_TRUE;
		(void) pthread_cond_signal(&refresh_cond);
	}
}
Ejemplo n.º 2
0
/*ARGSUSED*/
static void *
smbd_refresh_monitor(void *arg)
{
	smbd_online_wait("smbd_refresh_monitor");

	while (!smbd.s_shutting_down) {
		(void) sleep(SMBD_REFRESH_INTERVAL);

		(void) pthread_mutex_lock(&refresh_mutex);
		while ((atomic_swap_uint(&smbd.s_refreshes, 0) == 0) &&
		    (!smbd.s_shutting_down))
			(void) pthread_cond_wait(&refresh_cond, &refresh_mutex);
		(void) pthread_mutex_unlock(&refresh_mutex);

		if (smbd.s_shutting_down) {
			smbd_service_fini();
			/*NOTREACHED*/
		}

		(void) mutex_lock(&smbd_service_mutex);

		smbd_dc_monitor_refresh();
		smb_ccache_remove(SMB_CCACHE_PATH);

		/*
		 * Clear the DNS zones for the existing interfaces
		 * before updating the NIC interface list.
		 */
		dyndns_clear_zones();

		if (smbd_nicmon_refresh() != 0)
			smbd_report("NIC monitor refresh failed");

		smb_netbios_name_reconfig();
		smb_browser_reconfig();
		dyndns_update_zones();
		(void) smbd_kernel_bind();
		smbd_load_shares();
		smbd_load_printers();

		(void) mutex_unlock(&smbd_service_mutex);
	}

	smbd.s_refresh_tid = 0;
	return (NULL);
}
Ejemplo n.º 3
0
/*
 * Shutdown smbd and smbsrv kernel services.
 *
 * Shutdown will not begin until initialization has completed.
 * Only one thread is allowed to perform the shutdown.  Other
 * threads will be blocked on fini_in_progress until the process
 * has exited.
 */
static void
smbd_service_fini(void)
{
	static uint_t	fini_in_progress;

	(void) mutex_lock(&smbd_service_mutex);

	while (!smbd.s_initialized)
		(void) cond_wait(&smbd_service_cv, &smbd_service_mutex);

	if (atomic_swap_uint(&fini_in_progress, 1) != 0) {
		while (fini_in_progress)
			(void) cond_wait(&smbd_service_cv, &smbd_service_mutex);
		/*NOTREACHED*/
	}

	smbd.s_shutting_down = B_TRUE;
	smbd_report("service shutting down");

	smb_kmod_stop();
	smb_logon_abort();
	smb_lgrp_stop();
	smbd_opipe_stop();
	smbd_door_stop();
	smbd_refresh_fini();
	smbd_kernel_unbind();
	smbd_share_stop();
	smb_shr_stop();
	dyndns_stop();
	smbd_nicmon_stop();
	smb_ccache_remove(SMB_CCACHE_PATH);
	smb_pwd_fini();
	smb_domain_fini();
	mlsvc_fini();
	smb_netbios_stop();
	smbd_cups_fini();

	smbd.s_initialized = B_FALSE;
	smbd_report("service terminated");
	(void) mutex_unlock(&smbd_service_mutex);
	exit((smbd.s_fatal_error) ? SMF_EXIT_ERR_FATAL : SMF_EXIT_OK);
}
Ejemplo n.º 4
0
/*
 * Process IPIs for a CPU.
 */
int
mips64_ipi_intr(void *arg)
{
	unsigned int pending_ipis, bit;
	unsigned int cpuid = (unsigned int)(unsigned long)arg;

	KASSERT (cpuid == cpu_number());

	/* clear ipi interrupt */
	hw_ipi_intr_clear(cpuid);
	/* get and clear pending ipis */
	pending_ipis = atomic_swap_uint(&ipi_mailbox[cpuid], 0);
	
	if (pending_ipis > 0) {
		for (bit = 0; bit < MIPS64_NIPIS; bit++)
			if (pending_ipis & (1UL << bit))
				(*ipifuncs[bit])();
	}

	return 1;
}
Ejemplo n.º 5
0
void
vnet_send_dring_data(struct vnet_softc *sc, uint32_t start_idx)
{
	struct vio_dring_msg dm;
	u_int peer_state;

	peer_state = atomic_swap_uint(&sc->sc_peer_state, VIO_DP_ACTIVE);
	if (peer_state == VIO_DP_ACTIVE)
		return;

	bzero(&dm, sizeof(dm));
	dm.tag.type = VIO_TYPE_DATA;
	dm.tag.stype = VIO_SUBTYPE_INFO;
	dm.tag.stype_env = VIO_DRING_DATA;
	dm.tag.sid = sc->sc_local_sid;
	dm.seq_no = sc->sc_seq_no++;
	dm.dring_ident = sc->sc_dring_ident;
	dm.start_idx = start_idx;
	dm.end_idx = -1;
	vnet_sendmsg(sc, &dm, sizeof(dm));
}
Ejemplo n.º 6
0
void
*measure_thread(void *arg)
{
	int c, i;
	int throughput;
        for (c = 1 ;; c++) {
                sleep(2);
                throughput = 0;
                for (i = 0; i < nthreads; i++) {
#if defined(__sun)
                        throughput += atomic_swap_uint(&counters[i], 0);
#endif

#if defined(linux)
                        throughput += __sync_lock_test_and_set(&counters[i], 0);
#endif
		}
                //printf("%d\t%d\n", c, throughput);
		printf("%d\n", throughput);
                fflush(stdout);
        }
}
Ejemplo n.º 7
0
void
x86_ipi_handler(void)
{
	extern struct evcount ipi_count;
	struct cpu_info *ci = curcpu();
	u_int32_t pending;
	int bit;
	int floor;

	floor = ci->ci_handled_intr_level;
	ci->ci_handled_intr_level = ci->ci_ilevel;

	pending = atomic_swap_uint(&ci->ci_ipis, 0);
	for (bit = 0; bit < X86_NIPI && pending; bit++) {
		if (pending & (1<<bit)) {
			pending &= ~(1<<bit);
			(*ipifunc[bit])(ci);
			ipi_count.ec_count++;
		}
	}

	ci->ci_handled_intr_level = floor;
}
Ejemplo n.º 8
0
/*
 * Use SMF error codes only on return or exit.
 */
int
main(int argc, char *argv[])
{
	struct sigaction	act;
	sigset_t		set;
	uid_t			uid;
	int			pfd = -1;
	uint_t			sigval;
	struct rlimit		rl;
	int			orig_limit;

	smbd.s_pname = basename(argv[0]);
	openlog(smbd.s_pname, LOG_PID | LOG_NOWAIT, LOG_DAEMON);

	if (smbd_setup_options(argc, argv) != 0)
		return (SMF_EXIT_ERR_FATAL);

	if ((uid = getuid()) != smbd.s_uid) {
		smbd_report("user %d: %s", uid, strerror(EPERM));
		return (SMF_EXIT_ERR_FATAL);
	}

	if (getzoneid() != GLOBAL_ZONEID) {
		smbd_report("non-global zones are not supported");
		return (SMF_EXIT_ERR_FATAL);
	}

	if (is_system_labeled()) {
		smbd_report("Trusted Extensions not supported");
		return (SMF_EXIT_ERR_FATAL);
	}

	if (smbd_already_running())
		return (SMF_EXIT_OK);

	/*
	 * Raise the file descriptor limit to accommodate simultaneous user
	 * authentications/file access.
	 */
	if ((getrlimit(RLIMIT_NOFILE, &rl) == 0) &&
	    (rl.rlim_cur < rl.rlim_max)) {
		orig_limit = rl.rlim_cur;
		rl.rlim_cur = rl.rlim_max;
		if (setrlimit(RLIMIT_NOFILE, &rl) != 0)
			smbd_report("Failed to raise file descriptor limit"
			    " from %d to %d", orig_limit, rl.rlim_cur);
	}

	(void) sigfillset(&set);
	(void) sigdelset(&set, SIGABRT);

	(void) sigfillset(&act.sa_mask);
	act.sa_handler = smbd_sig_handler;
	act.sa_flags = 0;

	(void) sigaction(SIGABRT, &act, NULL);
	(void) sigaction(SIGTERM, &act, NULL);
	(void) sigaction(SIGHUP, &act, NULL);
	(void) sigaction(SIGINT, &act, NULL);
	(void) sigaction(SIGPIPE, &act, NULL);
	(void) sigaction(SIGUSR1, &act, NULL);

	(void) sigdelset(&set, SIGTERM);
	(void) sigdelset(&set, SIGHUP);
	(void) sigdelset(&set, SIGINT);
	(void) sigdelset(&set, SIGPIPE);
	(void) sigdelset(&set, SIGUSR1);

	if (smbd.s_fg) {
		(void) sigdelset(&set, SIGTSTP);
		(void) sigdelset(&set, SIGTTIN);
		(void) sigdelset(&set, SIGTTOU);

		if (smbd_service_init() != 0) {
			smbd_report("service initialization failed");
			exit(SMF_EXIT_ERR_FATAL);
		}
	} else {
		/*
		 * "pfd" is a pipe descriptor -- any fatal errors
		 * during subsequent initialization of the child
		 * process should be written to this pipe and the
		 * parent will report this error as the exit status.
		 */
		pfd = smbd_daemonize_init();

		if (smbd_service_init() != 0) {
			smbd_report("daemon initialization failed");
			exit(SMF_EXIT_ERR_FATAL);
		}

		smbd_daemonize_fini(pfd, SMF_EXIT_OK);
	}

	(void) atexit(smb_kmod_stop);

	while (!smbd.s_shutting_down) {
		if (smbd.s_sigval == 0 && smbd.s_refreshes == 0)
			(void) sigsuspend(&set);

		sigval = atomic_swap_uint(&smbd.s_sigval, 0);

		switch (sigval) {
		case 0:
		case SIGPIPE:
		case SIGABRT:
			break;

		case SIGHUP:
			syslog(LOG_DEBUG, "refresh requested");
			(void) pthread_cond_signal(&refresh_cond);
			break;

		case SIGUSR1:
			smb_log_dumpall();
			break;

		default:
			/*
			 * Typically SIGINT or SIGTERM.
			 */
			smbd.s_shutting_down = B_TRUE;
			break;
		}
	}

	smbd_service_fini();
	closelog();
	return ((smbd.s_fatal_error) ? SMF_EXIT_ERR_FATAL : SMF_EXIT_OK);
}