Пример #1
0
/*
 * Get a linked list of all the shares on the system from /etc/dfs/dfstab
 */
fs_sharelist_t *
fs_get_share_list(int *errp)
{
	fs_sharelist_t	*newp;
	fs_sharelist_t	*headp;
	fs_sharelist_t	*tailp;
	FILE		*fp;

	headp = NULL;
	tailp = NULL;

	if ((fp = fopen(SHARETAB, "r")) != NULL) {
		struct share	*sharetab_entry;

		(void) mutex_lock(&sharetab_lock);
		while (getshare(fp, &sharetab_entry) > 0) {

			newp = create_sharelist_entry(sharetab_entry, errp);
			if (newp == NULL) {
				/*
				 * Out of memory
				 */
				fs_free_share_list(headp);
				(void) mutex_unlock(&sharetab_lock);
				(void) fclose(fp);
				return (NULL);
			}

			if (headp == NULL) {
				headp = newp;
				tailp = newp;
			} else {
				tailp->next = newp;
				tailp = newp;
			}

		} /* while (getshare(fp, &sharetab_entry) != 0) */
		(void) mutex_unlock(&sharetab_lock);
		(void) fclose(fp);
	} else {
		*errp = errno;
	} /* if ((fp = fopen(SHARETAB, "r")) != NULL) */

	/*
	 * Caller must free the mount list
	 */
	return (headp);
} /* fs_get_share_list */
Пример #2
0
void
check_sharetab()
{
	FILE *f;
	struct stat st;
	static timestruc_t last_sharetab_time;
	timestruc_t prev_sharetab_time;
	struct share *sh;
	struct sh_list *shp, *shp_prev;
	int res, c = 0;

	/*
	 *  read in /etc/dfs/sharetab if it has changed
	 */

	if (stat(SHARETAB, &st) != 0) {
		syslog(LOG_ERR, "Cannot stat %s: %m", SHARETAB);
		return;
	}

	if (st.st_mtim.tv_sec == last_sharetab_time.tv_sec &&
	    st.st_mtim.tv_nsec == last_sharetab_time.tv_nsec) {
		/*
		 * No change.
		 */
		return;
	}

	/*
	 * Remember the mod time, then after getting the
	 * write lock check again.  If another thread
	 * already did the update, then there's no
	 * work to do.
	 */
	prev_sharetab_time = last_sharetab_time;

	(void) rw_wrlock(&sharetab_lock);

	if (prev_sharetab_time.tv_sec != last_sharetab_time.tv_sec ||
	    prev_sharetab_time.tv_nsec != last_sharetab_time.tv_nsec) {
		(void) rw_unlock(&sharetab_lock);
		return;
	}

	f = fopen(SHARETAB, "r+");
	if (f == NULL) {
		syslog(LOG_ERR, "Cannot open %s: %m", SHARETAB);
		(void) rw_unlock(&sharetab_lock);
		return;
	}

	/*
	 * Lock the file so that unshare can't
	 * truncate it while we're reading
	 */
	if (lockf(fileno(f), F_LOCK, 0L) < 0) {
		syslog(LOG_ERR, "Cannot lock %s: %m", SHARETAB);
		(void) rw_unlock(&sharetab_lock);
		(void) fclose(f);
		return;
	}

	/*
	 * Once we are sure /etc/dfs/sharetab has been
	 * modified, flush netgroup cache entries.
	 */
	netgrp_cache_flush();

	sh_free(share_list);			/* free old list */
	share_list = NULL;

	while ((res = getshare(f, &sh)) > 0) {
		c++;
		if (strcmp(sh->sh_fstype, "nfs") != 0)
			continue;

		shp = malloc(sizeof (*shp));
		if (shp == NULL)
			goto alloc_failed;
		if (share_list == NULL)
			share_list = shp;
		else
			/* LINTED not used before set */
			shp_prev->shl_next = shp;
		shp_prev = shp;
		shp->shl_next = NULL;
		shp->shl_sh = sharedup(sh);
		if (shp->shl_sh == NULL)
			goto alloc_failed;
	}
	if (res < 0)
		syslog(LOG_ERR, "%s: invalid at line %d\n",
			SHARETAB, c + 1);

	if (stat(SHARETAB, &st) != 0) {
		syslog(LOG_ERR, "Cannot stat %s: %m", SHARETAB);
		(void) rw_unlock(&sharetab_lock);
		return;
	}
	last_sharetab_time = st.st_mtim;
	(void) fclose(f);
	(void) rw_unlock(&sharetab_lock);
	return;

alloc_failed:
	syslog(LOG_ERR, "check_sharetab: no memory");
	sh_free(share_list);
	share_list = NULL;
	(void) fclose(f);
	(void) rw_unlock(&sharetab_lock);
}