Пример #1
0
/*
 * Restart the smb service.
 */
int
smb_smf_restart_service(void)
{
	return (smf_restart_instance(SMBD_DEFAULT_INSTANCE_FMRI));
}
Пример #2
0
/*
 * _nscd_restart_if_cfgfile_changed()
 * Restart if modification times of nsswitch.conf or resolv.conf have changed.
 *
 * If nsswitch.conf has changed then it is possible that sources for
 * various backends have changed and therefore the current cached
 * data may not be consistent with the new data sources.  By
 * restarting the cache will be cleared and the new configuration will
 * be used.
 *
 * The check for resolv.conf is made as only the first call to
 * res_gethostbyname() or res_getaddrbyname() causes a call to
 * res_ninit() to occur which in turn parses resolv.conf.  Therefore
 * to benefit from changes to resolv.conf nscd must be restarted when
 * resolv.conf is updated, removed or created.  If res_getXbyY calls
 * are removed from NSS then this check could be removed.
 *
 */
void
_nscd_restart_if_cfgfile_changed()
{

	static mutex_t		nsswitch_lock = DEFAULTMUTEX;
	static timestruc_t	last_nsswitch_check = { 0 };
	static timestruc_t	last_nsswitch_modified = { 0 };
	static timestruc_t	last_resolv_modified = { -1, 0 };
	static mutex_t		restarting_lock = DEFAULTMUTEX;
	static int 		restarting = 0;
	int			restart = 0;
	time_t			now = time(NULL);
	char			*me = "_nscd_restart_if_cfgfile_changed";

#define	FLAG_RESTART_REQUIRED	if (restarting == 0) {\
					(void) mutex_lock(&restarting_lock);\
					if (restarting == 0) {\
						restarting = 1;\
						restart = 1;\
					}\
					(void) mutex_unlock(&restarting_lock);\
				}

	if (restarting == 1)
		return;

	if (now - last_nsswitch_check.tv_sec < _NSC_FILE_CHECK_TIME)
		return;

	(void) mutex_lock(&nsswitch_lock);

	if (now - last_nsswitch_check.tv_sec >= _NSC_FILE_CHECK_TIME) {
		struct stat nss_buf;
		struct stat res_buf;

		last_nsswitch_check.tv_sec = now;
		last_nsswitch_check.tv_nsec = 0;

		(void) mutex_unlock(&nsswitch_lock); /* let others continue */

		if (stat("/etc/nsswitch.conf", &nss_buf) < 0) {
			return;
		} else if (last_nsswitch_modified.tv_sec == 0) {
			last_nsswitch_modified = nss_buf.st_mtim;
		}

		if (last_nsswitch_modified.tv_sec < nss_buf.st_mtim.tv_sec ||
		    (last_nsswitch_modified.tv_sec == nss_buf.st_mtim.tv_sec &&
		    last_nsswitch_modified.tv_nsec < nss_buf.st_mtim.tv_nsec)) {
			FLAG_RESTART_REQUIRED;
		}

		if (restart == 0) {
			if (stat("/etc/resolv.conf", &res_buf) < 0) {
				/* Unable to stat file, were we previously? */
				if (last_resolv_modified.tv_sec > 0) {
					/* Yes, it must have been removed. */
					FLAG_RESTART_REQUIRED;
				} else if (last_resolv_modified.tv_sec == -1) {
					/* No, then we've never seen it. */
					last_resolv_modified.tv_sec = 0;
				}
			} else if (last_resolv_modified.tv_sec == -1) {
				/* We've just started and file is present. */
				last_resolv_modified = res_buf.st_mtim;
			} else if (last_resolv_modified.tv_sec == 0) {
				/* Wasn't there at start-up. */
				FLAG_RESTART_REQUIRED;
			} else if (last_resolv_modified.tv_sec <
			    res_buf.st_mtim.tv_sec ||
			    (last_resolv_modified.tv_sec ==
			    res_buf.st_mtim.tv_sec &&
			    last_resolv_modified.tv_nsec <
			    res_buf.st_mtim.tv_nsec)) {
				FLAG_RESTART_REQUIRED;
			}
		}

		if (restart == 1) {
			char *fmri;

			/*
			 * if in self cred mode, kill the forker and
			 * child nscds
			 */
			if (_nscd_is_self_cred_on(0, NULL)) {
				_nscd_kill_forker();
				_nscd_kill_all_children();
			}

			/*
			 * time for restart
			 */
			_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_INFO)
			(me, "nscd restart due to %s or %s change\n",
			    "/etc/nsswitch.conf", "resolv.conf");
			/*
			 * try to restart under smf
			 */
			if ((fmri = getenv("SMF_FMRI")) == NULL) {
				/* not running under smf - reexec */
				(void) execv(main_execname, main_argv);
				exit(1); /* just in case */
			}

			if (smf_restart_instance(fmri) == 0)
				(void) sleep(10); /* wait a bit */
			exit(1); /* give up waiting for resurrection */
		}

	} else
		(void) mutex_unlock(&nsswitch_lock);
}