예제 #1
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);
}
예제 #2
0
파일: volname.c 프로젝트: andreiw/polaris
/*
 * This is an ON Consolidation Private interface.
 *
 * Print out the aliases available to the program user.  Changes
 * depending in whether volume management is running.
 */
void
_media_printaliases(void)
{
	struct alias		*s;
	DIR			*dirp;
	struct dirent64		*dp;
	char			pathbuf[MAXPATHLEN+1];
	char			*p;
	static const char	*vold_root = NULL;



	if (vold_root == NULL) {
		vold_root = volmgt_root();
	}

	if (!volmgt_running()) {
		/* no volume management */
		for (s = device_aliases; *s->alias != NULLC; s++) {
			(void) printf("\t%s -> %s\n", s->alias, s->name);
		}
		return;
	}

	for (s = volmgt_aliases; *s->alias != NULLC; s++) {
		(void) printf("\t%s -> %s\n", s->alias, s->name);
	}

	(void) concat_paths(pathbuf, (char *)vold_root, ALIAS_DIR, NULL);

	if ((dirp = opendir(pathbuf)) == NULL) {
		return;
	}
	while (dp = readdir64(dirp)) {
		if (strcmp(dp->d_name, ".") == 0) {
			continue;
		}
		if (strcmp(dp->d_name, "..") == 0) {
			continue;
		}
		if ((p = media_findname(dp->d_name)) != NULL) {
			(void) printf("\t%s -> %s\n", dp->d_name, p);
		}
	}
	(void) closedir(dirp);
}
예제 #3
0
/*
 * this routine will return the volmgt block name given the volmgt
 *  raw (char spcl) name
 *
 * if anything but a volmgt raw pathname is supplied that pathname will
 *  be returned
 *
 * NOTE: non-null return value will point to static data, overwritten with
 *  each call
 *
 * e.g. names starting with "/vol/r" will be changed to start with "/vol/",
 * and names starting with "vol/dev/r" will be changed to start with
 * "/vol/dev/"
 */
static char *
eject_getfullblkname(char *path, boolean_t vm_running)
{
	char		raw_root[MAXPATHLEN];
	const char	*vm_root;
	static char	res_buf[MAXPATHLEN];
	uint_t		raw_root_len;

#ifdef	DEBUG
	(void) fprintf(stderr, "eject_getfullblkname(\"%s\", %s): entering\n",
	    path, vm_running ? "B_TRUE" : "B_FALSE");
#endif
	/*
	 * try different strategies based on whether or not vold is running
	 */
	if (vm_running) {

		/* vold IS running -- look in /vol (or its alternate) */

		/* get vm root dir */
		vm_root = volmgt_root();

		/* get first volmgt root dev directory (and its length) */
		(void) snprintf(raw_root, sizeof (raw_root), "%s/r", vm_root);
		raw_root_len = strlen(raw_root);

		/* see if we have a raw volmgt pathname (e.g. "/vol/r*") */
		if (strncmp(path, raw_root, raw_root_len) == 0) {
			if (snprintf(res_buf, sizeof (res_buf), "%s/%s",
			    vm_root, path + raw_root_len) >= sizeof (res_buf)) {
				return (NULL);
			}
			goto dun;		/* found match in /vol */
		}

		/* get second volmgt root dev directory (and its length) */
		(void) snprintf(raw_root, sizeof (raw_root),
		    "%s/dev/r", vm_root);
		raw_root_len = strlen(raw_root);

		/* see if we have a raw volmgt pathname (e.g. "/vol/dev/r*") */
		if (strncmp(path, raw_root, raw_root_len) == 0) {
			if (snprintf(res_buf, sizeof (res_buf), "%s/dev/%s",
			    vm_root, path + raw_root_len) >= sizeof (res_buf)) {
				return (NULL);
			}
			goto dun;		/* found match in /vol/dev */
		}

	} else {

		/* vold is NOT running -- look in /dev */

		(void) strcpy(raw_root, "/dev/r");
		raw_root_len = strlen(raw_root);
		if (strncmp(path, raw_root, raw_root_len) == 0) {
			if (snprintf(res_buf, sizeof (res_buf), "/dev/%s",
			    path + raw_root_len) >= sizeof (res_buf)) {
				return (NULL);
			}
			goto dun;		/* found match in /dev */
		}
	}

	/* no match -- return what we got */
	(void) strcpy(res_buf, path);

dun:
#ifdef	DEBUG
	(void) fprintf(stderr, "eject_getfullblkname: returning %s\n",
	    res_buf ? res_buf : "<null ptr>");
#endif
	return (res_buf);
}
예제 #4
0
/*
 * This is an ON Consolidation Private interface.
 *
 * Forks off rmmount and (in essence) returns the result
 *
 * a return value of 0 (FALSE) means failure, non-zero (TRUE) means success
 */
