コード例 #1
0
int
dm_set_disp(
	dm_sessid_t	sid,
	void		*hanp,
	size_t		hlen,
	dm_token_t	token,
	dm_eventset_t	*eventsetp,
	u_int		maxevent)
{
	dm_session_t	*s;
	dm_fsreg_t	*fsrp;
	dm_tokdata_t	*tdp;
	dm_eventset_t	eventset;
	int		error;
	int		lc1;		/* first lock cookie */
	int		lc2;		/* second lock cookie */
	u_int		i;

	/* Copy in and validate the event mask.  Only the lower maxevent bits
	   are meaningful, so clear any bits set above maxevent.
	*/

	if (maxevent == 0 || maxevent > DM_EVENT_MAX)
		return(EINVAL);
	if (copy_from_user(&eventset, eventsetp, sizeof(eventset)))
		return(EFAULT);
	eventset &= (1 << maxevent) - 1;

	/* If the caller specified the global handle, then the only valid token
	   is DM_NO_TOKEN, and the only valid event in the event mask is
	   DM_EVENT_MOUNT.  If it is set, add the session to the list of
	   sessions that want to receive mount events.  If it is clear, remove
	   the session from the list.  Since DM_EVENT_MOUNT events never block
	   waiting for a session to register, there is noone to wake up if we
	   do add the session to the list.
	*/

	if (DM_GLOBALHAN(hanp, hlen)) {
		if (token != DM_NO_TOKEN)
			return(EINVAL);
		if ((error = dm_find_session_and_lock(sid, &s, &lc1)) != 0)
			return(error);
		if (eventset == 0) {
			s->sn_flags &= ~DM_SN_WANTMOUNT;
			error = 0;
		} else if (eventset == 1 << DM_EVENT_MOUNT) {
			s->sn_flags |= DM_SN_WANTMOUNT;
			error = 0;
		} else {
			error = EINVAL;
		}
		mutex_spinunlock(&s->sn_qlock, lc1);
		return(error);
	}

	/* Since it's not the global handle, it had better be a filesystem
	   handle.  Verify that the first 'maxevent' events in the event list
	   are all valid for a filesystem handle.
	*/

	if (eventset & ~DM_VALID_DISP_EVENTS)
		return(EINVAL);

	/* Verify that the session is valid, that the handle is a filesystem
	   handle, and that the filesystem is capable of sending events.  (If
	   a dm_fsreg_t structure exists, then the filesystem can issue events.)
	*/

	error = dm_app_get_tdp(sid, hanp, hlen, token, DM_TDT_VFS,
		DM_RIGHT_EXCL, &tdp);
	if (error != 0)
		return(error);

	fsrp = dm_find_fsreg_and_lock((fsid_t*)&tdp->td_handle.ha_fsid, &lc1);
	if (fsrp == NULL) {
		dm_app_put_tdp(tdp);
		return(EINVAL);
	}

	/* Now that we own 'fsrp->fr_lock', get the lock on the session so that
	   it can't disappear while we add it to the filesystem's event mask.
	*/

	if ((error = dm_find_session_and_lock(sid, &s, &lc2)) != 0) {
		mutex_spinunlock(&fsrp->fr_lock, lc1);
		dm_app_put_tdp(tdp);
		return(error);
	}

	/* Update the event disposition array for this filesystem, adding
	   and/or removing the session as appropriate.  If this session is
	   dropping registration for DM_EVENT_DESTROY, or is overriding some
	   other session's registration for DM_EVENT_DESTROY, then clear any
	   any attr-on-destroy attribute name also.
	*/

	for (i = 0; i < DM_EVENT_MAX; i++) {
		if (DMEV_ISSET(i, eventset)) {
			if (i == DM_EVENT_DESTROY && fsrp->fr_sessp[i] != s)
				bzero(&fsrp->fr_rattr, sizeof(fsrp->fr_rattr));
			fsrp->fr_sessp[i] = s;
		} else if (fsrp->fr_sessp[i] == s) {
			if (i == DM_EVENT_DESTROY)
				bzero(&fsrp->fr_rattr, sizeof(fsrp->fr_rattr));
			fsrp->fr_sessp[i] = NULL;
		}
	}
	mutex_spinunlock(&s->sn_qlock, lc2);	/* reverse cookie order */

	/* Wake up all processes waiting for a disposition on this filesystem
	   in case any of them happen to be waiting for an event which we just
	   added.
	*/

	if (fsrp->fr_dispcnt)
		sv_broadcast(&fsrp->fr_dispq);

	mutex_spinunlock(&fsrp->fr_lock, lc1);

	dm_app_put_tdp(tdp);
	return(0);
}
コード例 #2
0
ファイル: mls.c プロジェクト: Andiry/xfstests
/*
 * Get the complete list of events for a file.
 */
