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); }
/* ARGSUSED */ int32_t ud_open_dev(ud_handle_t h, char *special, uint32_t flags) { char *temp; struct stat i_stat, r_stat; (void) bzero(&i_stat, sizeof (struct stat)); (void) bzero(&r_stat, sizeof (struct stat)); /* * Get the stat structure */ if (stat(special, &i_stat) < 0) { temp = special; } else { if ((i_stat.st_mode & S_IFMT) == S_IFCHR) { /* * If Raw deivce is given use it as it is */ temp = special; } else if ((i_stat.st_mode & S_IFMT) == S_IFBLK) { /* * Block device try to convert to raw device */ temp = getfullrawname(special); /* * Stat the converted device name and verify * both the raw and block device belong to * the same device */ if (stat(temp, &r_stat) < 0) { temp = special; } else { if (((r_stat.st_mode & S_IFMT) == S_IFBLK) || (r_stat.st_rdev != i_stat.st_rdev)) { temp = special; } } } } /* * Now finally open the device */ h->fd = open(temp, flags); return (h->fd); }
int main(int argc, char *argv[]) { char *special, *name, *mountpoint = NULL; struct stat64 st; int i, mountfd; int Aflag = 0; char *chg[2]; int opt; struct fiotune fiotune; if (argc < 3) usage(); special = argv[argc - 1]; /* * For performance, don't search mnttab unless necessary */ if (stat64(special, &st) >= 0) { /* * If mounted directory, search mnttab for special */ if ((st.st_mode & S_IFMT) == S_IFDIR) { if (st.st_ino == UFSROOTINO) searchmnttab(&special, &mountpoint); /* * If mounted device, search mnttab for mountpoint */ } else if ((st.st_mode & S_IFMT) == S_IFBLK || (st.st_mode & S_IFMT) == S_IFCHR) { if (ustat(st.st_rdev, &ustatarea) >= 0) searchmnttab(&special, &mountpoint); } } /* * Doesn't appear to be mounted; take ``unmounted'' path */ if (mountpoint == NULL) searchvfstab(&special); if ((special = getfullrawname(special)) == NULL) { fprintf(stderr, "tunefs: malloc failed\n"); exit(32); } if (*special == '\0') { fprintf(stderr, "tunefs: Could not find raw device for %s\n", argv[argc -1]); exit(32); } if (stat64(special, &st) < 0) { fprintf(stderr, "tunefs: "); perror(special); exit(31+1); } /* * If a mountpoint has been found then we will ioctl() the file * system instead of writing to the file system's device */ /* ustat() ok because max number of UFS inodes can fit in ino_t */ if (ustat(st.st_rdev, &ustatarea) >= 0) { if (mountpoint == NULL) { printf("%s is mounted, can't tunefs\n", special); exit(32); } } else mountpoint = NULL; if ((st.st_mode & S_IFMT) != S_IFBLK && (st.st_mode & S_IFMT) != S_IFCHR) fatal("%s: not a block or character device", special); getsb(&sblock, special); while ((opt = getopt(argc, argv, "o:m:e:d:a:AV")) != EOF) { switch (opt) { case 'A': Aflag++; continue; case 'a': name = "maximum contiguous block count"; if (!isnumber(optarg)) fatal("%s: %s must be >= 1", *argv, name); i = atoi(optarg); if (i < 1) fatal("%s: %s must be >= 1", *argv, name); fprintf(stdout, "%s changes from %d to %d\n", name, sblock.fs_maxcontig, i); sblock.fs_maxcontig = i; continue; case 'd': sblock.fs_rotdelay = 0; continue; case 'e': name = "maximum blocks per file in a cylinder group"; if (!isnumber(optarg)) fatal("%s: %s must be >= 1", *argv, name); i = atoi(optarg); if (i < 1) fatal("%s: %s must be >= 1", *argv, name); fprintf(stdout, "%s changes from %d to %d\n", name, sblock.fs_maxbpg, i); sblock.fs_maxbpg = i; continue; case 'm': name = "minimum percentage of free space"; if (!isnumber(optarg)) fatal("%s: bad %s", *argv, name); i = atoi(optarg); if (i < 0 || i > 99) fatal("%s: bad %s", *argv, name); fprintf(stdout, "%s changes from %d%% to %d%%\n", name, sblock.fs_minfree, i); sblock.fs_minfree = i; continue; case 'o': name = "optimization preference"; chg[FS_OPTSPACE] = "space"; chg[FS_OPTTIME] = "time"; if (strcmp(optarg, chg[FS_OPTSPACE]) == 0) i = FS_OPTSPACE; else if (strcmp(optarg, chg[FS_OPTTIME]) == 0) i = FS_OPTTIME; else fatal("%s: bad %s (options are `space' or `time')", optarg, name); if (sblock.fs_optim == i) { fprintf(stdout, "%s remains unchanged as %s\n", name, chg[i]); continue; } fprintf(stdout, "%s changes from %s to %s\n", name, chg[sblock.fs_optim], chg[i]); sblock.fs_optim = i; continue; case 'V': { char *opt_text; int opt_count; (void) fprintf(stdout, "tunefs -F ufs "); for (opt_count = 1; opt_count < argc; opt_count++) { opt_text = argv[opt_count]; if (opt_text) (void) fprintf(stdout, " %s ", opt_text); } (void) fprintf(stdout, "\n"); } break; default: usage(); } } if ((argc - optind) != 1) usage(); if (mountpoint) { mountfd = open(mountpoint, O_RDONLY); if (mountfd == -1) { perror(mountpoint); fprintf(stderr, "tunefs: can't tune %s\n", mountpoint); exit(32); } fiotune.maxcontig = sblock.fs_maxcontig; fiotune.rotdelay = sblock.fs_rotdelay; fiotune.maxbpg = sblock.fs_maxbpg; fiotune.minfree = sblock.fs_minfree; fiotune.optim = sblock.fs_optim; if (ioctl(mountfd, _FIOTUNE, &fiotune) == -1) { perror(mountpoint); fprintf(stderr, "tunefs: can't tune %s\n", mountpoint); exit(32); } close(mountfd); } else { bwrite((diskaddr_t)SBLOCK, (char *)&sblock, SBSIZE); if (Aflag) for (i = 0; i < sblock.fs_ncg; i++) bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)), (char *)&sblock, SBSIZE); } close(fi); return (0); }
int /* fd if successful, -1 if error */ get_blk_device( struct sam_fs_part *fsp, int oflags, int maxdevretry) { int fd; int retrycnt = 0; struct dk_cinfo dkcinfo; struct vtoc vtoc; char *devrname; if (check_mnttab(fsp->pt_name)) { error(0, 0, catgets(catfd, SET, 13422, "device %s is mounted."), fsp->pt_name); return (-1); } if ((devrname = getfullrawname(fsp->pt_name)) == NULL) { error(0, 0, catgets(catfd, SET, 1606, "malloc: %s"), "getfullrawname"); return (-1); } if (*devrname == '\0') { error(0, errno, "%s", fsp->pt_name); error(0, 0, catgets(catfd, SET, 1998, "Raw device not found for eq (%d)"), fsp->pt_eq); free(devrname); return (-1); } /* * Oracle RAC (oban) devices under SunCluster initialize at the * same time as QFS filesystems are mounted. We loop waiting * for the devices to become available (maximum of maxdevretry * tries). */ while ((fd = open(devrname, oflags)) < 0) { if ((retrycnt >= maxdevretry) || ((strncmp(devrname, "/dev/md/", 8) != 0))) { error(0, errno, "%s", devrname); error(0, 0, catgets(catfd, SET, 1856, "Open failed on (%s), retries=%d"), devrname, retrycnt); free(devrname); return (-1); } retrycnt++; sleep(2); } if (retrycnt > 0) { printf("%s: %d retries on %s (max=%d).\n", program_name, retrycnt, devrname, maxdevretry); } if (ioctl(fd, DKIOCINFO, &dkcinfo) < 0) { error(0, errno, "%s", devrname); error(0, 0, catgets(catfd, SET, 1443, "Ioctl(DKIOCINFO) failed on (%s)"), devrname); free(devrname); return (-1); } if (ioctl(fd, DKIOCGVTOC, &vtoc) >= 0) { /* * Size of partition is returned in units of 512 * byte sectors. */ fsp->pt_size = (unsigned long) vtoc.v_part[dkcinfo.dki_partition].p_size; if (fsp->pt_size == 0) { error(0, 0, catgets(catfd, SET, 1909, "Partition %d is undefined on (%s)"), dkcinfo.dki_partition, devrname); free(devrname); return (-1); } } else if (is_efi_present()) { int part; int saved_errno; struct dk_gpt *efi_vtoc; saved_errno = errno; if ((part = call_efi_alloc_and_read(fd, &efi_vtoc)) >= 0) { fsp->pt_size = efi_vtoc->efi_parts[part].p_size; call_efi_free(efi_vtoc); if (fsp->pt_size == 0) { error(0, 0, catgets(catfd, SET, 1909, "Partition %d is undefined on (%s)"), part, devrname); free(devrname); return (-1); } } else { error(0, saved_errno, "%s", devrname); error(0, 0, catgets(catfd, SET, 13030, "Could not read VTOC or EFI label on %s: %d"), devrname, part); free(devrname); return (-1); } } else { error(0, errno, "%s", devrname); error(0, 0, catgets(catfd, SET, 1442, "Ioctl(DKIOCGVTOC) failed on (%s)"), devrname); free(devrname); return (-1); } free(devrname); return (fd); }
/* * prtvtoc(): Read and print a VTOC. */ static int prtvtoc(char *devname) { int fd; int idx; freemap_t *freemap; struct stat sb; struct extvtoc vtoc; int geo; struct dk_geom geom; char *name; int newvtoc = 0; struct dk_gpt *efi; name = getfullrawname(devname); if (name == NULL) return (warn(devname, "internal administrative call (getfullrawname) failed")); if (strcmp(name, "") == 0) name = devname; if ((fd = open(name, O_NONBLOCK|O_RDONLY)) < 0) return (warn(name, strerror(errno))); if (fstat(fd, &sb) < 0) return (warn(name, strerror(errno))); if ((sb.st_mode & S_IFMT) != S_IFCHR) return (warn(name, "Not a raw device")); geo = (readgeom(fd, name, &geom) == 0); if (geo) { if ((idx = readvtoc(fd, name, &vtoc)) == VT_ENOTSUP) { idx = (readefi(fd, name, &efi) == 0); newvtoc = 1; } else idx = (idx == 0); } (void) close(fd); if ((!geo) || (!idx)) return (-1); if (!newvtoc) freemap = findfree(&geom, &vtoc); else freemap = findfree64(efi); if (fflag) { if (!newvtoc) putfree(&vtoc, freemap); else putfree64(efi, freemap); } else { if (!newvtoc) puttable(&geom, &vtoc, freemap, devname, getmntpt(major(sb.st_rdev), noparttn(minor(sb.st_rdev)))); else puttable64(efi, freemap, devname, getmntpt(major(sb.st_rdev), noparttn(minor(sb.st_rdev)))); } if (newvtoc) efi_free(efi); return (0); }
static int ejectit(char *name) { int fd, r; boolean_t mejectable = B_FALSE; /* manually ejectable */ int result = EJECT_OK; /* * If volume management is either not running or not being managed by * vold, and the device is mounted, we try to umount the device. If we * fail, we give up, unless it used the -f flag. */ if (_dev_mounted(name)) { r = _dev_unmount(name); if (r == 0) { if (!force_eject) { (void) fprintf(stderr, gettext("WARNING: can not unmount %s, the file system is (probably) busy\n"), name); return (EJECT_PARM_ERR); } else { (void) fprintf(stderr, gettext("WARNING: %s has a mounted filesystem, ejecting anyway\n"), name); } } } /* * Require O_NDELAY for when floppy is not formatted * will still id floppy in drive */ /* * make sure we are dealing with a raw device * * XXX: NOTE: results from getfullrawname() * really should be free()d when no longer * in use */ name = getfullrawname(name); if ((fd = open(name, O_RDONLY | O_NDELAY)) < 0) { if (errno == EBUSY) { (void) fprintf(stderr, gettext("%s is busy (try 'eject floppy' or 'eject cdrom'?)\n"), name); return (EJECT_PARM_ERR); } perror(name); return (EJECT_PARM_ERR); } if (do_closetray) { if (ioctl(fd, CDROMCLOSETRAY) < 0) { result = EJECT_IOCTL_ERR; } } else if (ioctl(fd, DKIOCEJECT, 0) < 0) { /* check on why eject failed */ /* check for no floppy in manually ejectable drive */ if ((errno == ENOSYS) && !floppy_in_drive(name, fd, &mejectable)) { /* use code below to handle "not present" */ errno = ENXIO; } if (errno == ENOSYS || errno == ENOTSUP) { (void) fprintf(stderr, gettext(OK_TO_EJECT_MSG), name); } if ((errno == ENOSYS || errno == ENOTSUP) && mejectable) { /* * keep track of the fact that this is a manual * ejection */ result = EJECT_MAN_EJ; } else if (errno == EBUSY) { /* * if our pathname is s slice (UFS is great) then * check to see what really is busy */ if (!display_busy(name, B_FALSE)) { perror(name); } result = EJECT_IOCTL_ERR; } else if ((errno == EAGAIN) || (errno == ENODEV) || (errno == ENXIO)) { (void) fprintf(stderr, gettext("%s not present in a drive\n"), name); result = EJECT_OK; } else { perror(name); result = EJECT_IOCTL_ERR; } } (void) close(fd); return (result); }