/* * 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); }
/* * 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); }
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); }
/* * 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); }
/* * 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); }