static int setmntpaths_stat(struct stat const *st, struct nix_statfs *dest, nix_env_t *env) { FILE *fp; struct extmnttab ent; fp = fopen("/etc/mnttab", "r"); if(fp == NULL) { nix_env_set_errno(env, errno); return (-1); } #ifdef HAVE_RESETMNTTAB resetmnttab(fp); #endif while ((getextmntent(fp, &ent, sizeof(ent))) == 0) { if (ent.mnt_major == major(st->st_dev) && ent.mnt_minor == minor(st->st_dev)) { setmntpaths_mntent(&ent, dest); break; } } fclose(fp); }
static void build_mnt_list(FILE *mpt) { mnt_t *item; mnt_t **which; mnt_t *tmp; int found; struct extmnttab mnt; if (mpt) { while (nfs) { free(nfs->device_name); free(nfs->mount_point); free(nfs->devinfo); tmp = nfs; nfs = nfs->next; free(tmp); } while (ufs) { free(ufs->device_name); free(ufs->mount_point); free(ufs->devinfo); tmp = ufs; ufs = ufs->next; free(tmp); } (void) memset(&mnt, 0, sizeof (struct extmnttab)); resetmnttab(mpt); while ((found = getextmntent(mpt, &mnt, sizeof (struct extmnttab))) != -1) { if (found == 0) { if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) == 0) which = &ufs; else if (strcmp(mnt.mnt_fstype, MNTTYPE_NFS) == 0) which = &nfs; else which = 0; if (which) { item = safe_alloc(sizeof (mnt_t)); item->device_name = safe_strdup(mnt.mnt_special); item->mount_point = safe_strdup(mnt.mnt_mountp); item->devinfo = safe_strdup(mnt.mnt_mntopts); item->minor = mnt.mnt_minor; item->next = *which; *which = item; } } } } }
void CollectorSolaris::updateFilesystemMap(void) { FILE *fp = fopen("/etc/mnttab", "r"); if (fp) { struct mnttab Entry; int rc = 0; resetmnttab(fp); while ((rc = getmntent(fp, &Entry)) == 0) mFsMap[Entry.mnt_mountp] = Entry.mnt_special; fclose(fp); if (rc != -1) LogRel(("Error while reading mnttab: %d\n", rc)); } }
/* * Print the mount table info */ static void mi_print(void) { FILE *mt; struct extmnttab m; struct myrec *list, *mrp, *pmrp; char *flavor; int ignored = 0; seconfig_t nfs_sec; kstat_t *ksp; struct mntinfo_kstat mik; int transport_flag = 0; int path_count; int found; char *timer_name[] = { "Lookups", "Reads", "Writes", "All" }; mt = fopen(MNTTAB, "r"); if (mt == NULL) { perror(MNTTAB); exit(0); } list = NULL; resetmnttab(mt); while (getextmntent(mt, &m, sizeof (struct extmnttab)) == 0) { /* ignore non "nfs" and save the "ignore" entries */ if (strcmp(m.mnt_fstype, MNTTYPE_NFS) != 0) continue; /* * Check to see here if user gave a path(s) to * only show the mount point they wanted * Iterate through the list of paths the user gave and see * if any of them match our current nfs mount */ if (path[0] != NULL) { found = 0; for (path_count = 0; path[path_count] != NULL; path_count++) { if (strcmp(path[path_count], m.mnt_mountp) == 0) { found = 1; break; } } if (!found) continue; } if ((mrp = malloc(sizeof (struct myrec))) == 0) { fprintf(stderr, "nfsstat: not enough memory\n"); exit(1); } mrp->my_fsid = makedev(m.mnt_major, m.mnt_minor); if (ignore(m.mnt_mntopts)) { /* * ignored entries cannot be ignored for this * option. We have to display the info for this * nfs mount. The ignore is an indication * that the actual mount point is different and * something is in between the nfs mount. * So save the mount point now */ if ((mrp->ig_path = malloc( strlen(m.mnt_mountp) + 1)) == 0) { fprintf(stderr, "nfsstat: not enough memory\n"); exit(1); } (void) strcpy(mrp->ig_path, m.mnt_mountp); ignored++; } else { mrp->ig_path = 0; (void) strcpy(mrp->my_dir, m.mnt_mountp); } if ((mrp->my_path = strdup(m.mnt_special)) == NULL) { fprintf(stderr, "nfsstat: not enough memory\n"); exit(1); } mrp->next = list; list = mrp; } /* * If something got ignored, go to the beginning of the mnttab * and look for the cachefs entries since they are the one * causing this. The mount point saved for the ignored entries * is matched against the special to get the actual mount point. * We are interested in the acutal mount point so that the output * look nice too. */ if (ignored) { rewind(mt); resetmnttab(mt); while (getextmntent(mt, &m, sizeof (struct extmnttab)) == 0) { /* ignore non "cachefs" */ if (strcmp(m.mnt_fstype, MNTTYPE_CACHEFS) != 0) continue; for (mrp = list; mrp; mrp = mrp->next) { if (mrp->ig_path == 0) continue; if (strcmp(mrp->ig_path, m.mnt_special) == 0) { mrp->ig_path = 0; (void) strcpy(mrp->my_dir, m.mnt_mountp); } } } /* * Now ignored entries which do not have * the my_dir initialized are really ignored; This never * happens unless the mnttab is corrupted. */ for (pmrp = 0, mrp = list; mrp; mrp = mrp->next) { if (mrp->ig_path == 0) pmrp = mrp; else if (pmrp) pmrp->next = mrp->next; else list = mrp->next; } } (void) fclose(mt); for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) { int i; if (ksp->ks_type != KSTAT_TYPE_RAW) continue; if (strcmp(ksp->ks_module, "nfs") != 0) continue; if (strcmp(ksp->ks_name, "mntinfo") != 0) continue; for (mrp = list; mrp; mrp = mrp->next) { if ((mrp->my_fsid & MAXMIN) == ksp->ks_instance) break; } if (mrp == 0) continue; if (safe_kstat_read(kc, ksp, &mik) == -1) continue; printf("%s from %s\n", mrp->my_dir, mrp->my_path); /* * for printing rdma transport and provider string. * This way we avoid modifying the kernel mntinfo_kstat * struct for protofmly. */ if (strcmp(mik.mik_proto, "ibtf") == 0) { printf(" Flags: vers=%u,proto=rdma", mik.mik_vers); transport_flag = 1; } else { printf(" Flags: vers=%u,proto=%s", mik.mik_vers, mik.mik_proto); transport_flag = 0; } /* * get the secmode name from /etc/nfssec.conf. */ if (!nfs_getseconfig_bynumber(mik.mik_secmod, &nfs_sec)) { flavor = nfs_sec.sc_name; } else flavor = NULL; if (flavor != NULL) printf(",sec=%s", flavor); else printf(",sec#=%d", mik.mik_secmod); printf(",%s", (mik.mik_flags & MI_HARD) ? "hard" : "soft"); if (mik.mik_flags & MI_PRINTED) printf(",printed"); printf(",%s", (mik.mik_flags & MI_INT) ? "intr" : "nointr"); if (mik.mik_flags & MI_DOWN) printf(",down"); if (mik.mik_flags & MI_NOAC) printf(",noac"); if (mik.mik_flags & MI_NOCTO) printf(",nocto"); if (mik.mik_flags & MI_DYNAMIC) printf(",dynamic"); if (mik.mik_flags & MI_LLOCK) printf(",llock"); if (mik.mik_flags & MI_GRPID) printf(",grpid"); if (mik.mik_flags & MI_RPCTIMESYNC) printf(",rpctimesync"); if (mik.mik_flags & MI_LINK) printf(",link"); if (mik.mik_flags & MI_SYMLINK) printf(",symlink"); if (mik.mik_vers < NFS_V4 && mik.mik_flags & MI_READDIRONLY) printf(",readdironly"); if (mik.mik_flags & MI_ACL) printf(",acl"); if (mik.mik_vers >= NFS_V4) { if (mik.mik_flags & MI4_MIRRORMOUNT) printf(",mirrormount"); } printf(",rsize=%d,wsize=%d,retrans=%d,timeo=%d", mik.mik_curread, mik.mik_curwrite, mik.mik_retrans, mik.mik_timeo); printf("\n"); printf(" Attr cache: acregmin=%d,acregmax=%d" ",acdirmin=%d,acdirmax=%d\n", mik.mik_acregmin, mik.mik_acregmax, mik.mik_acdirmin, mik.mik_acdirmax); if (transport_flag) { printf(" Transport: proto=rdma, plugin=%s\n", mik.mik_proto); } #define srtt_to_ms(x) x, (x * 2 + x / 2) #define dev_to_ms(x) x, (x * 5) for (i = 0; i < NFS_CALLTYPES + 1; i++) { int j; j = (i == NFS_CALLTYPES ? i - 1 : i); if (mik.mik_timers[j].srtt || mik.mik_timers[j].rtxcur) { printf(" %s: srtt=%d (%dms), " "dev=%d (%dms), cur=%u (%ums)\n", timer_name[i], srtt_to_ms(mik.mik_timers[i].srtt), dev_to_ms(mik.mik_timers[i].deviate), mik.mik_timers[i].rtxcur, mik.mik_timers[i].rtxcur * 20); } } if (strchr(mrp->my_path, ',')) printf( " Failover: noresponse=%d,failover=%d," "remap=%d,currserver=%s\n", mik.mik_noresponse, mik.mik_failover, mik.mik_remap, mik.mik_curserver); printf("\n"); } }
/* * set_mntpt() looks at the entity's name (e_name) and finds its * mountpoint. To do this, we need to build a list of mountpoints * from /etc/mnttab. We only need to do this once and we don't do it * if we don't need to look at any mountpoints. * Returns 0 on success, non-zero if it couldn't find a mount-point. */ int set_mntpt(entity_t *ep) { static struct mnt { struct mnt *m_next; char *m_mntpt; ulong_t m_fsid; /* From statvfs(), set only as needed */ } *mnt_list = NULL; /* Linked list of mount-points */ struct mnt *mntp; struct statvfs64 statvfsbuf; char *original_name = ep->e_name; char path[PATH_MAX]; if (original_name == NULL) /* Shouldn't happen */ return (1); /* We only set up mnt_list the first time this is called */ if (mnt_list == NULL) { FILE *fp; struct mnttab mnttab; if ((fp = fopen(MNTTAB, "r")) == NULL) { perror(MNTTAB); return (1); } resetmnttab(fp); /* * We insert at the front of the list so that when we * search entries we'll have the last mounted entries * first in the list so that we can match the longest * mountpoint. */ while (getmntent(fp, &mnttab) == 0) { if ((mntp = malloc(sizeof (*mntp))) == NULL) { perror("malloc() mount list"); return (1); } mntp->m_mntpt = strdup(mnttab.mnt_mountp); mntp->m_next = mnt_list; mnt_list = mntp; } (void) fclose(fp); } if (realpath(original_name, path) == NULL) { perror(original_name); return (1); } /* * Now that we have the path, walk through the mnt_list and * look for the first (best) match. */ for (mntp = mnt_list; mntp; mntp = mntp->m_next) { if (strncmp(path, mntp->m_mntpt, strlen(mntp->m_mntpt)) == 0) { if (mntp->m_fsid == 0) { if (statvfs64(mntp->m_mntpt, &statvfsbuf)) { /* Can't statvfs so no match */ continue; } else { mntp->m_fsid = statvfsbuf.f_fsid; } } if (ep->e_fsid != mntp->m_fsid) { /* No match - Move on */ continue; } break; } } if (mntp == NULL) { (void) fprintf(stderr, gettext( "Can't find mount point for %s\n"), path); return (1); } ep->e_name = strdup(mntp->m_mntpt); free(original_name); return (0); }
int get_disk_info(char * _device, char * _uuid, char * _label, char * _name) { int r; fslabel_t label; # ifdef USE_STRUCT_MNTENT struct mntent *entry; # elif defined(USE_STRUCT_MNTTAB) struct mnttab *entry, ebuf; # else struct statfs *entry; # endif # ifdef HAVE_SETMNTENT FILE *table; if (!(table = setmntent(_PATH_MOUNTED, "r"))) return -1; # elif defined(USE_STRUCT_MNTTAB) FILE *table; if (!(table = fopen(_PATH_MOUNTED, "r"))) return -1; resetmnttab(table); # endif # ifdef USE_STRUCT_MNTENT while ((entry = getmntent(table)) != 0) # elif defined(USE_STRUCT_MNTTAB) entry = &ebuf; while (!getmntent(table, entry)) # define mnt_fsname mnt_special # define mnt_dir mnt_mountp # else int mnts; if (!(mnts = getmntinfo(&entry, MNT_NOWAIT))) return -1; for (mnts--; mnts >= 0; mnts--) # define mnt_fsname f_mntfromname # define mnt_dir f_mntonname # define entry (entry + mnts) # endif { if (strcmp(entry->mnt_fsname, _device) == 0 || strcmp(entry->mnt_dir, _device) == 0) { if ((r = fslabel_identify(entry->mnt_fsname, &label)) == 1) { strncpy(_uuid, label.uuid, sizeof(label.uuid) - 1); _uuid[sizeof(label.uuid) - 1] = 0; strncpy(_label, label.label, sizeof(label.label) - 1); _label[sizeof(label.label) - 1] = 0; } else { _uuid[0] = 0; _label[0] = 0; /* printf("fslabel: %s: cannot identify filesystem.\n", entry->mnt_fsname); */ } strncpy(_name, entry->mnt_dir, PATH_MAX - 1); _name[PATH_MAX - 1] = 0; strncpy(_device, entry->mnt_fsname, PATH_MAX - 1); _device[PATH_MAX - 1] = 0; break; } } # ifdef HAVE_SETMNTENT endmntent(table); # elif defined(USE_STRUCT_MNTTAB) fclose(table); # endif 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); }