int
event_info(
	dm_sessid_t	 sid,
	void		*hanp,
	size_t		 hlen)
{
	u_int		ret;
	dm_eventset_t	eventlist;

	DMEV_ZERO(eventlist);
	if (dm_get_eventlist(sid, hanp, hlen, DM_NO_TOKEN, DM_EVENT_MAX, 
				&eventlist, &ret)) {
		errno_msg("Can't get list of events");
		return(1);
	}
	printf("\n\tEvent list: \n\t\t");
	if (DMEV_ISSET(DM_EVENT_MOUNT, eventlist)) 
		printf("mount ");
	if (DMEV_ISSET(DM_EVENT_PREUNMOUNT, eventlist)) 
		printf("preunmount ");
	if (DMEV_ISSET(DM_EVENT_UNMOUNT, eventlist)) 
		printf("unmount ");
	if (DMEV_ISSET(DM_EVENT_DEBUT, eventlist)) 
		printf("debut ");
	if (DMEV_ISSET(DM_EVENT_CREATE, eventlist)) 
		printf("create ");
	if (DMEV_ISSET(DM_EVENT_POSTCREATE, eventlist)) 
		printf("postcreate ");
	if (DMEV_ISSET(DM_EVENT_REMOVE, eventlist)) 
		printf("remove ");
	if (DMEV_ISSET(DM_EVENT_POSTREMOVE, eventlist)) 
		printf("postmount ");
	if (DMEV_ISSET(DM_EVENT_RENAME, eventlist)) 
		printf("rename ");
	if (DMEV_ISSET(DM_EVENT_POSTRENAME, eventlist)) 
		printf("postrename ");
	if (DMEV_ISSET(DM_EVENT_LINK, eventlist)) 
		printf("link ");
	if (DMEV_ISSET(DM_EVENT_POSTLINK, eventlist)) 
		printf("postlink ");
	if (DMEV_ISSET(DM_EVENT_SYMLINK, eventlist)) 
		printf("symlink ");
	if (DMEV_ISSET(DM_EVENT_POSTSYMLINK, eventlist)) 
		printf("postsymlink ");
	if (DMEV_ISSET(DM_EVENT_READ, eventlist)) 
		printf("read ");
	if (DMEV_ISSET(DM_EVENT_WRITE, eventlist)) 
		printf("write ");
	if (DMEV_ISSET(DM_EVENT_TRUNCATE, eventlist)) 
		printf("truncate ");
	if (DMEV_ISSET(DM_EVENT_ATTRIBUTE, eventlist)) 
		printf("attribute ");
	if (DMEV_ISSET(DM_EVENT_DESTROY, eventlist)) 
		printf("destroy ");
	if (DMEV_ISSET(DM_EVENT_NOSPACE, eventlist)) 
		printf("nospace ");
	if (DMEV_ISSET(DM_EVENT_USER, eventlist)) 
		printf("user ");

	printf("\n");
	return(0);
}
コード例 #3
0
int
main(
	int	argc, 
	char	**argv)
{
	dm_sessid_t	 sid = DM_NO_SESSION;
	dm_token_t	token = DM_NO_TOKEN;
	u_int		nelem = DM_EVENT_MAX;
	char		*object;
	dm_eventset_t	eventset;
	void		*hanp;
	size_t	 	 hlen;
	u_int		nelemp;
	char		*name;
	int		Fflag = 0;
	int		error;
	int		opt;
	int		i;

	if (Progname = strrchr(argv[0], '/')) {
		Progname++;
	} else {
		Progname = argv[0];
	}

	/* Crack and validate the command line options. */

	while ((opt = getopt(argc, argv, "Fn:s:t:")) != EOF) {
		switch (opt) {
		case 'F':
			Fflag++;
			break;
		case 'n':
			nelem = atol(optarg);
			break;
		case 's':
			sid = atol(optarg);
			break;
		case 't':
			token = atol(optarg);
			break;
		case '?':
			usage();
		}
	}
	if (optind + 1 != argc)
		usage();
	object = argv[optind];

	if (dm_init_service(&name) == -1)  {
		fprintf(stderr, "Can't initialize the DMAPI\n");
		exit(1);
	}

	if ((error = opaque_to_handle(object, &hanp, &hlen)) != 0) {
		fprintf(stderr, "can't get a handle from %s, %s\n",
			object, strerror(error));
		return(1);
	}

	if (Fflag) {
		void	*fshanp;
		size_t	fshlen;

		if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) {
			fprintf(stderr, "can't get filesystem handle from %s\n",
				object);
			exit(1);
		}
		dm_handle_free(hanp, hlen);
		hanp = fshanp;
		hlen = fshlen;
	}

	if (sid == DM_NO_SESSION)
		find_test_session(&sid);

	DMEV_ZERO(eventset);

	if (dm_get_eventlist(sid, hanp, hlen, token, nelem,
	    &eventset, &nelemp)) {
		fprintf(stderr, "dm_get_eventlist failed, %s\n",
			strerror(errno));
		return(1);
	}