int
_dev_unmount(char *path)
{
	char		*bn = NULL;		/* block name */
	char		*mtype = NULL;		/* media type */
	char		*spcl = NULL;		/* special dev. path */
	char		*spcl_failed = NULL;	/* spcl that failed */
	int		ret_val = FALSE;	/* what we return */
	char		*vr;			/* volmgt root dir */
	int		media_info_gotten = 0;
	int		mnum = 0;
	int		volume_is_not_managed;
	char		*pathbuf, *absname;


	if ((bn = (char *)volmgt_getfullblkname(path)) == NULL) {
		goto dun;
	}

	if ((pathbuf = malloc(PATH_MAX+1)) == NULL)
		goto dun;

	absname = bn;
	if (realpath(bn, pathbuf) != NULL)
		absname = pathbuf;

	volume_is_not_managed = !volmgt_running() ||
	    (!volmgt_ownspath(absname) && volmgt_symname(bn) == NULL);

	free(pathbuf);

	/* decide of we should use rmmount to unmount the media */
	if (!volume_is_not_managed) {
		int		use_rmm = FALSE;	/* use rmmount??  */

		/* at least volmgt is running */
		vr = (char *)volmgt_root();
		if (strncmp(bn, vr, strlen(vr)) == 0) {
			/* the block path is rooted in /vol */
			use_rmm = TRUE;
		}

		/* try to get info about media */
		media_info_gotten = get_media_info(bn, &mtype, &mnum, &spcl);

		ret_val = call_unmount_prog(media_info_gotten, use_rmm, mtype,
		    mnum, spcl, bn);

	} else {

		/* volmgt is *not* running */

		if (get_media_info(bn, &mtype, &mnum, &spcl)) {

			/*
			 * volmgt is off and get_media_info() has returned
			 * info on the media -- soo (this is kinda' a hack)
			 * ... we iterate, looking for multiple slices
			 * of (say) a floppy being mounted
			 *
			 * note: if an unmount fails we don't want to try
			 * to unmount the same device on the next try, so
			 * we try to watch for that
			 */

			do {
				/*
				 * don't call the unmount program is we're just
				 * trying to unmount the same device that
				 * failed last time -- if that's the case,
				 * then bail
				 */
				if (spcl_failed != NULL) {
					if (strcmp(spcl, spcl_failed) == 0) {
						break;
					}
				}
				ret_val = call_unmount_prog(TRUE, FALSE,
				    mtype, mnum, spcl, bn);

				if (!ret_val) {
					/* save spcl device name that failed */
					spcl_failed = strdup(spcl);
				} else {
					/*
					 * unmount succeeded, so clean up
					 */
					if (spcl_failed != NULL) {
						free(spcl_failed);
						spcl_failed = NULL;
					}
				}

			} while (get_media_info(bn, &mtype, &mnum, &spcl));

		} else {

			/* just do the unmmount cycle once */
			ret_val = call_unmount_prog(FALSE, FALSE, NULL, 0,
			    NULL, bn);
		}

	}

	if (mtype != NULL) {
		free(mtype);
	}
	if (spcl != NULL) {
		free(spcl);
	}
	if (spcl_failed != NULL) {
		free(spcl_failed);
	}
	if (bn != NULL) {
		free(bn);
	}

dun:

	return (ret_val);
}
예제 #5
0
파일: volname.c 프로젝트: andreiw/polaris
/*
 * 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);
}