Ejemplo n.º 1
0
/*
 *clears bit in bitmap
 */
void libuss_clear_multi_table_index(int x)
{
	int ret;
	ret = pthread_mutex_lock(&multiplexer_mtx);
	if(ret != 0) dexit("thread_mutex_lock");

	local_thread_bitmap[x] = 0;
	
	ret = pthread_mutex_unlock(&multiplexer_mtx);
	if(ret != 0) dexit("thread_mutex_unlock");
}
Ejemplo n.º 2
0
/*
 * return the actual value of run_on
 */
int update_run_on(int *run_on, int *device_id, int sfd)
{
#if(USS_FIFO == 1)
	struct uss_message m;
	ssize_t nof_br = fifo_blocking_read(&m, sfd);
	if(nof_br == sizeof(struct uss_message) /*&& errno != EAGAIN*/)
	{
		*run_on = m.accelerator_type;
		*device_id = m.accelerator_index;
	}
	else if(nof_br == (ssize_t)-1 && errno == EAGAIN)
	{
		//everything ok made empty nonblocking read
		//printf("EAGAIN nof_br=%i \n", (int)nof_br);
	}
	else if(nof_br == (ssize_t)0)
	{
		//EOF read
		dexit("update_run_on: daemon has crashed!");
	}
	else
	{
		//printf("so(mess)=%i nof_br=%i \n",(int)sizeof(struct uss_message), (int)nof_br);
		dexit("update_run_on: read too small");
	}
#elif(USS_RTSIG == 1)
	struct signalfd_siginfo fdsi;
	ssize_t nof_br = rtsig_blocking_read(sfd, &fdsi);
	if(nof_br == sizeof(struct signalfd_siginfo))
	{
		struct uss_address a;
		memset(&a, 0, sizeof(struct uss_address));
		struct uss_message m;
		convert_int_to_uss(fdsi.ssi_int, &a, &m);

		*run_on = m.accelerator_type;
		*device_id = m.accelerator_index;
	}
	else if(nof_br != sizeof(struct signalfd_siginfo) && errno == EAGAIN)
	{
		//everything ok made empty nonblocking read
	}
	else
	{
		dexit("update_run_on: read too small");	
	}
#endif
	return *run_on;
}
Ejemplo n.º 3
0
/***************************************\
* message wrapper function				*
\***************************************/
void convert_uss_to_int(struct uss_address *a, struct uss_message *m, int *i)
{
	int wrapped_int = 0;
	if(m->message_type >= (int)(1<<USS_WRAPPED_INT_RTSIG_MESSAGE_TYPE_LEN)) dexit("send_rtsig: message_type oob");
	if(m->accelerator_type >= (int)(1<<USS_WRAPPED_INT_RTSIG_ACCEL_TYPE_LEN)) dexit("send_rtsig: message_type oob");
	if(m->accelerator_index >= (int)(1<<USS_WRAPPED_INT_RTSIG_ACCEL_INDEX_LEN)) dexit("send_rtsig: message_type oob");
	if(a->lid >= (int)(1<<USS_WRAPPED_INT_RTSIG_LOCAL_ADDRESS_LEN)) dexit("send_rtsig: message_type oob");
	
	wrapped_int |= (m->message_type<<USS_WRAPPED_INT_RTSIG_MESSAGE_TYPE_POS);
	wrapped_int |= (m->accelerator_type<<USS_WRAPPED_INT_RTSIG_ACCEL_TYPE_POS);
	wrapped_int |= (m->accelerator_index<<USS_WRAPPED_INT_RTSIG_ACCEL_INDEX_POS);
	wrapped_int |= (a->lid<<USS_WRAPPED_INT_RTSIG_LOCAL_ADDRESS_POS);
	
	*i = wrapped_int;
}
Ejemplo n.º 4
0
/*
 * returns 0 on succes, -1 on error
 */
