BOOL Manager::Part_Reported_As_Logical(Target_Spec *spec, char *rdisk, int count) { int i, retval; char *p; char rstr[MAX_NAME], lstr[MAX_NAME]; // for physical/logical disks. FILE *fp; struct mnttab mtab, mpref; // // checks if the named partition/slice has already been mounted. // The file systems listed in the mnttab file are already mounted. So, we have two cases : // The file system is listed for testing (eg: ufs) or not listed (eg. procfs) // But we need only check if the file sys is mounted and thats sufficient. That will // ensure that we don't crash anything running. // strcpy(rstr, rdisk); if ((fp = fopen(mnttab, "r")) == NULL) { cout << "open (mount tab) file " << mnttab << " failed with error " << errno << endl; cout << "Set environment variable MNTTAB to correct pathname" << endl; // We wont try to report any disk. Could expose the OS partition to destructive tests. return TRUE; } for (i = 0; i < count; i++) { // Initialize the mpref structure to NULL. Solaris does'nt do it. memset(&mpref, 0, sizeof(struct mnttab)); #ifdef _DEBUG cout << "checking if physical disk already reported as logical." << endl << " logical disk : " << spec[i].name << " physical disk : " << rdisk << endl; #endif // check for this pattern is also in Manager::Report_Disks() // and TargetDisk::Init_Logical(). p = strstr(spec[i].name, " ["); strncpy(lstr, spec[i].name, p - spec[i].name); lstr[p - spec[i].name] = 0; mpref.mnt_mountp = lstr; if ((retval = getmntany(fp, &mtab, &mpref)) == 0) { // found the entry in mnttab. if (strstr(mtab.mnt_special, rstr)) { // equal! the entry contains this physical disk name (in the form c0t0d0[p|s]?). // further the entry is in the list of reported logical disks. // So, this physical disk has already been reported as a logical disk. #ifdef _DEBUG cout << "physical disk " << rdisk << " reported logical disk " << mtab.mnt_mountp << endl; #endif fclose(fp); return TRUE; } } } fclose(fp); return FALSE; }
int mounted(char *device) { char target[NSC_MAXPATH]; struct mnttab mntref; struct mnttab mntent; FILE *mntfp; int rdsk; char *s; int i; rdsk = i = 0; for (s = target; i < NSC_MAXPATH && (*s = *device++); i++) { if (*s == 'r' && rdsk == 0 && strncmp(device, "dsk/", 4) == 0) rdsk = 1; else s++; } *s = '\0'; mntref.mnt_special = target; mntref.mnt_mountp = NULL; mntref.mnt_fstype = NULL; mntref.mnt_mntopts = NULL; mntref.mnt_time = NULL; mntfp = fopen(MNTTAB, "r"); if (mntfp == NULL) { rdc_warn(NULL, gettext("can not check volume %s against mount table"), mntref.mnt_special); /* Assume the worst, that it is mounted */ return (1); } if (getmntany(mntfp, &mntent, &mntref) != -1) { /* found something before EOF */ (void) fclose(mntfp); return (1); } (void) fclose(mntfp); return (0); }
/* Get the name of a mounted filesytem */ char * get_mnt_special(char *mountp, char *fstype) { struct mnttab entry, search; char *special = NULL; FILE *fp; search.mnt_special = search.mnt_mntopts = search.mnt_time = NULL; search.mnt_mountp = mountp; search.mnt_fstype = fstype; if ((fp = fopen(MNTTAB, "r")) != NULL) { if (getmntany(fp, &entry, &search) == 0) special = entry.mnt_special; (void) fclose(fp); } return special; }
/* * Unshare the given filesystem. */ int zfs_unshare_proto(zfs_handle_t *zhp, const char *mountpoint, zfs_share_proto_t *proto) { struct mnttab search = { 0 }, entry; char *mntpt = NULL; /* check to see if need to unmount the filesystem */ search.mnt_special = (char *)zfs_get_name(zhp); search.mnt_fstype = MNTTYPE_ZFS; #ifndef __APPLE__ rewind(zhp->zfs_hdl->libzfs_mnttab); #endif /*!__APPLE__*/ if (mountpoint != NULL) mntpt = zfs_strdup(zhp->zfs_hdl, mountpoint); if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) && getmntany(zhp->zfs_hdl->libzfs_mnttab, &entry, &search) == 0)) { zfs_share_proto_t *curr_proto; if (mountpoint == NULL) mntpt = zfs_strdup(zhp->zfs_hdl, entry.mnt_mountp); for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) { if (is_shared(zhp->zfs_hdl, mntpt, *curr_proto) && unshare_one(zhp->zfs_hdl, zhp->zfs_name, mntpt, *curr_proto) != 0) { if (mntpt != NULL) free(mntpt); return (-1); } } } if (mntpt != NULL) free(mntpt); return (0); }
/** Check if a filesystem on a special device file is mounted * * @param device_file Special device file, e.g. /dev/cdrom * @return TRUE iff there is a filesystem system mounted * on the special device file */ static dbus_bool_t is_mounted (const char *device_file) { FILE *f; dbus_bool_t rc = FALSE; struct mnttab mp; struct mnttab mpref; if ((f = fopen ("/etc/mnttab", "r")) == NULL) return rc; bzero(&mp, sizeof (mp)); bzero(&mpref, sizeof (mpref)); mpref.mnt_special = (char *)device_file; if (getmntany(f, &mp, &mpref) == 0) { rc = TRUE; } fclose (f); return rc; }
/* * Unmount the given filesystem. */ int zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags) { struct mnttab search = { 0 }, entry; char *mntpt = NULL; /* check to see if need to unmount the filesystem */ search.mnt_special = zhp->zfs_name; search.mnt_fstype = MNTTYPE_ZFS; rewind(zhp->zfs_hdl->libzfs_mnttab); if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) && getmntany(zhp->zfs_hdl->libzfs_mnttab, &entry, &search) == 0)) { /* * mountpoint may have come from a call to * getmnt/getmntany if it isn't NULL. If it is NULL, * we know it comes from getmntany which can then get * overwritten later. We strdup it to play it safe. */ if (mountpoint == NULL) mntpt = zfs_strdup(zhp->zfs_hdl, entry.mnt_mountp); else mntpt = zfs_strdup(zhp->zfs_hdl, mountpoint); /* * Unshare and unmount the filesystem */ if (zfs_unshare_proto(zhp, mntpt, share_all_proto) != 0) return (-1); if (unmount_one(zhp->zfs_hdl, mntpt, flags) != 0) { free(mntpt); (void) zfs_shareall(zhp); return (-1); } free(mntpt); } return (0); }
/* * Checks to see if the mount is active. If the filesystem is mounted, we fill * in 'where' with the current mountpoint, and return 1. Otherwise, we return * 0. */ boolean_t is_mounted(libzfs_handle_t *zfs_hdl, const char *special, char **where) { struct mnttab search = { 0 }, entry; /* * Search for the entry in /etc/mnttab. We don't bother getting the * mountpoint, as we can just search for the special device. This will * also let us find mounts when the mountpoint is 'legacy'. */ search.mnt_special = (char *)special; search.mnt_fstype = MNTTYPE_ZFS; rewind(zfs_hdl->libzfs_mnttab); if (getmntany(zfs_hdl->libzfs_mnttab, &entry, &search) != 0) return (B_FALSE); if (where != NULL) *where = zfs_strdup(zfs_hdl, entry.mnt_mountp); return (B_TRUE); }
/* * Get the boot device. Cannot load FCode to current boot device. * Boot devices under volume management will prompt a warning. */ static int q_getbootdev(uchar_t *bootpath) { struct mnttab mp; struct mnttab mpref; FILE *fp = NULL; static char buf[BUFSIZ]; char *p = NULL, *p1 = NULL; /* p = full device, p1 = chunk to rm */ char *slot = ":devctl"; char *root = "/"; if ((fp = fopen(MNTTAB, "r")) == NULL) { (void) fprintf(stderr, MSGSTR(21000, "Error: Could not open %s\n"), MNTTAB); return (1); } mntnull(&mpref); mpref.mnt_mountp = (char *)root; if (getmntany(fp, &mp, &mpref) != 0 || mpref.mnt_mountp == NULL) { (void) fprintf(stderr, MSGSTR(21019, "Error: Cannot get boot device, check %s.\n"), MNTTAB); (void) fclose(fp); return (1); } (void) fclose(fp); /* * If we can't get a link, we may be dealing with a volume mgr * so give a warning. If a colon is present, we likely have a * non-local disk or cd-rom, so no warning is necessary. * e.g. /devices/pci@1f,4000/scsi@3/sd@6,0:b (cdrom, no link) or * storage-e4:/blah/blah remote boot server */ if (readlink(mp.mnt_special, buf, BUFSIZ) < 0) { if (strstr(mp.mnt_special, ":") == NULL) { (void) fprintf(stderr, MSGSTR(21020, "\nWarning: Cannot read boot device link, check %s.\n"), MNTTAB); (void) fprintf(stderr, MSGSTR(21021, "Do not upgrade FCode on adapters controlling the boot device.\n")); } return (1); } /* * Copy boot device path to bootpath. First remove leading * path junk (../../..) then if it's an ifp device, chop off * the disk and add the devctl to the end of the path. */ if (p = strstr(buf, "/devices")) { if (strstr(buf, fc_trans) != NULL) { p1 = strrchr(p, '/'); *p1 = '\0'; } } (void) strcpy((char *)bootpath, (char *)p); if (p1) { (void) strcat((char *)bootpath, slot); } return (0); }
int main(int argc, char **argv) { struct stat sb, sb2; char *argname; char *cp; int c; struct mntent mntpref; register struct mntent *mntp; struct mntent mntent; register FILE *mtabp; setlinebuf(stdout); progname = basename(argv[0]); gflag = ! isatty(0); while ((c = getopt(argc, argv, "C:p:e:MgsdnvTt:f:m:b:N:FV")) != -1 ) switch (c) { case 'M': Mflag = 1; break; case 'g': gflag = 1; break; case 'n': /* nflag = 1; */ break; case 'v': ++vflag; break; case 'd': dflag = 1; break; case 's': /* frag stats only */ /* sflag = 1; */ fprintf(stderr, "%s: Stats not yet supported for XFS\n", progname); usage(1); break; case 't': howlong = atoi(optarg); break; case 'f': leftofffile = optarg; break; case 'm': mtab = optarg; break; case 'b': argv_blksz_dio = atoi(optarg); break; case 'p': npasses = atoi(optarg); break; case 'V': printf("%s version %s\n", progname, VERSION); break; default: usage(1); } if (vflag) setbuf(stdout, NULL); starttime = time(0); /* Save the caller's real uid */ RealUid = getuid(); pagesize = getpagesize(); if (optind < argc) { for (; optind < argc; optind++) { argname = argv[optind]; mntp = NULL; if (lstat(argname, &sb) < 0) { fprintf(stderr, "%s: could not stat: %s: %s\n", progname, argname, strerror(errno)); continue; } if (S_ISLNK(sb.st_mode) && stat(argname, &sb2) == 0 && (S_ISBLK(sb2.st_mode) || S_ISCHR(sb2.st_mode))) sb = sb2; if (S_ISBLK(sb.st_mode) || (S_ISDIR(sb.st_mode))) { if ((mtabp = setmntent(mtab, "r")) == NULL) { fprintf(stderr, "%s: failed reading mtab: %s\n", progname, mtab); exit(1); } bzero(&mntpref, sizeof(mntpref)); if (S_ISDIR(sb.st_mode)) mntpref.mnt_dir = argname; else mntpref.mnt_fsname = argname; if ((getmntany(mtabp, &mntent, &mntpref) == 0) && (strcmp(mntent.mnt_type, MNTTYPE_XFS) == 0)) { mntp = &mntent; if (S_ISBLK(sb.st_mode)) { cp = mntp->mnt_dir; if (cp == NULL || stat(cp, &sb2) < 0) { fprintf(stderr, "%s: could not stat: %s: %s\n", progname, argname, strerror(errno)); continue; } sb = sb2; argname = cp; } } } if (mntp != NULL) { fsrfs(mntp->mnt_dir, 0, 100); } else if (S_ISCHR(sb.st_mode)) { fprintf(stderr, "%s: char special not supported: %s\n", progname, argname); exit(1); } else if (S_ISDIR(sb.st_mode) || S_ISREG(sb.st_mode)) { struct statfs fs; statfs(argname, &fs); if (fs.f_type != XFS_SB_MAGIC) { fprintf(stderr, "%s: cannot defragment: %s: Not XFS\n", progname, argname); continue; } if (S_ISDIR(sb.st_mode)) fsrdir(argname); else fsrfile(argname, sb.st_ino); } else { printf( "%s: not fsys dev, dir, or reg file, ignoring\n", argname); } } } else { initallfs(mtab); fsrallfs(howlong, leftofffile); } return 0; }
/* * Verify the filesystem type for a regular statefile is "ufs" * or verify a block device is not in use as a mounted filesytem. * Returns 1 if any error, otherwise 0. */ static int check_mount(char *sfile, dev_t sfdev, int ufs) { char *src, *err_fmt = NULL, *mnttab = MNTTAB; int rgent, match = 0; struct mnttab zroot = { 0 }; struct mnttab entry; struct extmnttab ent; FILE *fp; if ((fp = fopen(mnttab, "r")) == NULL) { mesg(MERR, open_fmt, mnttab, strerror(errno)); return (1); } if (ufs) { zroot.mnt_mountp = "/"; zroot.mnt_fstype = "zfs"; if (getmntany(fp, &entry, &zroot) == 0) { err_fmt = "ufs statefile with zfs root is not" " supported\n"; mesg(MERR, err_fmt, sfile); (void) fclose(fp); return (1); } resetmnttab(fp); } /* * Search for a matching dev_t; * ignore non-ufs filesystems for a regular statefile. */ while ((rgent = getextmntent(fp, &ent, sizeof (ent))) != -1) { if (rgent > 0) { mesg(MERR, "error reading \"%s\"\n", mnttab); (void) fclose(fp); return (1); } else if (ufs && strcmp(ent.mnt_fstype, "ufs")) continue; else if (makedev(ent.mnt_major, ent.mnt_minor) == sfdev) { match = 1; break; } } /* * No match is needed for a block device statefile, * a match is needed for a regular statefile. */ if (match == 0) { if (new_cc.cf_type != CFT_UFS) STRCPYLIM(new_cc.cf_devfs, sfile, "block statefile"); else err_fmt = "cannot find ufs mount point for \"%s\"\n"; } else if (new_cc.cf_type == CFT_UFS) { STRCPYLIM(new_cc.cf_fs, ent.mnt_mountp, "mnt entry"); STRCPYLIM(new_cc.cf_devfs, ent.mnt_special, "mnt special"); while (*(sfile + 1) == '/') sfile++; src = sfile + strlen(ent.mnt_mountp); while (*src == '/') src++; STRCPYLIM(new_cc.cf_path, src, "statefile path"); } else err_fmt = "statefile device \"%s\" is a mounted filesystem\n"; (void) fclose(fp); if (err_fmt) mesg(MERR, err_fmt, sfile); return (err_fmt != NULL); }
/* * display a "busy" message for the supplied pathname * * if the pathname is not a slice, then just display a busy message * else if the pathname is some slice subdirectory then look for the * *real* culprits * * if this is not done then the user can get a message like * /vol/dev/rdsk/c0t6d0/solaris_2_5_sparc/s5: Device busy * when they try to eject "cdrom0", but "s0" (e.g.) may be the only busy * slice * * return B_TRUE iff we printed the appropriate error message, else * return B_FALSE (and caller will print error message itself) */ static boolean_t display_busy(char *path, boolean_t vm_running) { int errno_save = errno; /* to save errno */ char *blk; /* block name */ FILE *fp = NULL; /* for scanning mnttab */ struct mnttab mref; /* for scanning mnttab */ struct mnttab mp; /* for scanning mnttab */ boolean_t res = B_FALSE; /* return value */ char busy_base[MAXPATHLEN]; /* for keeping base dir name */ uint_t bblen; /* busy_base string length */ char *cp; /* for truncating path */ #ifdef DEBUG (void) fprintf(stderr, "display_busy(\"%s\"): entering\n", path); #endif /* * get the block pathname. * eject_getfullblkname returns NULL or pathname which * has length < MAXPATHLEN. */ blk = eject_getfullblkname(path, vm_running); if (blk == NULL) goto dun; /* open mnttab for scanning */ if ((fp = fopen(MNTTAB, "r")) == NULL) { /* can't open mnttab!? -- give up */ goto dun; } (void) memset((void *)&mref, '\0', sizeof (struct mnttab)); mref.mnt_special = blk; if (getmntany(fp, &mp, &mref) == 0) { /* we found our entry -- we're done */ goto dun; } /* perhaps we have a sub-slice (which is what we exist to test for) */ /* create a base pathname */ (void) strcpy(busy_base, blk); if ((cp = strrchr(busy_base, '/')) == NULL) { /* no last slash in pathname!!?? -- give up */ goto dun; } *cp = '\0'; bblen = strlen(busy_base); /* bblen = (uint)(cp - busy_base); */ /* scan for matches */ rewind(fp); /* rescan mnttab */ while (getmntent(fp, &mp) == 0) { /* * work around problem where '-' in /etc/mnttab for * special device turns to NULL which isn't expected */ if (mp.mnt_special == NULL) mp.mnt_special = "-"; if (strncmp(busy_base, mp.mnt_special, bblen) == 0) { res = B_TRUE; (void) fprintf(stderr, "%s: %s\n", mp.mnt_special, strerror(EBUSY)); } } dun: if (fp != NULL) { (void) fclose(fp); } #ifdef DEBUG (void) fprintf(stderr, "display_busy: returning %s\n", res ? "B_TRUE" : "B_FALSE"); #endif errno = errno_save; return (res); }
/* * Unmount a single filesystem. */ static int unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags) { #ifdef __APPLE__ #if !TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE /* First try going through diskarb */ if (diskarb_unmount(mountpoint, flags) == 0) { return (0); } #endif #endif #ifdef __APPLE__ if (unmount(mountpoint, flags) != 0) { #else if (umount2(mountpoint, flags) != 0) { #endif zfs_error_aux(hdl, strerror(errno)); return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot unmount '%s'"), mountpoint)); } return (0); } /* * Unmount the given filesystem. */ int zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags) { struct mnttab search = { 0 }, entry; char *mntpt = NULL; /* check to see if need to unmount the filesystem */ search.mnt_special = zhp->zfs_name; search.mnt_fstype = MNTTYPE_ZFS; #ifndef __APPLE__ rewind(zhp->zfs_hdl->libzfs_mnttab); #endif /*!__APPLE__*/ if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) && getmntany(zhp->zfs_hdl->libzfs_mnttab, &entry, &search) == 0)) { /* * mountpoint may have come from a call to * getmnt/getmntany if it isn't NULL. If it is NULL, * we know it comes from getmntany which can then get * overwritten later. We strdup it to play it safe. */ if (mountpoint == NULL) mntpt = zfs_strdup(zhp->zfs_hdl, entry.mnt_mountp); else mntpt = zfs_strdup(zhp->zfs_hdl, mountpoint); /* * Unshare and unmount the filesystem */ #ifndef __APPLE__ if (zfs_unshare_proto(zhp, mntpt, share_all_proto) != 0) return (-1); #endif if (unmount_one(zhp->zfs_hdl, mntpt, flags) != 0) { free(mntpt); (void) zfs_shareall(zhp); return (-1); } free(mntpt); } return (0); } /* * Unmount this filesystem and any children inheriting the mountpoint property. * To do this, just act like we're changing the mountpoint property, but don't * remount the filesystems afterwards. */ int zfs_unmountall(zfs_handle_t *zhp, int flags) { prop_changelist_t *clp; int ret; clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT, flags); if (clp == NULL) return (-1); ret = changelist_prefix(clp); changelist_free(clp); return (ret); }