/* * Sort datasets by specified columns. * * o Numeric types sort in ascending order. * o String types sort in alphabetical order. * o Types inappropriate for a row sort that row to the literal * bottom, regardless of the specified ordering. * * If no sort columns are specified, or two datasets compare equally * across all specified columns, they are sorted alphabetically by name * with snapshots grouped under their parents. */ static int zfs_sort(const void *larg, const void *rarg, void *data) { zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle; zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle; zfs_sort_column_t *sc = (zfs_sort_column_t *)data; zfs_sort_column_t *psc; for (psc = sc; psc != NULL; psc = psc->sc_next) { char lbuf[ZFS_MAXPROPLEN], rbuf[ZFS_MAXPROPLEN]; char *lstr, *rstr; uint64_t lnum, rnum; boolean_t lvalid, rvalid; int ret = 0; /* * We group the checks below the generic code. If 'lstr' and * 'rstr' are non-NULL, then we do a string based comparison. * Otherwise, we compare 'lnum' and 'rnum'. */ lstr = rstr = NULL; if (psc->sc_prop == ZPROP_INVAL) { nvlist_t *luser, *ruser; nvlist_t *lval, *rval; luser = zfs_get_user_props(l); ruser = zfs_get_user_props(r); lvalid = (nvlist_lookup_nvlist(luser, psc->sc_user_prop, &lval) == 0); rvalid = (nvlist_lookup_nvlist(ruser, psc->sc_user_prop, &rval) == 0); if (lvalid) verify(nvlist_lookup_string(lval, ZPROP_VALUE, &lstr) == 0); if (rvalid) verify(nvlist_lookup_string(rval, ZPROP_VALUE, &rstr) == 0); } else if (psc->sc_prop == ZFS_PROP_NAME) { lvalid = rvalid = B_TRUE; (void) strlcpy(lbuf, zfs_get_name(l), sizeof(lbuf)); (void) strlcpy(rbuf, zfs_get_name(r), sizeof(rbuf)); lstr = lbuf; rstr = rbuf; } else if (zfs_prop_is_string(psc->sc_prop)) { lvalid = (zfs_prop_get(l, psc->sc_prop, lbuf, sizeof (lbuf), NULL, NULL, 0, B_TRUE) == 0); rvalid = (zfs_prop_get(r, psc->sc_prop, rbuf, sizeof (rbuf), NULL, NULL, 0, B_TRUE) == 0); lstr = lbuf; rstr = rbuf; } else { lvalid = zfs_prop_valid_for_type(psc->sc_prop, zfs_get_type(l)); rvalid = zfs_prop_valid_for_type(psc->sc_prop, zfs_get_type(r)); if (lvalid) (void) zfs_prop_get_numeric(l, psc->sc_prop, &lnum, NULL, NULL, 0); if (rvalid) (void) zfs_prop_get_numeric(r, psc->sc_prop, &rnum, NULL, NULL, 0); } if (!lvalid && !rvalid) continue; else if (!lvalid) return (1); else if (!rvalid) return (-1); if (lstr) ret = strcmp(lstr, rstr); else if (lnum < rnum) ret = -1; else if (lnum > rnum) ret = 1; if (ret != 0) { if (psc->sc_reverse == B_TRUE) ret = (ret < 0) ? 1 : -1; return (ret); } } return (zfs_compare(larg, rarg, NULL)); }
int main(int argc, char **argv) { struct extmnttab mnt; FILE *fp; fp = fopen("/etc/mnttab", "r"); if(!fp) { perror("fopen"); exit(-1); } while(getextmntent(fp, &mnt, sizeof (struct extmnttab)) == 0) { struct statvfs buf; int i; for(i=0;suppress_fstype[i] != NULL;i++) if(!strcmp(mnt.mnt_fstype, suppress_fstype[i])) break; if (suppress_fstype[i] == NULL && statvfs(mnt.mnt_mountp, &buf) == 0) { if(!strcmp(mnt.mnt_fstype, "zfs")) { uint64_t used, avail; uint64_t *space_used = NULL, *space_avail = NULL; libzfs_handle_t *zfsh = libzfs_init(); zfs_handle_t *handle = zfs_path_to_zhandle(zfsh, (char *)mnt.mnt_mountp, ZFS_TYPE_FILESYSTEM); if(handle) { char source[ZFS_MAXNAMELEN]; zprop_source_t srctype; int rv; #define ZFS_PULL_N_PRINT(prop, name, T, F, expr) do { \ uint64_t datum; \ if(zfs_prop_get_numeric(handle, prop, \ &datum, &srctype, source, sizeof(source)) == 0) { \ printf("zfs`%s`" name "\t" T" \t" F "\n", mnt.mnt_mountp, expr); \ } \ } while(0) uint64_t used = -1, avail = -1; if(zfs_prop_get_numeric(handle, ZFS_PROP_USEDDS, &used, &srctype, source, sizeof(source)) == 0) { printf("zfs`%s`used\tL\t%llu\n", mnt.mnt_mountp, used); } if(zfs_prop_get_numeric(handle, ZFS_PROP_AVAILABLE, &avail, &srctype, source, sizeof(source)) == 0) { printf("zfs`%s`avail\tL\t%llu\n", mnt.mnt_mountp, avail); } if(used != -1 && avail != -1) { printf("zfs`%s`used_percent\tn\t%f\n", mnt.mnt_mountp, 100.0 * (used / (double)(used + avail))); } ZFS_PULL_N_PRINT(ZFS_PROP_USEDCHILD, "used_children", "L", "%llu", datum); ZFS_PULL_N_PRINT(ZFS_PROP_USEDSNAP, "used_snapshot", "L", "%llu", datum); ZFS_PULL_N_PRINT(ZFS_PROP_REFERENCED, "referenced", "L", "%llu", datum); ZFS_PULL_N_PRINT(ZFS_PROP_RECORDSIZE, "record_size", "L", "%llu", datum); ZFS_PULL_N_PRINT(ZFS_PROP_QUOTA, "quota", "L", "%llu", datum); ZFS_PULL_N_PRINT(ZFS_PROP_RESERVATION, "reservation", "L", "%llu", datum); ZFS_PULL_N_PRINT(ZFS_PROP_REFRESERVATION, "ref_reservation", "L", "%llu", datum); ZFS_PULL_N_PRINT(ZFS_PROP_USEDREFRESERV, "ref_reservation_used", "L", "%llu", datum); #ifdef HAVE_LOGICAL_USED ZFS_PULL_N_PRINT(ZFS_PROP_LOGICALUSED, "logical_used", "L", "%llu", datum); ZFS_PULL_N_PRINT(ZFS_PROP_LOGICALREFERENCED, "logical_referenced", "L", "%llu", datum); #endif ZFS_PULL_N_PRINT(ZFS_PROP_COMPRESSRATIO, "compress_ratio", "n", "%f", (double)datum/100.0); zfs_close(handle); } libzfs_fini(zfsh); } else { printf("fs`%s`f_bsize\tL\t%llu\n", mnt.mnt_mountp, buf.f_bsize); printf("fs`%s`f_frsize\tL\t%llu\n", mnt.mnt_mountp, buf.f_frsize); printf("fs`%s`f_blocks\tL\t%llu\n", mnt.mnt_mountp, buf.f_blocks); printf("fs`%s`f_bfree\tL\t%llu\n", mnt.mnt_mountp, buf.f_bfree); printf("fs`%s`f_bavail\tL\t%llu\n", mnt.mnt_mountp, buf.f_bavail); printf("fs`%s`f_files\tL\t%llu\n", mnt.mnt_mountp, buf.f_blocks); printf("fs`%s`f_ffree\tL\t%llu\n", mnt.mnt_mountp, buf.f_ffree); printf("fs`%s`f_favail\tL\t%llu\n", mnt.mnt_mountp, buf.f_favail); } } } exit(0); }