Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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);
}