Beispiel #1
0
static ERL_NIF_TERM
update_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
	ks_returner_t	*ret;
	kstat_raw_reader_t	save_raw = NULL;
	ks_handle_t	*handle;
	kid_t		id;
	ks_instance_t	*ksi, *ktmp;
	ks_nvpair_t	*nvpair, *ntmp;
	kstat_t		*kp;
	int		count = 0;

	ret = new_returner(env);

	if (argc < 1) {
		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));
	}

	if ((id = kstat_chain_update(handle->ks_ctl)) == 0 && handle->ks_id != -1) {
		return EKSTAT_RETURN(EKSTAT_ERROR("kstat_chain_update stopped"));
	}

	if (id == -1) {
		return EKSTAT_RETURN(EKSTAT_ERROR("kid not valid"));
	}

	/* Free the instances list */
	ksi = list_head(&handle->instances_list);
	while (ksi != NULL) {
		nvpair = list_head(&ksi->ks_nvlist);
		while (nvpair != NULL) {
			ntmp = nvpair;
			nvpair = list_next(&ksi->ks_nvlist, nvpair);
			list_remove(&ksi->ks_nvlist, ntmp);
			if (ntmp->data_type == KSTAT_DATA_STRING)
				free(ntmp->value.str.addr.ptr);
			free(ntmp);
		}

		ktmp = ksi;
		ksi = list_next(&handle->instances_list, ksi);
		list_remove(&handle->instances_list, ktmp);
		list_destroy(&ktmp->ks_nvlist);
		free(ktmp);
	}

	for (kp = handle->ks_ctl->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) {
				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) {
			return EKSTAT_RETURN(EKSTAT_ERROR("ks_instance_t malloc"));
		}

		list_link_init(&ksi->ks_next);

		(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(ret, ksi, "crtime", kp->ks_crtime);
		SAVE_HRTIME_X(ret, ksi, "snaptime", kp->ks_snaptime);

		/* Insert this instance into a sorted list */
		ktmp = list_head(&handle->instances_list);
		while (ktmp != NULL && compare_instances(ksi, ktmp) < 0) {
			ktmp = list_next(&handle->instances_list, ktmp);
		}

		list_insert_before(&handle->instances_list, ktmp, ksi);

		/* Read the actual statistics */
		id = kstat_read(handle->ks_ctl, kp, NULL);
		if (id == -1) {
			continue;
		}

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

		count++;
	}

	return EKSTAT_RETURN(EKSTAT_OK(EKSTAT_INT(count)));
}
Beispiel #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;
	}
}
}