int libuss_send_to_daemon(struct uss_address *source_address, struct uss_address *receiver_address, 
						struct uss_message *message, int daemon_fd)
{
	int ret;
#if(USS_FILE_LOGGING == 1)
	struct timeval tv;
	gettimeofday(&tv, NULL);
	int fd = open("./benchmark/usslog", O_WRONLY | O_APPEND);
	if(fd == -1) {dexit("dlog");}
	char buf[100] = {0x0};
	sprintf(buf, "%ld %ld : sending message cleanup (%i) to of accelerator_type %i\n", 
		(long)tv.tv_sec, (long)tv.tv_usec, message->message_type, message->accelerator_type);
	write(fd, buf, strlen(buf));
	close(fd);
#endif
#if(USS_FIFO == 1)	
	ret = fifo_send(message, daemon_fd);
#elif(USS_RTSIG == 1)	
	//wraps source address (because daemon needs a threads LID) and message into a single int value
	int wrapped_int = 0;
	convert_uss_to_int(source_address, message, &wrapped_int);
	//send to receiver addres (because we send to daemon no receiver LID is needed)
	ret = rtsig_send(0, receiver_address->pid, wrapped_int);
#endif
	return ret;
}
Ejemplo n.º 5
0
rt_public void wide_listen(void)
{
	/* Listen on all the file descriptors opened for reading until the
	 * connected socket is broken.
	 */

	/* Make sure we listen on the connected socket and call the handling
	 * routine whenever data is available there.
	 */

#ifdef EIF_WINDOWS
	if (-1 == add_input(app_sp, (STREAM_FN) arqsthandle)) {
#else
	if (-1 == add_input(app_sp, arqsthandle)) {
#endif

#ifdef USE_ADD_LOG
		add_log(4, "add_input: %s (%s)", s_strerror(), s_strname());
#endif
		dexit(1);
	}

#ifdef USE_ADD_LOG
	add_log(12, "in listen");
#endif

	/* After having selected, we scan all our files to make sure none of them
	 * has been removed from the selection process. If at least one is missing,
	 * we are exiting immediately.
	 */

#ifdef EIF_WINDOWS

	while (0 <= do_select(0)) {
#ifdef USE_ADD_LOG
	add_log(12, "in while do_select");
#endif
		if (!has_input(app_sp)) {			/* Socket connection broken? */
#ifdef USE_ADD_LOG
	add_log(12, "in !has_input which is what we want");
#endif
			return;						/* Anyway, abort processing */
		}
	}
#ifdef USE_ADD_LOG
	add_log(12, "out of listen");
#endif

#else

	while (0 < do_select((struct timeval *) 0)) {
		if (!has_input(app_sp))			/* Socket connection broken? */
			return;						/* Anyway, abort processing */
	}
#endif

#ifdef USE_ADD_LOG
	add_log(12, "do_select: %s (%s)", s_strerror(), s_strname());
#endif
}
Ejemplo n.º 6
0
char *
volmgt_getfullrawname(char *n)
{
	extern char	*getfullrawname(char *);
	char		*rval;
	char		namebuf[MAXPATHLEN+1];
	char		*s;
	char		c;
	char		*res;


#ifdef	DEBUG
	denter("volmgt_getfullrawname(%s): entering\n", n);
#endif
	/* try to get full char-spcl device name */
	rval = getfullrawname(n);
	if ((rval != NULL) && (*rval != NULLC)) {
		/* found it */
		res = rval;
		goto dun;
	}

	/* we have a null-string result */
	if (rval != NULL) {
		/* free null string */
		free(rval);
	}

	/* ok, so we either have a bad device or a floppy */

	/* try the "fd", "diskette", and the "dsk" form */
	if (((s = strstr(n, "/fd")) != NULL) ||
	    ((s = strstr(n, "/diskette")) != NULL) ||
	    ((s = strstr(n, "/dsk/")) != NULL)) {
		/*
		 * ensure we have room to add one more char
		 */
		if (strlen(n) < (MAXPATHLEN - 1)) {
			c = *++s;		/* save the first char */
			*s = NULLC;		/* replace it with a null */
			(void) strcpy(namebuf, n); /* save first part of str */
			*s = c;			/* put first charback */
			(void) strcat(namebuf, "r"); /* insert an 'r' */
			(void) strcat(namebuf, s); /* copy rest of str */
			res = strdup(namebuf);
			goto dun;
		}
	}

	/* no match found */
	res = strdup("");
dun:
#ifdef	DEBUG
	dexit("volmgt_getfullrawname: returning %s\n",
	    res ? res : "<null ptr>");
#endif
	return (res);
}
Ejemplo n.º 7
0
/*
 *returns a free lid or negative if no more avail
 *depends on USS_MAX_LOCAL_THREADS
 */
int libuss_get_new_multi_table_index()
{
	int ret, i;
	int final_ret = -1;
	ret = pthread_mutex_lock(&multiplexer_mtx);
	if(ret != 0) dexit("thread_mutex_lock");

	for(i = 0; i < USS_MAX_LOCAL_THREADS; i++)
	{
		if(local_thread_bitmap[i] == 0)
		{
			local_thread_bitmap[i] = 1;
			final_ret = i;
			break;
		}
	}	
	
	ret = pthread_mutex_unlock(&multiplexer_mtx);
	if(ret != 0) dexit("thread_mutex_unlock");
	
	return final_ret;
}
Ejemplo n.º 8
0
/*
 * this requires the communication method to use file descriptors
 * that can be made blocking or nonblocking via fcntl
 */
int waitfor_run_on(int *run_on, int *device_id, int sfd)
{
	int flags, ret, final_ret;

	//delete flag: O_NONBLOCK
	flags = fcntl(sfd, F_GETFL);
	if(flags == -1) {dexit("waitfor_run_on had problem with fcntl");}
	flags &= (~O_NONBLOCK);
	ret = fcntl(sfd, F_SETFL, flags);
	if(ret == -1) {dexit("waitfor_run_on had problem with fcntl");}
	
	//now do blocking read on modified sfd
	final_ret = update_run_on(run_on, device_id, sfd);
	
	//reset flag: O_NONBLOCK
	flags = fcntl(sfd, F_GETFL);
	if(flags == -1) {dexit("waitfor_run_on had problem with fcntl");}
	flags |= O_NONBLOCK;
	ret = fcntl(sfd, F_SETFL, flags);
	if(ret == -1) {dexit("waitfor_run_on had problem with fcntl");}

	return final_ret;
}
Ejemplo n.º 9
0
/*
 * translate suplied vol name into a pathname
 *
 * if volmgt is running, this pathname will be in /vol (or its equiv)
 *
 * if volmgt is not running then this path may be anywhere
 *
 * in either case the pathname will *not* be verified as a blk/chr dev
 *
 * if the return value is non-null then it's been alloced
 *
 * NOTE: assume "vol" is not a NULL ptr
 */
static char *
fsi_xlate_name(char *vol)
{
	char	*res = NULL;			/* result to return */
	char	*vr;				/* volmgt root dir */
	bool_t	vm_running = volmgt_running();	/* volmgt running? */


#ifdef	DEBUG
	denter("fsi_xlate_name(\"%s\"): entering\n", vol);
#endif

	/* is it an absolute pathname ?? */
	if (*vol == '/') {

		if (vm_running) {
			/* pathname must be in the /vol namespace */
			vr = (char *)volmgt_root();
			if (strncmp(vol, vr, strlen(vr)) != 0) {
				/* not a cool pathname */
				errno = EINVAL;	/* XXX: is this correct */
				goto dun;
			}
		}

		res = strdup(vol);

	} else {

		/*
		 * if volmgt is running we can try to dereference it
		 * if volmgt isn't running then just give up
		 */

		if (!vm_running) {
			/* some unknown "name" */
			errno = ENOENT;
			goto dun;
		}

		res = volmgt_symdev(vol);

	}

dun:
#ifdef	DEBUG
	dexit("fsi_xlate_name: returning %s\n", res ? res : "<null ptr>");
#endif
	return (res);
}
Ejemplo n.º 10
0
/***************************************\
* multiplexer start						*
\***************************************/
int libuss_start_multiplexer()
{
	//
	//try to create a multiplexer socket
	//
	int ret;
	ret = pthread_mutex_lock(&multiplexer_mtx);
	if(ret != 0) dexit("thread_mutex_lock");
	
	if(multiplexer_started == 0)
	{
		int ret, fd_multiplexer;
		struct sockaddr_un server_addr;
		
		//create a socket
		ret = remove(USS_REGISTRATION_MULTIPLEXER_SOCKET);
		if(ret == -1 && errno != ENOENT) {dexit("problem when trying to remove old socket");}
		
		fd_multiplexer = socket(AF_UNIX, SOCK_STREAM, 0);
		if(fd_multiplexer==-1) {dexit("dderror: creating socket\n");}
		
		memset(&server_addr, 0, sizeof(struct sockaddr_un));
		server_addr.sun_family = AF_UNIX;
		strncpy(server_addr.sun_path, USS_REGISTRATION_MULTIPLEXER_SOCKET, sizeof(server_addr.sun_path)-1);
		
		ret = bind(fd_multiplexer, (struct sockaddr*) &server_addr, sizeof(struct sockaddr_un));
		if(fd_multiplexer==-1) {dexit("dderror: binding socket failed\n");}
		
		ret = listen(fd_multiplexer, 128);
		if(fd_multiplexer==-1) {dexit("dderror: listen on socket failed\n");}
			
		pthread_create(&registration_multiplexer_thread, NULL, libuss_registration_multiplexer_thread, &fd_multiplexer);
		
		struct sigaction sa;
		sa.sa_flags = SA_SIGINFO | SA_RESTART;
		sa.sa_sigaction = incoming_sig_handler;
		sigemptyset(&sa.sa_mask);
		ret = sigaction((SIGRTMIN+0), &sa, NULL);
		if(ret == -1) {printf("dderror: signal int not established\n"); exit(1);}
		
		multiplexer_started = 1;
	}
	
	ret = pthread_mutex_unlock(&multiplexer_mtx);
	if(ret != 0) dexit("thread_mutex_unlock");
	
	return 0;
}
Ejemplo n.º 11
0
/*
 * arc approved interface (pending)
 *	- can not be modified without approval from an arc
 *
 * committment level:
 *	public
 *
 * description:
 *	media_findname: try to come up with the character device when
 *	provided with a starting point.  This interface provides the
 *	application programmer to provide "user friendly" names and
 *	easily determine the "/vol" name.
 *
 * arguments:
 *	start - a string describing a device.  This string can be:
 *		- a full path name to a device (insures it's a
 *		  character device by using getfullrawname()).
 *		- a full path name to a volume management media name
 *		  with partitions (will return the lowest numbered
 *		  raw partition.
 *		- the name of a piece of media (e.g. "fred").
 *		- a symbolic device name (e.g. floppy0, cdrom0, etc)
 *		- a name like "floppy" or "cdrom".  Will pick the lowest
 *		  numbered device with media in it.
 *
 * return value(s):
 *	A pointer to a string that contains the character device
 *	most appropriate to the "start" argument.
 *
 *	NULL indicates that we were unable to find media based on "start".
 *
 *	The string must be free(3)'d.
 *
 * preconditions:
 *	none.
 */
char *
media_findname(char *start)
{
	static char 	*media_findname_work(char *);
	char		*s = NULL;


	/*
	 * This is just a wrapper to implement the volmgt_check nastyness.
	 */
#ifdef	DEBUG
	denter("media_findname(%s): entering\n", start ? start : "<null ptr>");
#endif

	if (start == NULL) {
		errno = EFAULT;
		goto dun;
	}

	/*
	 * If we don't get positive results, we kick volume management
	 * to ask it to look in the floppy drive.
	 *
	 * XXX: maybe this should be configurable ???
	 */
	if ((s = media_findname_work(start)) == NULL) {
#ifdef	DEBUG
		dprintf("media_findname: calling volcheck and trying again\n");
#endif
		(void) volmgt_check(NULL);
		s = media_findname_work(start);
	}

dun:
#ifdef	DEBUG
	dexit("media_findname: returning \"%s\"\n", s ? s : "<null ptr>");
#endif
	return (s);
}
Ejemplo n.º 12
0
/*
 * Return a raw name, given a starting point.
 *
 * Assume: input string ptr is not null
 */
static char *
media_findname_work(char *start)
{
	extern char		*vol_basename(char *);
	static void		volmgt_deref_link(char *, char *, char *);
	char			pathbuf[MAXPATHLEN+1];
	char			*rv;
	char			*s;
	char			linkbuf[MAXNAMELEN+1];
	char			*nameptr;
	struct stat64		sb;
	int			n;
	int			i;
	static const char	*vold_root = NULL;
	static char		vold_alias_dir[MAXPATHLEN+1];
	char			*res = NULL;
	DIR			*dirp = NULL;
	struct dirent64		*dp;



#ifdef	DEBUG
	denter("media_findname_work(%s): entering\n", start);
#endif

	if (vold_root == NULL) {
		vold_root = volmgt_root();
		(void) concat_paths(vold_alias_dir, (char *)vold_root,
		    (char *)ALIAS_DIR, NULL);
	}

	/*
	 * if this is an absolute path name then
	 *  if it's a symlink deref it
	 *  if it's a raw device then we're done
	 *  else if it's a directory then look for a dev under it
	 */
	if (IS_ABS_PATH(start)) {

		/* try to get data on name passed in */
		if (lstat64(start, &sb) < 0) {
#ifdef	DEBUG
			dprintf(
			"media_findname_work: lstat of \"%s\" (errno %d)\n",
			    start, errno);
#endif
			goto dun;		/* error exit */
		}

		/*
		 * if is this a link to something else (e.g. ".../floppy0")
		 * and it's in the volmgt namespace, then deref it
		 */
		if (S_ISLNK(sb.st_mode) && (strncmp(start, vold_alias_dir,
		    strlen(vold_alias_dir)) == 0)) {

			/* it's a symlink */
			if ((n = readlink(start, linkbuf, MAXNAMELEN)) <= 0) {
				/* we can't read the link */
#ifdef	DEBUG
				dprintf(
		"media_findname_work: readlink(\"%s\") failed (errno %d)\n",
				    start, errno);
#endif
				goto dun;	/* error exit */
			}
			linkbuf[n] = NULLC;

			/* dereference the link */
			volmgt_deref_link(pathbuf, start, linkbuf);

			/* stat where "start" pointed at */
			if (stat64(pathbuf, &sb) < 0) {
#ifdef	DEBUG
				dprintf(
		"media_findname_work: stat failed on \"%s\" (errno %d)\n",
				    pathbuf, errno);
#endif
				goto dun;	/* error exit */
			}
			nameptr = pathbuf;

		} else {
			nameptr = start;
		}

		/* do we already have a char-spcl device ?? */
		if (S_ISCHR(sb.st_mode)) {
			/*
			 * absoluate pathname of a char-spcl device passed in
			 */
			res = strdup(nameptr);
			goto dun;		/* success */
		}

		/* not a char-spcl device -- is it a dir ?? */
		if (S_ISDIR(sb.st_mode)) {
			/* open the dir and find first char-spcl device */
			if ((s = getrawpart0(nameptr)) != NULL) {
				/*
				 * absoluate pathname to a directory passed
				 * in, under which there is at least one
				 * char-spcl device
				 */
				free(s);
				res = strdup(nameptr);
				goto dun;	/* success */
			}
		}

		/*
		 * try to get the char-spcl name if this is a blk-spcl
		 *
		 * XXX: shouldn't we ensure this is a blk spcl device?
		 */
		rv = volmgt_getfullrawname(nameptr);
		if ((rv == NULL) || (*rv == NULLC)) {
			goto dun;		/* error exit */
		}

		/* stat the fullrawname device (to see if it's char-spcl) */
		if (stat64(rv, &sb) < 0) {
#ifdef	DEBUG
			dprintf(
			    "media_findname_work: stat of \"%s\" (errno %d)\n",
			    rv, errno);
#endif
			goto dun;		/* error exit */
		}

		/* have we found the char-spcl device ?? */
		if (S_ISCHR(sb.st_mode)) {
			/*
			 * absolute pathname to block device supplied and
			 * converted to an absoluate pathname to a char device
			 */
			res = rv;		/* already malloc'ed */
			goto dun;		/* success */
		}

		/*
		 * fullrawname not a char-spcl device -- is it a dir ??
		 *
		 * XXX: didn't we already check for a directory name
		 * being supplied above?
		 */
		if (S_ISDIR(sb.st_mode)) {
			/* open dir and find first char-spcl device */
			if ((s = getrawpart0(rv)) != NULL) {
				/*
				 * the absolute pathname of directory
				 * containing at least one char-spcl device
				 * was passed in
				 */
				free(s);
				res = strdup(rv);
				goto dun;	/* success */
			}
		}

		/* having a full pathname didn't help us */
		goto dun;	/* failure -- pathname not found */
	}

	/*
	 * Ok, now we check to see if it's an alias.
	 * Note here that in the case of an alias, we prefer
	 * to return what the alias (symbolic link) points
	 * at, rather than the symbolic link.  Makes for
	 * nicer printouts and such.
	 */
	(void) concat_paths(pathbuf, vold_alias_dir, start, NULL);

#ifdef	DEBUG
	dprintf("media_findname_work: looking for \"%s\"\n", pathbuf);
#endif

	if (stat64(pathbuf, &sb) == 0) {
#ifdef	DEBUG
		dprintf("media_findname_work: is \"%s\" a chr-spcl dev?\n",
		    pathbuf);
#endif
		/* is this a char-spcl device ?? */
		if (S_ISCHR(sb.st_mode)) {
			/* it's probably a link, so ... */
			if ((n = readlink(pathbuf,
			    linkbuf, MAXNAMELEN)) <= 0) {
				/*
				 * error (since we are in the symlink
				 * directory) not a link, but just punt
				 * anyway
				 */
				res = strdup(pathbuf);
			} else {
				/* it was a link */
				linkbuf[n] = NULLC;
				res = strdup(linkbuf);
			}
			goto dun;		/* success */
		}

#ifdef	DEBUG
		dprintf("media_findname_work: not chr-spcl -- is it a dir?\n");
#endif
		/* not a char-spcl device -- is it a dir ?? */
		if (S_ISDIR(sb.st_mode)) {
			/* it's probably a link, so ... */
			if ((n = readlink(pathbuf,
			    linkbuf, MAXNAMELEN)) <= 0) {
				/*
				 * error, but just punt anyway
				 */
				nameptr = pathbuf;
				s = getrawpart0(pathbuf);
			} else {
				/* it was a link */
				linkbuf[n] = NULLC;
				/* open dir, finding first char-spcl dev */
				nameptr = linkbuf;
				s = getrawpart0(linkbuf);
			}
			if (s != NULL) {
				free(s);
				res = strdup(nameptr);
				goto dun;
			}
		}
	}

	/*
	 * check all aliases in the alias dir, to see if any match
	 */
	if ((dirp = opendir(vold_alias_dir)) == NULL) {
		goto try_hack;
	}

	while (dp = readdir64(dirp)) {

		/* skip uninteresting entries */
		if (strcmp(dp->d_name, ".") == 0) {
			continue;
		}
		if (strcmp(dp->d_name, "..") == 0) {
			continue;
		}

#ifdef	DEBUG
		dprintf("media_findname_work: scanning alias \"%s\" ...\n",
		    dp->d_name);
#endif
		/*
		 * open the link and see if it points at our entry
		 */
		(void) concat_paths(pathbuf, vold_alias_dir, dp->d_name,
		    NULL);
		if ((n = readlink(pathbuf, linkbuf, MAXNAMELEN)) <= 0) {
#ifdef	DEBUG
				dprintf(
		"media_findname_work: readlink(\"%s\") failed (errno %d)\n",
				    pathbuf, errno);
#endif
			continue;
		}
		linkbuf[n] = NULLC;

#ifdef	DEBUG
		dprintf("media_findname_work: scanning link \"%s\" ...\n",
		    linkbuf);
#endif
		if (strcmp(vol_basename(linkbuf), start) == 0) {

			/* we *think* we've found a match */

			if (stat64(linkbuf, &sb) == 0) {

				if (S_ISCHR(sb.st_mode)) {
					res = strdup(linkbuf);
					goto dun;
				}

				if (S_ISDIR(sb.st_mode)) {
					res = getrawpart0(linkbuf);
					if (res != NULL) {
						free(res);
						res = strdup(linkbuf);
					}
					goto dun;
				}

			}

		}
	}

try_hack:

	/*
	 * Ok, well maybe that's not it.  Let's try the
	 * hackname alias.
	 */

	/*
	 * This creates the "hack" name.  The model
	 * is that xx# has the alias xx.  So, cdrom#
	 * and floppy# (the most frequent case) can
	 * be referred to as cdrom and floppy.
	 * We poke at what we consider to be a reasonable number of
	 * devices (currently 5) before giving up.
	 */

	for (i = 0; i < HACKNAME_MAX; i++) {
		char	num_buf[NUMBUF_SZ];


		(void) sprintf(num_buf, "%d", i);
		(void) concat_paths(pathbuf, vold_alias_dir, start, num_buf);

		if (stat64(pathbuf, &sb) == 0) {

			/* is it a char-spcl device ?? */
			if (S_ISCHR(sb.st_mode)) {
				/* it's probably a link, so... */
				if ((n = readlink(pathbuf,
				    linkbuf, MAXNAMELEN)) <= 0) {
					/* it wasn't a link */
					res = strdup(pathbuf);
				} else {
					/* it was a link */
					linkbuf[n] = NULLC;
					res = strdup(linkbuf);
				}
				goto dun;
			}

			/* not a char-spcl device -- is it a dir ?? */
			if (S_ISDIR(sb.st_mode)) {
				/* it's probably a link, so ... */
				if ((n = readlink(pathbuf,
				    linkbuf, MAXNAMELEN)) <= 0) {
					/* get fist char-spcl dev in dir */
					nameptr = pathbuf;
					s = getrawpart0(pathbuf);
				} else {
					/* it was a link */
					linkbuf[n] = NULLC;
					/* get fist char-spcl dev in dir */
					nameptr = linkbuf;
					s = getrawpart0(linkbuf);
				}
				if (s != NULL) {
					free(s);
					res = strdup(nameptr);
					goto dun;
				}
			}
		}
	}

#ifdef	DEBUG
	dprintf("media_findname_work: %s didn't match any test!\n", start);
#endif

dun:
	if (dirp != NULL) {
		(void) closedir(dirp);
	}

#ifdef	DEBUG
	dexit("media_findname_work: returning \"%s\"\n",
	    res ? res : "<null ptr>");
#endif
	return (res);
}
Ejemplo n.º 13
0
/*
 *this thread hijacks outgoing registration attempts
 *and slices in a local ID
 *it is also a thread that can receive SIGRTMIN+0
 */
void* libuss_registration_multiplexer_thread(void *args)
{
	pthread_detach(pthread_self());
	int ret;
	int *fd_multiplexer_ptr = (int*)args;
	int fd_multiplexer = *fd_multiplexer_ptr;
	int fd_localthread, fd_daemon;

	//SIGRTMIN+0 has to be unlocked
	sigset_t unimmune_set;
	sigemptyset(&unimmune_set);
	sigaddset(&unimmune_set, (SIGRTMIN+0));
	pthread_sigmask(SIG_UNBLOCK, &unimmune_set, NULL);
	//
	//loop for each new accepted connection (create no new thread for each => many regs may be delayed)
	//
	while(1)
	{
		//
		//wait for reg attempt from a local thread that uses multiplexer
		//
		fd_localthread = accept(fd_multiplexer, NULL, NULL);
		if(fd_localthread==-1) {printf("dderror: accept failed\n"); exit(1);}
		
		//
		//now new connection to daemon
		//
		struct sockaddr_un client_addr;
		
		fd_daemon = socket(AF_UNIX, SOCK_STREAM, 0);
		if(fd_daemon == -1) {dexit("error creating socket -> quit");}
		
		memset(&client_addr, 0, sizeof(struct sockaddr_un));
		client_addr.sun_family = AF_UNIX;
		strncpy(client_addr.sun_path, USS_REGISTRATION_DAEMON_SOCKET, sizeof(client_addr.sun_path)-1);
		
		ret = connect(fd_daemon, (struct sockaddr*) &client_addr, sizeof(struct sockaddr_un));
		if(ret == -1) 
		{
			printf("error connecting socket\n");
			close(fd_localthread);
			dexit("multiplexer could not connect to daemon -> quit");
		}
		else
		{
		//
		//read meta_sched_addr_info from local thread
		//
		struct meta_sched_addr_info transport;
		memset(&transport, 0, sizeof(struct meta_sched_addr_info));
		int nof_br = read(fd_localthread, &transport, sizeof(struct meta_sched_addr_info));
		
		//if we received too small msai return error value
		if(nof_br != sizeof(struct meta_sched_addr_info))
		{
			dexit("received too small msai");
		}
		
		//
		//create multi_table entry
		//
		int index = libuss_get_new_multi_table_index();
		if(index < 0) 
		{
			close(fd_localthread);
			close(fd_daemon);
			dexit("too many threads per process");
		}
		else
		{		
			multi_table[index].local_thread = transport.tid;
			
			//
			//write modified meta_sched_addr_info to daemon
			//
			transport.addr.lid = index;
			write(fd_daemon, &transport, sizeof(struct meta_sched_addr_info));
			
			//
			//read uss_response from daemon
			//
			struct uss_registration_response resp;
			read(fd_daemon, &resp, sizeof(uss_registration_response));
			
			//
			//write modfied uss_response back to local thread
			//
			resp.client_addr.pid = getpid();
			resp.client_addr.lid = index;
			write(fd_localthread, &resp, sizeof(struct uss_registration_response));

#if(USS_DEBUG == 1)			
			printf("SCHED RESP CHECK: %i\n", resp.check);
#endif

			//
			//depending on sched response, keep or clear saved state for this local thread
			//
			if(resp.check == USS_CONTROL_SCHED_ACCEPTED)
			{
			}
			else if(resp.check == USS_CONTROL_SCHED_DECLINED)
			{
				libuss_clear_multi_table_index(index);
			}
			else
			{
				//sth odd happend
				dexit("wrong scheduler response");
			}
			}
			//close own connection with daemon
			close(fd_daemon);
		}
	}//end while	
	
	return NULL;
}
Ejemplo n.º 14
0
void _start()
{
    main();
    dexit();
}
Ejemplo n.º 15
0
/*
 * libuss_start
 *
 * provides main algorithm
 *
 * (dont use function pointer binding here, because it would
 *  require a rebind each time an accelerator is chosen
 *  -> maybe solve by inline calculation?)
 */
int libuss_start(struct meta_sched_info *msi, void *md, void *mcp, int *is_finished, int *run_on, int *device_id)
{
	//
	//local variables
	//
	int ret;
	
	/*
	 *run_on variable is provided from outside what allows other threads to check this ones status
	 */
	*run_on = USS_ACCEL_TYPE_IDLE;
	*device_id = 0;

	//
	//benchmark variables
	//
	#if(BENCHMARK_REGISTRATION_TIME == 1)
	struct timespec ts;
	#endif
	#if(BENCHMARK_CONTEXTSWITCH_TIME == 1)
	struct timespec cst;
	uint64_t cst_init_ns = 0; uint64_t cst_clean_ns = 0;
	char buf[100] = {0x0}; int bench_fd;
	#endif

	//
	//register at uss (fails if no daemon is started)
	//
	struct uss_address my_addr, daemon_addr;
	memset(&my_addr, 0, sizeof(struct uss_address));	
	memset(&daemon_addr, 0, sizeof(struct uss_address));
	int my_fd;
	int daemon_fd;

	#if(BENCHMARK_REGISTRATION_TIME == 1)
	if(clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {dexit("clock_gettime() failed");}
	uint64_t regtime_start_ns = ts.tv_sec*(1000000000) + ts.tv_nsec;
	#endif

	ret = libuss_register_at_daemon(msi, &my_addr, &daemon_addr, &my_fd, &daemon_fd);

	#if(BENCHMARK_REGISTRATION_TIME == 1)
	if(clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {dexit("clock_gettime() failed");}
	uint64_t regtime_stop_ns = ts.tv_sec*(1000000000) + ts.tv_nsec;
	printf("%llu\n", (unsigned long long int)(regtime_stop_ns - regtime_start_ns));
	#endif
	
	if(ret == -1) {printf("registering at daemon unsuccessful -> quit\n"); return USS_ERROR_GENERAL;}
	if(ret == USS_ERROR_SCHED_DECLINED_REG) {printf("scheduler declined registration\n"); return USS_ERROR_SCHED_DECLINED_REG;}
	if(ret == USS_ERROR_TRANSPORT) {printf("transport error occured\n"); return USS_ERROR_TRANSPORT;}
	
	struct meta_sched_info_element *selected;
	struct uss_message curr_message;
	int current_device_id;
	int do_main_atleast_once = 0;	
	
	//
	//main functionality
	//
	//update once
	update_run_on(run_on, device_id, my_fd);
	//loop
	while (!(*is_finished))
	{
		switch(*run_on)
		{
		case USS_ACCEL_TYPE_CUDA:
			#if(USS_LIBRARY_DEBUG == 1)
			printf("case: run CUDA\n");
			#endif
			current_device_id = *device_id;
			do_main_atleast_once = 0;
			selected = msi->ptr[USS_ACCEL_TYPE_CUDA];
			
			#if(BENCHMARK_CONTEXTSWITCH_TIME == 1)
			if(clock_gettime(CLOCK_MONOTONIC, &cst) != 0) {dexit("clock_gettime() failed");}
			cst_init_ns = cst.tv_sec*(1000000000) + cst.tv_nsec;
			bench_fd = open("./benchmark/cstlog", O_WRONLY | O_APPEND); if(bench_fd == -1) {dexit("bench_cst");}
			memset(buf, 0, (size_t)100);
			sprintf(buf, "i %lld\n", (long long int)(cst_init_ns)); //=time (ns) when this writer is before init
			write(bench_fd, buf, strlen(buf)); 
			memset(buf, 0, (size_t)100);
			sprintf(buf, "c %lld\n", (long long int)(cst_clean_ns)); //=time (ns) when this writer did a cleanup
			write(bench_fd, buf, strlen(buf)); 			
			close(bench_fd);
			#endif
			
			selected->init(md, mcp, current_device_id);
			
			while(((USS_ACCEL_TYPE_CUDA == *run_on && current_device_id == *device_id) || do_main_atleast_once == 0)
					&& !(*is_finished))
			{
			selected->main(md, mcp, current_device_id);
			update_run_on(run_on, device_id, my_fd);
			do_main_atleast_once = 1;
			}
			
			selected->free(md, mcp, current_device_id);
			
			#if(BENCHMARK_CONTEXTSWITCH_TIME == 1)
			if(clock_gettime(CLOCK_MONOTONIC, &cst) != 0) {dexit("clock_gettime() failed");}
			cst_clean_ns = cst.tv_sec*(1000000000) + cst.tv_nsec;
			#endif
			
			if((*is_finished)) 
			{
				#if(USS_FIFO == 1)	
				curr_message.address = my_addr;
				#endif
				curr_message.message_type = USS_MESSAGE_ISFINISHED;
				curr_message.accelerator_type = USS_ACCEL_TYPE_CUDA;
				curr_message.accelerator_index = current_device_id;
				ret = libuss_send_to_daemon(&my_addr, &daemon_addr, &curr_message, daemon_fd);
				if(ret != 0) {dexit("library could not send message!!");}
			}
			else
			{
				#if(USS_FIFO == 1)	
				curr_message.address = my_addr;
				#endif
				curr_message.message_type = USS_MESSAGE_CLEANUP_DONE;
				curr_message.accelerator_type = USS_ACCEL_TYPE_CUDA;
				curr_message.accelerator_index = current_device_id;
				ret = libuss_send_to_daemon(&my_addr, &daemon_addr, &curr_message, daemon_fd);
				if(ret != 0) {dexit("library could not send message!!");}
			}
			break;
			
		case USS_ACCEL_TYPE_FPGA:
			#if(USS_LIBRARY_DEBUG == 1)
			printf("case: run FPGA\n");
			#endif			
			current_device_id = *device_id;
			do_main_atleast_once = 0;
			selected = msi->ptr[USS_ACCEL_TYPE_FPGA];
			
			selected->init(md, mcp, current_device_id);
			
			while(((USS_ACCEL_TYPE_FPGA == *run_on && current_device_id == *device_id) || do_main_atleast_once == 0)
					&& !(*is_finished))
			{
			selected->main(md, mcp, current_device_id);
			update_run_on(run_on, device_id, my_fd);
			do_main_atleast_once = 1;
			}
			
			selected->free(md, mcp, current_device_id);
			
			if((*is_finished)) 
			{
				#if(USS_FIFO == 1)	
				curr_message.address = my_addr;
				#endif
				curr_message.message_type = USS_MESSAGE_ISFINISHED;
				curr_message.accelerator_type = USS_ACCEL_TYPE_FPGA;
				curr_message.accelerator_index = current_device_id;
				ret = libuss_send_to_daemon(&my_addr, &daemon_addr, &curr_message, daemon_fd);
				if(ret != 0) {dexit("library could not send message!!");}
			}
			else
			{
				#if(USS_FIFO == 1)	
				curr_message.address = my_addr;
				#endif
				curr_message.message_type = USS_MESSAGE_CLEANUP_DONE;
				curr_message.accelerator_type = USS_ACCEL_TYPE_FPGA;
				curr_message.accelerator_index = current_device_id;
				ret = libuss_send_to_daemon(&my_addr, &daemon_addr, &curr_message, daemon_fd);
				if(ret != 0) {dexit("library could not send message!!");}
			}
			break;

		case USS_ACCEL_TYPE_STREAM:
			#if(USS_LIBRARY_DEBUG == 1)
			printf("case: run FPGA\n");
			#endif			
			current_device_id = *device_id;
			do_main_atleast_once = 0;
			selected = msi->ptr[USS_ACCEL_TYPE_STREAM];
			
			selected->init(md, mcp, current_device_id);
			
			while(((USS_ACCEL_TYPE_STREAM == *run_on && current_device_id == *device_id) || do_main_atleast_once == 0)
					&& !(*is_finished))
			{
			selected->main(md, mcp, current_device_id);
			update_run_on(run_on, device_id, my_fd);
			do_main_atleast_once = 1;
			}
			
			selected->free(md, mcp, current_device_id);
			
			if((*is_finished)) 
			{
				#if(USS_FIFO == 1)	
				curr_message.address = my_addr;
				#endif
				curr_message.message_type = USS_MESSAGE_ISFINISHED;
				curr_message.accelerator_type = USS_ACCEL_TYPE_STREAM;
				curr_message.accelerator_index = current_device_id;
				ret = libuss_send_to_daemon(&my_addr, &daemon_addr, &curr_message, daemon_fd);
				if(ret != 0) {dexit("library could not send message!!");}
			}
			else
			{
				#if(USS_FIFO == 1)	
				curr_message.address = my_addr;
				#endif
				curr_message.message_type = USS_MESSAGE_CLEANUP_DONE;
				curr_message.accelerator_type = USS_ACCEL_TYPE_STREAM;
				curr_message.accelerator_index = current_device_id;
				ret = libuss_send_to_daemon(&my_addr, &daemon_addr, &curr_message, daemon_fd);
				if(ret != 0) {dexit("library could not send message!!");}
			}
			break;
			
		case USS_ACCEL_TYPE_CPU:
			#if(USS_LIBRARY_DEBUG == 1)
			printf("case: run CPU\n");
			#endif
			selected = msi->ptr[USS_ACCEL_TYPE_CPU];
			selected->init(md, mcp, 0);
			
			while(USS_ACCEL_TYPE_CPU == *run_on && !(*is_finished))
			{
			selected->main(md, mcp, 0);
			update_run_on(run_on, device_id, my_fd);
			/*CPU has no do_main_atleaat_once because its init/cleanup cost are low*/
			}
			
			selected->free(md, mcp, 0);
			if((*is_finished)) 
			{
				#if(USS_FIFO == 1)	
				curr_message.address = my_addr;
				#endif
				curr_message.message_type = USS_MESSAGE_ISFINISHED;
				curr_message.accelerator_type = USS_ACCEL_TYPE_CPU;
				curr_message.accelerator_index = 0;
				ret = libuss_send_to_daemon(&my_addr, &daemon_addr, &curr_message, daemon_fd);
				if(ret != 0) {dexit("library could not send message!!");}
			}
			else
			{
				#if(USS_FIFO == 1)	
				curr_message.address = my_addr;
				#endif
				curr_message.message_type = USS_MESSAGE_CLEANUP_DONE;
				curr_message.accelerator_type = USS_ACCEL_TYPE_CPU;
				curr_message.accelerator_index = 0;
				ret = libuss_send_to_daemon(&my_addr, &daemon_addr, &curr_message, daemon_fd);
				if(ret != 0) {dexit("library could not send message!!");}
			}
			break;
			
		case USS_ACCEL_TYPE_IDLE:
			/*fallthrough to default
			 */
			 
		default:
#if(USS_LIBRARY_DEBUG == 1)
			printf("case: IDLE\n");
#endif
			//this app thread has been 'idled' by daemon -> cant do anything until a message from daemon
			waitfor_run_on(run_on, device_id, my_fd);
			break;
			
		}//end switch
	}//end main while

	//
	//cleanup by closing the file descriptors
	//
	close(my_fd);
	close(daemon_fd);

	return ret;
}
Ejemplo n.º 16
0
/*
 * libuss_register_at_daemon
 *
 */
int libuss_register_at_daemon(struct meta_sched_info *msi, struct uss_address *my_addr, struct uss_address *daemon_addr, int *my_fd, int *daemon_fd)
{
	//
	//validity check
	//
	if(!msi) {printf("error: msi is NULL pointer -> quit"); return -1;}
	
	//
	//local variables
	//
	int ret;
	int fd;
	ssize_t size_ret;
	struct sockaddr_un target_addr;

	//
	//create a socket
	//
	fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if(fd == -1) {printf("error creating socket -> quit"); return -1;}

	//
	//make this thread listen on virtual line
	//
	*my_fd = libuss_install_receiver(my_addr);
	if(*my_fd == -1) 
	{
		printf("(problem with receiver installation)\n");
		return USS_ERROR_GENERAL;
	}

#if(USS_RTSIG == 1)
	libuss_start_multiplexer(); //will start only if not active yet
#endif

	//
	//connect to daemon
	//		
	memset(&target_addr, 0, sizeof(struct sockaddr_un));
	target_addr.sun_family = AF_UNIX;
	
#if(USS_FIFO == 1)	
	strncpy(target_addr.sun_path, USS_REGISTRATION_DAEMON_SOCKET, sizeof(target_addr.sun_path)-1);
#elif(USS_RTSIG == 1)	
	strncpy(target_addr.sun_path, USS_REGISTRATION_MULTIPLEXER_SOCKET, sizeof(target_addr.sun_path)-1);
#endif

	ret = connect(fd, (struct sockaddr*) &target_addr, sizeof(struct sockaddr_un));
	if(ret == -1) {printf("libuss_register error connecting socket -> return \n"); return -1;}
	
	//
	//parse msi into meta_sched_addr_info 
	//
	int i;
	struct meta_sched_addr_info transport;
	struct meta_sched_info_element *temp = NULL;

	memset(&transport, 0, sizeof(struct meta_sched_addr_info));
	
	transport.addr = *my_addr;
	transport.tid = pthread_self();
	transport.length = 0;
	
	for(i = 0; i < USS_NOF_SUPPORTED_ACCEL; i++)
	{
		temp = msi->ptr[i];
		if(!temp)
		{
			//user doesn't want to use this accel
			continue;
		}
		else
		{
			if(transport.length >= USS_MAX_MSI_TRANSPORT)
			{
				printf("warning: user specified more accelerators than allowed by USS_MAX_MSI_TRANSPORT\n");
			}
			else
			{
				transport.accelerator_type[transport.length] = i;
				transport.affinity[transport.length] = temp->affinity;
				transport.flags[transport.length] = temp->flags;
				transport.length += 1;
			}
		}
	}
	//abort if user hasn't set any elements in his msi
	if(transport.length == 0) {printf("error: user has specified empty msi -> quit\n"); return -1;}
	
	//
	//sort msai using bubble sort
	//
	int exchanged;
	int n = transport.length;
	do
	{
		exchanged = 0;
		for(i = 0; i < (n-1); i++)
		{
			if(transport.affinity[i] < transport.affinity[i+1])
			{
				int temp_acc = transport.accelerator_type[i+1];
				int temp_aff = transport.affinity[i+1];
				int temp_fla = transport.flags[i+1];
				transport.accelerator_type[i+1] = transport.accelerator_type[i];
				transport.affinity[i+1] = transport.affinity[i];
				transport.flags[i+1] = transport.flags[i];
				transport.accelerator_type[i] = temp_acc;
				transport.affinity[i] = temp_aff;
				transport.flags[i] = temp_fla;
				exchanged = 1;
			}
		}
		n--;
	} while(exchanged == 1 && n > 0);
	
#if(USS_LIBRARY_DEBUG == 1)
	//printf("\nREGISTRATION\n");
	//print_msi_short(&transport);
#endif

	//
	//send meta_sched_addr_info to server
	//
	size_ret = write(fd, &transport, sizeof(struct meta_sched_addr_info));
	if(size_ret != sizeof(struct meta_sched_addr_info)) {dexit("libuss_register: write too small");}
	
	//
	//read response and analyze for success
	//
	struct uss_registration_response resp;
	ssize_t size_got = 0;
	while(size_got < (ssize_t)sizeof(struct uss_registration_response))
	{
		size_ret = read(fd, ((&resp)+size_got), ((ssize_t)sizeof(struct uss_registration_response) - size_got));
		if(size_ret == -1) {dexit("libuss_register: general error with read call");}
		size_got += size_ret;
	}
	if(size_ret != sizeof(struct uss_registration_response)) {dexit("libuss_register: read too small or unequal");}

	int check = resp.check;
	*daemon_addr = resp.daemon_addr;
	*my_addr = resp.client_addr;
	
	if(check == USS_CONTROL_SCHED_ACCEPTED) 
	{
		#if(USS_FIFO == 1)
		#if(USS_LIBRARY_DEBUG == 1)
		printf("my_addr->fifo=%ld\n", my_addr->fifo);
		#endif
		*daemon_fd = libuss_install_sender(daemon_addr);
		if(*daemon_fd == -1) 
		{
			printf("(problem with sender installation)\n");
			close(fd);
			return USS_ERROR_GENERAL;
		}
		#elif(USS_RTSIG == 1)
		//sending signals needs no senderobject
		#endif

		#if(USS_LIBRARY_DEBUG == 1)
		printf("(succesfully transported msi and acceped by sched)\n");	
		#endif		
		close(fd);
		return 0;
	}
	else if(check == USS_CONTROL_SCHED_DECLINED)
	{
		dexit("(scheduler did not accept registration)\n");
		ret = close(fd);
		return USS_ERROR_SCHED_DECLINED_REG;
	}
	return -1;
}
Ejemplo n.º 17
0
/*
 * This is an ON Consolidation Private interface.
 */
char *
_media_oldaliases(char *start)
{
	struct alias	*s, *ns;
	char		*p;
	char		*res;



#ifdef	DEBUG
	denter("_media_oldaliases(%s): entering\n", start);
#endif

	for (s = device_aliases; *s->alias != NULLC; s++) {
		if (strcmp(start, s->alias) == 0) {
			break;
		}
	}

	/* we don't recognize that alias at all */
	if (*s->alias == NULLC) {
#ifdef	DEBUG
		dprintf("_media_oldaliases: failed\n");
#endif
		res = NULL;
		goto dun;
	}

	/* if volume management isn't running at all, give him back the name */
	if (!volmgt_running()) {
#ifdef	DEBUG
		dprintf("_media_oldaliases: no vold!\n");
#endif
		res = strdup(s->name);
		goto dun;
	}
	/*
	 * If volume management is managing that device, look up the
	 * volume management name.
	 */
	if (volmgt_inuse(s->name)) {
		for (s = volmgt_aliases; *s->alias != NULLC; s++) {
			if (strcmp(start, s->alias) == 0) {
				res = strdup(s->name);
				goto dun;
			}
		}
#ifdef	DEBUG
		dprintf("_media_oldaliases: failed\n");
#endif
		res = NULL;
		goto dun;
	}

	/*
	 * If volume management isn't managing the device, it's possible
	 * that he's given us an alias that we should recognize, but the
	 * default name is wrong.  For example a user might have his
	 * cdrom on controller 1, being managed by volume management,
	 * but we would think it isn't because volmgt_inuse just told
	 * us that c0t6d0s2 isn't being managed.  So, before we return
	 * the /dev name, we'll test the alias out using media_findname.
	 * If media_findname can't make sense out of the alias, it probably
	 * means that we really, really aren't managing the device and
	 * should just return the /dev name.  Whew.  Isn't this grody?
	 */

	for (ns = volmgt_aliases; *ns->alias != NULLC; ns++) {
		if (strcmp(start, ns->alias) == 0) {
			if ((p = media_findname_work(ns->name))) {
				res = p;
				goto dun;
			} else {
				break;
			}
		}
	}

	res = strdup(s->name);
dun:
#ifdef	DEBUG
	dexit("_media_oldaliases: returning %s\n", res ? res : "<null ptr>");
#endif
	return (res);
}
Ejemplo n.º 18
0
static int
get_media_info(char *path, char **mtypep, int *mnump, char **spclp)
{
	FILE		*fp = NULL;
	int		fd = -1;
	char		*cn = NULL;		/* char spcl pathname */
	struct stat64	sb;
	struct dk_cinfo	info;
	struct mnttab	mnt;
	int		ret_val = FALSE;

	if ((fp = fopen(MNTTAB, "rF")) == NULL) {
		/* mtab is gone... let him go */
		goto dun;
	}

	/* get char spcl pathname */
	if ((cn = volmgt_getfullrawname(path)) == NULL) {
		goto dun;
	}
	if (cn[0] == NULLC) {
		goto dun;
	}

	if ((fd = open(cn, O_RDONLY|O_NDELAY)) < 0) {
		goto dun;
	}

	if (fstat64(fd, &sb) < 0) {
		goto dun;
	}

	if (ioctl(fd, DKIOCINFO, &info) != 0) {
		goto dun;
	}

	/* if we found the entry then disect it */
	if (vol_getmntdev(fp, &mnt, sb.st_rdev, &info) != 0) {
		char		*cp;
		char		*mtype;
		char		*mnt_dir;
		int		mtype_len;
		DIR		*dirp = NULL;
		struct dirent64	*dp;
		char		*volname;


		/* return the spcl device name found */
		*spclp = strdup(mnt.mnt_special);

		/*
		 * try to get the media type (e.g. "floppy") from the mount
		 * point (e.g. "/floppy/NAME") if vold is running
		 */

		if (!volmgt_running() ||
		    (!volmgt_ownspath(*spclp) &&
		    volmgt_symname(*spclp) == NULL)) {
			ret_val = TRUE;		/* success (if limited) */
			goto dun;
		}

		/* get the first part of the mount point (e.g. "floppy") */
		cp = mnt.mnt_mountp;
		if (*cp++ != '/') {
			goto dun;
		}
		mtype = cp;
		if ((cp = strchr(mtype, '/')) == NULL) {
			goto dun;
		}
		*cp++ = NULLC;
		mnt_dir = mnt.mnt_mountp;	/* save dir path */

		/* get the volume name (e.g. "unnamed_floppy") */
		volname = cp;

		/* scan for the symlink that points to our volname */
		if ((dirp = opendir(mnt_dir)) == NULL) {
			goto dun;
		}
		mtype_len = strlen(mtype);
		while ((dp = readdir64(dirp)) != NULL) {
			char		lpath[2 * (MAXNAMELEN+1)];
			char		linkbuf[MAXPATHLEN+4];
			int		lb_len;
			struct stat64	sb;


			if (strncmp(dp->d_name, mtype, mtype_len) != 0) {
				continue;	/* not even close */
			}

			(void) sprintf(lpath, "%s/%s", mnt_dir,
			    dp->d_name);
			if (lstat64(lpath, &sb) < 0) {
				continue;	/* what? */
			}
			if (!S_ISLNK(sb.st_mode)) {
				continue;	/* not our baby */
			}
			if ((lb_len = readlink(lpath, linkbuf,
			    sizeof (linkbuf))) < 0) {
				continue;
			}
			linkbuf[lb_len] = NULLC; /* null terminate */
			if ((cp = vol_basename(linkbuf)) == NULL) {
				continue;
			}
			/* now we have the name! */
			if (strcmp(cp, volname) == 0) {
				/* found it !! */
				if (sscanf(dp->d_name + mtype_len, "%d",
				    mnump) == 1) {
					*mtypep = strdup(mtype);
					ret_val = TRUE;
				}
				break;
			}
		}
		(void) closedir(dirp);
	}

dun:
	if (fp != NULL) {
		(void) fclose(fp);
	}
	if (fd >= 0) {
		(void) close(fd);
	}
	if (cn != NULL) {
		free(cn);
	}
#ifdef	DEBUG
	if (ret_val) {
		dexit("get_media_info: returning mtype=%s, mnum=%d, spcl=%s\n",
		    *mtypep == NULL ? "<null ptr>" : *mtypep,
		    *mnump,
		    *spclp == NULL ? "<null ptr>" : *spclp);
	} else {
		dexit("get_media_info: FAILED\n");
	}
#endif
	return (ret_val);
}
Ejemplo n.º 19
0
/*
 * arc approved interface
 *	- can not be modified without approval from an arc
 *
 * committment level:
 *	uncommitted
 *
 * description:
 *	volmgt_acquire: try to acquire the volmgt advisory device reservation
 *	for a specific device.
 *
 * arguments:
 *	dev - a device name to attempt reserving.  This string can be:
 *		- a full path name to a device
 *		- a symbolic device name (e.g. floppy0)
 *
 *	id  - a reservation string that hopefully describes the application
 *		making this reservation.
 *
 *	pid - a pointer to a pid_t type.  If this argument is not NULL
 *		and the requested device is already reserved, the process
 *		id of the reservation owner will be returned in this
 *		location.
 *
 *	ovr - an override indicator.  If set to non-zero, the caller requests
 *		that this reservation be made unconditionally.
 *
 *	err - the address of a pointer to a string which is to receive the
 *		id argument used when the current device was reserved.  This
 *		is only used when the current reservation attempt fails due
 *		to an already existing reservation for this device.
 *
 * return value(s):
 *	A non-zero indicator if successful.
 *
 *	A zero indicator if unsuccessful.  If errno is EBUSY, then the err
 *	argument will be set to point to the string that the process currently
 *	holding the reservation supplied when reserving the device.  It is up
 *	to the caller to release the storage occupied by the string via
 *	free(3C) when no longer needed.
 *
 * preconditions:
 *	none
 */
int
volmgt_acquire(char *dev, char *id, int ovr, char **err, pid_t *pidp)
{
	char			*targ_name = NULL;
	struct stat		sb;
	dev_t			idev;
	vol_dbid_t		dbid = (vol_dbid_t)-1;
	vol_db_entry_t		dbe;
	vol_db_entry_t		*dbp;
	int			retval = 0;	/* default return => ERROR */
	int			reterr = 0;


#ifdef	DEBUG
	denter("volmgt_acquire(\"%s\", \"%s\", %s, %#p, %#p): entering\n",
	    dev ? dev : "<null ptr>", id ? id : "<null ptr>",
	    ovr ? "TRUE" : "FALSE", err, pidp);
#endif
	/*
	 * the supplied arguments must not be NULL
	 */
	if ((dev == NULL) || (id == NULL) || (err == NULL)) {
		errno = EINVAL;
		goto dun;
	}

	/*
	 * the id string must not be longer than the maximum allowable
	 * number of characters
	 */
	if (strlen(id) > VOL_RSV_MAXIDLEN) {
		errno = E2BIG;
		goto dun;
	}

	if ((targ_name = fsi_xlate_name(dev)) == NULL) {
		goto dun;
	}

	/*
	 * convert 'char *dev' to major/minor pair
	 */
	if (stat(targ_name, &sb) < 0) {
		goto dun;
	}
	idev = sb.st_rdev;

	/*
	 * open the database file
	 */
	if ((dbid = vol_db_open()) < 0) {
		goto dun;
	}

	if ((dbp = vol_db_find(dbid, idev)) == NULL) {
		/*
		 * the entry wasn't found, so reserve it
		 */
		dbe.dev_major = major(idev);
		dbe.dev_minor = minor(idev);
		dbe.pid = getpid();
		dbe.id_tag = id;
		if (vol_db_insert(dbid, &dbe) != 0) {
			retval = 1;		/* success! */
		}
	} else {
		if (ovr || (vol_db_proc_find(dbp->pid) == 0)) {
			/*
			 * the entry exists but either override was specified
			 * or the process holding the reservation is no longer
			 * active
			 *
			 * in either case we'll usurp the reservation
			 */
			if (vol_db_remove(dbid, idev) != 0) {
				/* reserve the device */
				dbe.dev_major = major(idev);
				dbe.dev_minor = minor(idev);
				dbe.pid = getpid();
				dbe.id_tag = id;
				if (vol_db_insert(dbid, &dbe) != 0) {
					retval = 1;
				}
			}

		} else {

			/*
			 * the entry exists and override was NOT specified
			 */

			/*
			 * optionally return the pid of the reservation
			 * owner
			 */
			if (pidp != NULL) {
				*pidp = dbp->pid;
			}

			*err = strdup(dbp->id_tag);
			reterr = EBUSY;
		}
		vol_db_free(dbp);	/* Release the entry */
	}


	/*
	 * if an error was encountered (currently only EBUSY supported)
	 * set errno to reflect it
	 */
	if (reterr != 0) {
		errno = reterr;
	}

dun:
	if ((int)dbid >= 0) {
		(void) vol_db_close(dbid);
	}
	if (targ_name != NULL) {
		free(targ_name);
	}
#ifdef	DEBUG
	dexit("volmgt_acquire: returning %s\n", retval ? "TRUE" : "FALSE");
#endif
	return (retval);
}
Ejemplo n.º 20
0
/*
 * arc approved interface
 *	- can not be modified without approval from an arc
 *
 * committment level:
 *	uncommitted
 *
 * description:
 *	volmgt_release: try to release the volmgt advisory device reservation
 *	for a specific device.
 *
 * arguments:
 *	dev - a device name to attempt reserving.  This string can be:
 *		- a full path name to a device
 *		- a symbolic device name (e.g. floppy0)
 *
 * return value(s):
 *	A non-zero indicator if successful
 *	A zero indicator if unsuccessful
 *
 * preconditions:
 *	none
 */
int
volmgt_release(char *dev)
{
	char			*targ_name = NULL;
	struct stat		sb;
	long			idev;
	vol_dbid_t		dbid;
	vol_db_entry_t		*dbp;
	int			retval = 0;	/* default return => FAILURE */
	int			reterr = 0;


#ifdef	DEBUG
	denter("volmgt_release(\"%s\"): entering\n", dev ? dev : "<null ptr>");
#endif
	/*
	 * first let's do some minimal validation of the supplied arguments
	 */

	/*
	 * the supplied argument must not be NULL
	 */
	if (dev == NULL) {
		errno = EINVAL;
		goto dun;
	}

	if ((targ_name = fsi_xlate_name(dev)) == NULL) {
		goto dun;
	}

	/*
	 * convert 'char *dev' to major/minor pair
	 */
	if (stat(targ_name, &sb) < 0) {
		goto dun;
	}
	idev = sb.st_rdev;

	/*
	 * open the database file
	 */
	if ((dbid = vol_db_open()) < 0) {
		goto dun;
	}

	if ((dbp = vol_db_find(dbid, idev)) == NULL) {
		/* the entry wasn't found so I can't clear reservation */
		errno = ENOENT;
		goto dun;
	}

	/* the entry was found so make sure I can clear it */
	if (dbp->pid == getpid()) {
		/*
		 * the reservation was made by me, clear it
		 */
		if (vol_db_remove(dbid, idev) != 0) {
			retval = 1;
		}
	} else {
		/*
		 * the entry wasn't made by me
		 */
		reterr = EBUSY;
	}
	vol_db_free(dbp);

	/*
	 * if an error was encountered (currently only EBUSY supported)
	 * set errno to reflect it
	 */
	if (reterr != 0) {
		errno = reterr;
	}
dun:
	if ((int)dbid >= 0) {
		(void) vol_db_close(dbid);
	}
	if (targ_name != NULL) {
		free(targ_name);
	}
#ifdef	DEBUG
	dexit("volmgt_release: returning %s\n", retval ? "TRUE" : "FALSE");
#endif
	return (retval);
}