示例#1
0
static ERL_NIF_TERM
read_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
	ks_returner_t	*ret;
	ERL_NIF_TERM	term, statistics;
	ks_handle_t	*handle;
	ks_instance_t	*ksi;
	ks_nvpair_t	*nvpair;
	char		*ks_number;
	ks_selector_t	*selector;
	int		matched;

	ret = new_returner(env);

	if (argc < 1 || argc > 6) {
		return EKSTAT_RETURN(enif_make_badarg(ret->env));
	}

	if (!enif_get_resource(env, argv[0], kstat_handle, (void **)(&handle))) {
		return EKSTAT_RETURN(enif_make_badarg(ret->env));
	}

	selector = new_selector(ret);

	if (ret->ready == B_TRUE) {
		if ((void *)(selector) != NULL) {
			free_selector(selector);
		}
		return EKSTAT_RETURN(ret->term);
	}

	switch (argc) {
	case 2:
		(void) ks_selector_arg(ret, &selector->ks_class, argv[1]);
		break;
	case 3:
		(void) ks_selector_arg(ret, &selector->ks_class, argv[1]);
		(void) ks_selector_arg(ret, &selector->ks_module, argv[2]);
		break;
	case 4:
		(void) ks_selector_arg(ret, &selector->ks_class, argv[1]);
		(void) ks_selector_arg(ret, &selector->ks_module, argv[2]);
		(void) ks_selector_arg(ret, &selector->ks_instance, argv[3]);
		break;
	case 5:
		(void) ks_selector_arg(ret, &selector->ks_class, argv[1]);
		(void) ks_selector_arg(ret, &selector->ks_module, argv[2]);
		(void) ks_selector_arg(ret, &selector->ks_instance, argv[3]);
		(void) ks_selector_arg(ret, &selector->ks_name, argv[4]);
		break;
	case 6:
		(void) ks_selector_arg(ret, &selector->ks_class, argv[1]);
		(void) ks_selector_arg(ret, &selector->ks_module, argv[2]);
		(void) ks_selector_arg(ret, &selector->ks_instance, argv[3]);
		(void) ks_selector_arg(ret, &selector->ks_name, argv[4]);
		(void) ks_selector_arg(ret, &selector->ks_statistic, argv[5]);
		break;
	default:
		break;
	}

	if (ret->ready == B_TRUE) {
		free_selector(selector);
		return EKSTAT_RETURN(ret->term);
	}

	term = enif_make_list(env, 0);

	/* Iterate over each instance */
	for (ksi = list_head(&handle->instances_list); ksi != NULL; ksi = list_next(&handle->instances_list, ksi)) {
		matched = 0;
		statistics = (ERL_NIF_TERM)(NULL);

		(void) asprintf(&ks_number, "%d", ksi->ks_instance);
		if (
			!(ks_match(ret, ksi->ks_module, &selector->ks_module) &&
			ks_match(ret, ksi->ks_name, &selector->ks_name) &&
			ks_match(ret, ks_number, &selector->ks_instance) &&
			ks_match(ret, ksi->ks_class, &selector->ks_class))
		) {
			free(ks_number);
			if (ret->ready == B_TRUE) {
				free_selector(selector);
				return EKSTAT_RETURN(ret->term);
			}
			continue;
		}

		free(ks_number);

		/* Finally iterate over each statistic */
		for (nvpair = list_head(&ksi->ks_nvlist); nvpair != NULL; nvpair = list_next(&ksi->ks_nvlist, nvpair)) {
			if (!ks_match(ret, nvpair->name, &selector->ks_statistic)) {
				if (ret->ready == B_TRUE) {
					free_selector(selector);
					return EKSTAT_RETURN(ret->term);
				}
				continue;
			}

			if ((void *)(statistics) == NULL) {
				statistics = enif_make_list(env, 0);
			}

			matched = 1;
			statistics = enif_make_list_cell(env, ks_nvpair_term(ret, nvpair), statistics);
		}

		if (matched == 1) {
			term = enif_make_list_cell(env, ks_instance_term(ret, ksi, statistics), term);
		}
	}

	free_selector(selector);

	return EKSTAT_RETURN(term);
}
示例#2
0
/*
* Iterate over all kernel statistics and save matches.
*/
static void
ks_instances_read(kstat_ctl_t *kc)
{
kstat_raw_reader_t save_raw = NULL;
kid_t		id;
ks_selector_t	*selector;
ks_instance_t	*ksi;
ks_instance_t	*tmp;
kstat_t		*kp;
boolean_t	skip;

for (kp = kc->kc_chain; kp != NULL; kp = kp->ks_next) {
	/* Don't bother storing the kstat headers */
	if (strncmp(kp->ks_name, "kstat_", 6) == 0) {
		continue;
	}

	/* Don't bother storing raw stats we don't understand */
	if (kp->ks_type == KSTAT_TYPE_RAW) {
		save_raw = lookup_raw_kstat_fn(kp->ks_module,
				kp->ks_name);
		if (save_raw == NULL) {
#ifdef REPORT_UNKNOWN
			(void) fprintf(stderr,
					"Unknown kstat type %s:%d:%s - "
					"%d of size %d\n", kp->ks_module,
					kp->ks_instance, kp->ks_name,
					kp->ks_ndata, kp->ks_data_size);
#endif
			continue;
		}
	}

	/*
	 * Iterate over the list of selectors and skip
	 * instances we dont want. We filter for statistics
	 * later, as we dont know them yet.
	 */
	skip = B_TRUE;
	selector = list_head(&selector_list);
	while (selector != NULL) {
		if (ks_match(kp->ks_module, &selector->ks_module) &&
				ks_match(kp->ks_name, &selector->ks_name)) {
			skip = B_FALSE;
			break;
		}
		selector = list_next(&selector_list, selector);
	}

	if (skip) {
		continue;
	}

	/*
	 * Allocate a new instance and fill in the values
	 * we know so far.
	 */
	ksi = (ks_instance_t *)malloc(sizeof (ks_instance_t));
	if (ksi == NULL) {
		perror("malloc");
		exit(3);
	}

	list_link_init(&ksi->ks_next);

	(void) strlcpy(ksi->ks_zone, "global", KSTAT_STRLEN);
	(void) strlcpy(ksi->ks_module, kp->ks_module, KSTAT_STRLEN);
	(void) strlcpy(ksi->ks_name, kp->ks_name, KSTAT_STRLEN);
	(void) strlcpy(ksi->ks_class, kp->ks_class, KSTAT_STRLEN);

	ksi->ks_instance = kp->ks_instance;
	ksi->ks_snaptime = kp->ks_snaptime;
	ksi->ks_type = kp->ks_type;

	list_create(&ksi->ks_nvlist, sizeof (ks_nvpair_t),
			offsetof(ks_nvpair_t, nv_next));

	SAVE_HRTIME_X(ksi, "crtime", kp->ks_crtime);
	SAVE_HRTIME_X(ksi, "snaptime", kp->ks_snaptime);
	if (g_pflg) {
		SAVE_STRING_X(ksi, "class", kp->ks_class);
	}

	/* Insert this instance into a sorted list */
	tmp = list_head(&instances_list);
	while (tmp != NULL && compare_instances(ksi, tmp) > 0)
		tmp = list_next(&instances_list, tmp);

	list_insert_before(&instances_list, tmp, ksi);

	/* Read the actual statistics */
	id = kstat_read(kc, kp, NULL);
	if (id == -1) {
#ifdef REPORT_UNKNOWN
		perror("kstat_read");
#endif
		continue;
	}

	switch (kp->ks_type) {
	case KSTAT_TYPE_RAW:
		save_raw(kp, ksi);
		break;
	case KSTAT_TYPE_NAMED:
		save_named(kp, ksi);
		break;
	case KSTAT_TYPE_INTR:
		save_intr(kp, ksi);
		break;
	case KSTAT_TYPE_IO:
		save_io(kp, ksi);
		break;
	case KSTAT_TYPE_TIMER:
		save_timer(kp, ksi);
		break;
	default:
		assert(B_FALSE); /* Invalid type */
		break;
	}
}
}