static xmmsv_t * parse_collection (xmmsv_t *dict) { xmmsv_coll_type_t type = 0; xmmsv_t *coll; xmmsv_t *attributes, *operands, *list; const char *name; assert (xmmsv_is_type (dict, XMMSV_TYPE_DICT)); xmmsv_dict_entry_get_string (dict, "type", &name); assert (collection_type_from_string (name, &type)); coll = xmmsv_new_coll (type); if (xmmsv_dict_get (dict, "attributes", &attributes)) parse_attributes (coll, attributes); if (xmmsv_dict_get (dict, "operands", &operands)) parse_operands (coll, operands); if (xmmsv_dict_get (dict, "idlist", &list)) parse_idlist (coll, list); return coll; }
int main(int argc, char *argv[]) { int c; int i, j; /* Generic counters */ int nentities_found; int linesout = 0; /* Keeps track of lines printed */ int printhdr = 0; /* Print a header? 0 = no, 1 = yes */ int nfstypes; /* Number of fstypes */ int dispflag = 0; /* Flags for display control */ long count = 0; /* Number of iterations for display */ int forever; /* Run forever */ long interval = 0; boolean_t fstypes_only = B_FALSE; /* Display fstypes only */ char **fstypes; /* Array of names of all fstypes */ int nentities; /* Number of stat-able entities */ entity_t *entities; /* Array of stat-able entities */ kstat_ctl_t *kc; void (*dfunc)(char *, vopstats_t *, vopstats_t *, int) = dflt_display; hrtime_t start_n; /* Start time */ hrtime_t period_n; /* Interval in nanoseconds */ extern int optind; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ #endif (void) textdomain(TEXT_DOMAIN); /* Don't let buffering interfere with piped output. */ (void) setvbuf(stdout, NULL, _IOLBF, 0); cmdname = argv[0]; while ((c = getopt(argc, argv, OPTIONS)) != EOF) { switch (c) { default: usage(); break; case 'F': /* Only display available FStypes */ fstypes_only = B_TRUE; break; #if PARSABLE_OUTPUT case 'P': /* Parsable output */ dispflag |= DISP_RAW; break; #endif /* PARSABLE_OUTPUT */ case 'T': /* Timestamp */ if (optarg) { if (strcmp(optarg, "u") == 0) { timestamp_fmt = UDATE; } else if (strcmp(optarg, "d") == 0) { timestamp_fmt = DDATE; } } /* If it was never set properly... */ if (timestamp_fmt == NODATE) { (void) fprintf(stderr, gettext("%s: -T option " "requires either 'u' or 'd'\n"), cmdname); usage(); } break; case 'a': set_dispfunc(&dfunc, attr_display); break; case 'f': set_dispfunc(&dfunc, vop_display); break; case 'i': set_dispfunc(&dfunc, io_display); break; case 'n': set_dispfunc(&dfunc, naming_display); break; case 'v': set_dispfunc(&dfunc, vm_display); break; } } #if PARSABLE_OUTPUT if ((dispflag & DISP_RAW) && (timestamp_fmt != NODATE)) { (void) fprintf(stderr, gettext( "-P and -T options are mutually exclusive\n")); usage(); } #endif /* PARSABLE_OUTPUT */ /* Gather the list of filesystem types */ if ((nfstypes = build_fstype_list(&fstypes)) == 0) { (void) fprintf(stderr, gettext("Can't build list of fstypes\n")); exit(1); } nentities = parse_operands( argc, argv, optind, &interval, &count, &entities); forever = count == MAXLONG; period_n = (hrtime_t)interval * NANOSEC; if (nentities == -1) /* Set of operands didn't parse properly */ usage(); if ((nentities == 0) && (fstypes_only == B_FALSE)) { (void) fprintf(stderr, gettext( "Must specify -F or at least one fstype or mount point\n")); usage(); } if ((nentities > 0) && (fstypes_only == B_TRUE)) { (void) fprintf(stderr, gettext( "Cannot use -F with fstypes or mount points\n")); usage(); } /* * If we had no operands (except for interval/count) and we * requested FStypes only (-F), then fill in the entities[] * array with all available fstypes. */ if ((nentities == 0) && (fstypes_only == B_TRUE)) { if ((entities = calloc(nfstypes, sizeof (entity_t))) == NULL) { perror("calloc() fstype stats"); exit(1); } for (i = 1; i < nfstypes; i++) { if (fstypes[i]) { entities[nentities].e_name = strdup(fstypes[i]); nentities++; } } } set_ksnames(entities, nentities, fstypes, nfstypes); if ((kc = kstat_open()) == NULL) { perror("kstat_open"); exit(1); } /* Set start time */ start_n = gethrtime(); /* Initial timestamp */ if (timestamp_fmt != NODATE) { print_timestamp(timestamp_fmt); linesout++; } /* * The following loop walks through the entities[] list to "prime * the pump" */ for (j = 0, printhdr = 1; j < nentities; j++) { entity_t *ent = &entities[j]; vopstats_t *vsp = &ent->e_vs[CUR_INDEX]; kstat_t *ksp = NULL; if (get_vopstats(kc, ent->e_ksname, vsp, &ksp) == 0) { (*dfunc)(ent->e_name, NULL, vsp, dispflag_policy(printhdr, dispflag)); linesout++; } else { /* * If we can't find it the first time through, then * get rid of it. */ entities[j].e_ksname[0] = 0; /* * If we're only displaying FStypes (-F) then don't * complain about any file systems that might not * be loaded. Otherwise, let the user know that * they chose poorly. */ if (fstypes_only == B_FALSE) { (void) fprintf(stderr, gettext( "No statistics available for %s\n"), entities[j].e_name); } } printhdr = 0; } if (count > 1) /* Set up signal handler for SIGCONT */ if (signal(SIGCONT, cont_handler) == SIG_ERR) fail(1, "signal failed"); BUMP_INDEX(); /* Swap the previous/current indices */ i = 1; while (forever || i++ <= count) { /* * No telling how many lines will be printed in any interval. * There should be a minimum of HEADERLINES between any * header. If we exceed that, no big deal. */ if (linesout > HEADERLINES) { linesout = 0; printhdr = 1; } /* Have a kip */ sleep_until(&start_n, period_n, forever, &caught_cont); if (timestamp_fmt != NODATE) { print_timestamp(timestamp_fmt); linesout++; } for (j = 0, nentities_found = 0; j < nentities; j++) { entity_t *ent = &entities[j]; /* * If this entry has been cleared, don't attempt * to process it. */ if (ent->e_ksname[0] == 0) { continue; } if (get_vopstats(kc, ent->e_ksname, &ent->e_vs[CUR_INDEX], NULL) == 0) { (*dfunc)(ent->e_name, &ent->e_vs[PREV_INDEX], &ent->e_vs[CUR_INDEX], dispflag_policy(printhdr, dispflag)); linesout++; nentities_found++; } else { if (ent->e_type == ENTYPE_MNTPT) { (void) printf(gettext( "<<mount point no longer " "available: %s>>\n"), ent->e_name); } else if (ent->e_type == ENTYPE_FSTYPE) { (void) printf(gettext( "<<file system module no longer " "loaded: %s>>\n"), ent->e_name); } else { (void) printf(gettext( "<<%s no longer available>>\n"), ent->e_name); } /* Disable this so it doesn't print again */ ent->e_ksname[0] = 0; } printhdr = 0; /* Always shut this off */ } BUMP_INDEX(); /* Bump the previous/current indices */ /* * If the entities we were observing are no longer there * (file system modules unloaded, file systems unmounted) * then we're done. */ if (nentities_found == 0) break; } return (0); }