Пример #1
0
/*
 * Parse path components and apply requested matching rule at
 * directory level.
 */
static void
process_rule(struct sdev_node *dir, struct sdev_node *gdir,
    char *path, char *tgt, int type)
{
	char *name;
	struct pathname	pn;
	int rv = 0;

	if ((strlen(path) > 5) && (strncmp(path, "/dev/", 5) == 0)) {
		path += 5;
	}

	if (pn_get(path, UIO_SYSSPACE, &pn) != 0)
		return;

	name = kmem_alloc(MAXPATHLEN, KM_SLEEP);
	(void) pn_getcomponent(&pn, name);
	pn_skipslash(&pn);
	SDEV_HOLD(dir);

	while (pn_pathleft(&pn)) {
		/* If this is pattern, just add the pattern */
		if (strpbrk(name, "*?[]") != NULL &&
		    (type == PROFILE_TYPE_INCLUDE ||
		    type == PROFILE_TYPE_EXCLUDE)) {
			ASSERT(tgt == NULL);
			tgt = pn.pn_path;
			break;
		}
		if ((rv = prof_make_dir(name, &gdir, &dir)) != 0) {
			cmn_err(CE_CONT, "process_rule: %s error %d\n",
			    path, rv);
			break;
		}
		(void) pn_getcomponent(&pn, name);
		pn_skipslash(&pn);
	}

	/* process the leaf component */
	if (rv == 0) {
		prof_add_rule(name, tgt, dir, type);
		SDEV_SIMPLE_RELE(dir);
	}

	kmem_free(name, MAXPATHLEN);
	pn_free(&pn);
}
Пример #2
0
/*
 * Clean pts sdev_nodes that are no longer valid.
 */
static void
devpts_prunedir(struct sdev_node *ddv)
{
	struct vnode *vp;
	struct sdev_node *dv, *next = NULL;
	int (*vtor)(struct sdev_node *) = NULL;

	ASSERT(ddv->sdev_flags & SDEV_VTOR);

	vtor = (int (*)(struct sdev_node *))sdev_get_vtor(ddv);
	ASSERT(vtor);

	if (rw_tryupgrade(&ddv->sdev_contents) == NULL) {
		rw_exit(&ddv->sdev_contents);
		rw_enter(&ddv->sdev_contents, RW_WRITER);
	}

	for (dv = ddv->sdev_dot; dv; dv = next) {
		next = dv->sdev_next;

		/* skip stale nodes */
		if (dv->sdev_flags & SDEV_STALE)
			continue;

		/* validate and prune only ready nodes */
		if (dv->sdev_state != SDEV_READY)
			continue;

		switch (vtor(dv)) {
		case SDEV_VTOR_VALID:
		case SDEV_VTOR_SKIP:
			continue;
		case SDEV_VTOR_INVALID:
			sdcmn_err7(("prunedir: destroy invalid "
			    "node: %s(%p)\n", dv->sdev_name, (void *)dv));
			break;
		}
		vp = SDEVTOV(dv);
		if (vp->v_count > 0)
			continue;
		SDEV_HOLD(dv);
		/* remove the cache node */
		(void) sdev_cache_update(ddv, &dv, dv->sdev_name,
		    SDEV_CACHE_DELETE);
	}
	rw_downgrade(&ddv->sdev_contents);
}
Пример #3
0
/*
 * First step in refreshing directory contents.
 * Remove each invalid entry and rebuild the link
 * reference for each stale entry.
 */
static void
devvt_prunedir(struct sdev_node *ddv)
{
	struct vnode *vp;
	struct sdev_node *dv, *next = NULL;
	int (*vtor)(struct sdev_node *) = NULL;

	ASSERT(ddv->sdev_flags & SDEV_VTOR);

	vtor = (int (*)(struct sdev_node *))sdev_get_vtor(ddv);
	ASSERT(vtor);

	for (dv = SDEV_FIRST_ENTRY(ddv); dv; dv = next) {
		next = SDEV_NEXT_ENTRY(ddv, dv);

		switch (vtor(dv)) {
		case SDEV_VTOR_VALID:
			break;
		case SDEV_VTOR_SKIP:
			break;
		case SDEV_VTOR_INVALID:
			vp = SDEVTOV(dv);
			if (vp->v_count != 0)
				break;
			/* remove the cached node */
			SDEV_HOLD(dv);
			(void) sdev_cache_update(ddv, &dv,
			    dv->sdev_name, SDEV_CACHE_DELETE);
			SDEV_RELE(dv);
			break;
		case SDEV_VTOR_STALE:
			devvt_rebuild_stale_link(ddv, dv);
			break;
		}
	}
}