#ifdef	VERITAS_21
	fprintf(stdout, "Events on object %s (0x%x), nelemp %d:\n",
#else
	fprintf(stdout, "Events on object %s (0x%llx), nelemp %d:\n",
#endif
		object, eventset, nelemp);

	for (i = 0; i < nelemp; i++) {
		if (!DMEV_ISSET(i, eventset))
			continue;
		switch (i) {
		case DM_EVENT_CANCEL:
			fprintf(stdout, "DM_EVENT_CANCEL");
			break;
		case DM_EVENT_MOUNT:
			fprintf(stdout, "DM_EVENT_MOUNT");
			break;
		case DM_EVENT_PREUNMOUNT:
			fprintf(stdout, "DM_EVENT_PREUNMOUNT");
			break;
		case DM_EVENT_UNMOUNT:
			fprintf(stdout, "DM_EVENT_UNMOUNT");
			break;
		case DM_EVENT_DEBUT:
			fprintf(stdout, "DM_EVENT_DEBUT");
			break;
		case DM_EVENT_CREATE:
			fprintf(stdout, "DM_EVENT_CREATE");
			break;
		case DM_EVENT_CLOSE:
			fprintf(stdout, "DM_EVENT_CLOSE");
			break;
		case DM_EVENT_POSTCREATE:
			fprintf(stdout, "DM_EVENT_POSTCREATE");
			break;
		case DM_EVENT_REMOVE:
			fprintf(stdout, "DM_EVENT_REMOVE");
			break;
		case DM_EVENT_POSTREMOVE:
			fprintf(stdout, "DM_EVENT_POSTREMOVE");
			break;
		case DM_EVENT_RENAME:
			fprintf(stdout, "DM_EVENT_RENAME");
			break;
		case DM_EVENT_POSTRENAME:
			fprintf(stdout, "DM_EVENT_POSTRENAME");
			break;
		case DM_EVENT_LINK:
			fprintf(stdout, "DM_EVENT_LINK");
			break;
		case DM_EVENT_POSTLINK:
			fprintf(stdout, "DM_EVENT_POSTLINK");
			break;
		case DM_EVENT_SYMLINK:
			fprintf(stdout, "DM_EVENT_SYMLINK");
			break;
		case DM_EVENT_POSTSYMLINK:
			fprintf(stdout, "DM_EVENT_POSTSYMLINK");
			break;
		case DM_EVENT_READ:
			fprintf(stdout, "DM_EVENT_READ");
			break;
		case DM_EVENT_WRITE:
			fprintf(stdout, "DM_EVENT_WRITE");
			break;
		case DM_EVENT_TRUNCATE:
			fprintf(stdout, "DM_EVENT_TRUNCATE");
			break;
		case DM_EVENT_ATTRIBUTE:
			fprintf(stdout, "DM_EVENT_ATTRIBUTE");
			break;
		case DM_EVENT_DESTROY:
			fprintf(stdout, "DM_EVENT_DESTROY");
			break;
		case DM_EVENT_NOSPACE:
			fprintf(stdout, "DM_EVENT_NOSPACE");
			break;
		case DM_EVENT_USER:
			fprintf(stdout, "DM_EVENT_USER");
			break;
		case DM_EVENT_MAX:
			fprintf(stdout, "DM_EVENT_23");
			break;
		}
		fprintf(stdout, " (%d)\n", i);
	}

	dm_handle_free(hanp, hlen);
	return(0);
}
コード例 #4
0
ファイル: get_config_events.c プロジェクト: Andiry/xfstests
int
main(
	int	argc, 
	char	**argv)
{
	u_int		nelem = DM_EVENT_MAX;
	char		*han_str;
	dm_eventset_t	eventset;
	void		*hanp;
	size_t	 	 hlen;
	u_int		nelemp;
	char		*name;
	int		error;
	int		opt;
	int		i;

	Progname = strrchr(argv[0], '/');
	if (Progname) {
		Progname++;
	} else {
		Progname = argv[0];
	}

	/* Crack and validate the command line options. */

	while ((opt = getopt(argc, argv, "n:")) != EOF) {
		switch (opt) {
		case 'n':
			nelem = atol(optarg);
			break;
		case '?':
			usage();
		}
	}
	if (optind + 1 != argc)
		usage();
	han_str = argv[optind];
	if ((error = atohan(han_str, &hanp, &hlen)) != 0) {
		fprintf(stderr, "atohan() failed, %s\n", strerror(error));
		return(1);
	}

	if (dm_init_service(&name))  {
		fprintf(stderr, "Can't initialize the DMAPI\n");
		return(1);
	}

	DMEV_ZERO(eventset);

	if (dm_get_config_events(hanp, hlen, nelem, &eventset, &nelemp)) {
		fprintf(stderr, "dm_get_config_events failed, %s\n",
			strerror(errno));
		return(1);
	}

	fprintf(stdout, "Events supported (0x%llx), nelemp %d:\n",
		(unsigned long long) eventset, nelemp);

	for (i = 0; i < nelemp; i++) {
		if (!DMEV_ISSET(i, eventset))
			continue;
		switch (i) {
		case DM_EVENT_CANCEL:
			fprintf(stdout, "DM_EVENT_CANCEL");
			break;
		case DM_EVENT_MOUNT:
			fprintf(stdout, "DM_EVENT_MOUNT");
			break;
		case DM_EVENT_PREUNMOUNT:
			fprintf(stdout, "DM_EVENT_PREUNMOUNT");
			break;
		case DM_EVENT_UNMOUNT:
			fprintf(stdout, "DM_EVENT_UNMOUNT");
			break;
		case DM_EVENT_DEBUT:
			fprintf(stdout, "DM_EVENT_DEBUT");
			break;
		case DM_EVENT_CREATE:
			fprintf(stdout, "DM_EVENT_CREATE");
			break;
		case DM_EVENT_CLOSE:
			fprintf(stdout, "DM_EVENT_CLOSE");
			break;
		case DM_EVENT_POSTCREATE:
			fprintf(stdout, "DM_EVENT_POSTCREATE");
			break;
		case DM_EVENT_REMOVE:
			fprintf(stdout, "DM_EVENT_REMOVE");
			break;
		case DM_EVENT_POSTREMOVE:
			fprintf(stdout, "DM_EVENT_POSTREMOVE");
			break;
		case DM_EVENT_RENAME:
			fprintf(stdout, "DM_EVENT_RENAME");
			break;
		case DM_EVENT_POSTRENAME:
			fprintf(stdout, "DM_EVENT_POSTRENAME");
			break;
		case DM_EVENT_LINK:
			fprintf(stdout, "DM_EVENT_LINK");
			break;
		case DM_EVENT_POSTLINK:
			fprintf(stdout, "DM_EVENT_POSTLINK");
			break;
		case DM_EVENT_SYMLINK:
			fprintf(stdout, "DM_EVENT_SYMLINK");
			break;
		case DM_EVENT_POSTSYMLINK:
			fprintf(stdout, "DM_EVENT_POSTSYMLINK");
			break;
		case DM_EVENT_READ:
			fprintf(stdout, "DM_EVENT_READ");
			break;
		case DM_EVENT_WRITE:
			fprintf(stdout, "DM_EVENT_WRITE");
			break;
		case DM_EVENT_TRUNCATE:
			fprintf(stdout, "DM_EVENT_TRUNCATE");
			break;
		case DM_EVENT_ATTRIBUTE:
			fprintf(stdout, "DM_EVENT_ATTRIBUTE");
			break;
		case DM_EVENT_DESTROY:
			fprintf(stdout, "DM_EVENT_DESTROY");
			break;
		case DM_EVENT_NOSPACE:
			fprintf(stdout, "DM_EVENT_NOSPACE");
			break;
		case DM_EVENT_USER:
			fprintf(stdout, "DM_EVENT_USER");
			break;
		case DM_EVENT_MAX:
			fprintf(stdout, "DM_EVENT_23");
			break;
		}
		fprintf(stdout, " (%d)\n", i);
	}

	dm_handle_free(hanp, hlen);
	return(0);
}