示例#1
0
/*ARGSUSED*/
static int
simple_report_collection_cb(lcollection_t *lcol, void *arg)
{
#define	DELTA(field) \
	(unsigned long long)( \
	    (lcol->lcol_stat.field - lcol->lcol_stat_old.field))

	debug("%s %s status: succeeded/attempted (k): %llu/%llu, "
	    "ineffective/scans/unenforced/samplings:  %llu/%llu/%llu/%llu, RSS "
	    "min/max (k): %llu/%llu, cap %llu kB, processes/thpt: %llu/%llu, "
	    "%llu scans over %llu ms\n",
	    (lcol->lcol_id.rcid_type == RCIDT_PROJECT ? "project" : "zone"),
	    lcol->lcol_name,
	    DELTA(lcols_pg_eff), DELTA(lcols_pg_att),
	    DELTA(lcols_scan_ineffective), DELTA(lcols_scan),
	    DELTA(lcols_unenforced_cap), DELTA(lcols_rss_sample),
	    (unsigned long long)lcol->lcol_stat.lcols_min_rss,
	    (unsigned long long)lcol->lcol_stat.lcols_max_rss,
	    (unsigned long long)lcol->lcol_rss_cap,
	    (unsigned long long)(lcol->lcol_stat.lcols_proc_in -
	    lcol->lcol_stat.lcols_proc_out), DELTA(lcols_proc_out),
	    DELTA(lcols_scan_count),
	    NSEC2MSEC(DELTA(lcols_scan_time_complete)));

#undef DELTA

	return (0);
}
示例#2
0
static int
print_delay_handler(int id, const char *pool, zinject_record_t *record,
    void *data)
{
	int *count = data;

	if (record->zi_guid == 0 || record->zi_func[0] != '\0')
		return (0);

	if (record->zi_cmd != ZINJECT_DELAY_IO)
		return (0);

	if (*count == 0) {
		(void) printf("%3s  %-15s  %-15s  %-15s  %s\n",
		    "ID", "POOL", "DELAY (ms)", "LANES", "GUID");
		(void) printf("---  ---------------  ---------------  "
		    "---------------  ----------------\n");
	}

	*count += 1;

	(void) printf("%3d  %-15s  %-15llu  %-15llu  %llx\n", id, pool,
	    (u_longlong_t)NSEC2MSEC(record->zi_timer),
	    (u_longlong_t)record->zi_nlanes,
	    (u_longlong_t)record->zi_guid);

	return (0);
}
示例#3
0
static boolean_t
dsl_scan_check_pause(dsl_scan_t *scn, const zbookmark_t *zb)
{
	uint64_t elapsed_nanosecs;
	int mintime;

	/* we never skip user/group accounting objects */
	if (zb && (int64_t)zb->zb_object < 0)
		return (B_FALSE);

	if (scn->scn_pausing)
		return (B_TRUE); /* we're already pausing */

	if (!ZB_IS_ZERO(&scn->scn_phys.scn_bookmark))
		return (B_FALSE); /* we're resuming */

	/* We only know how to resume from level-0 blocks. */
	if (zb && zb->zb_level != 0)
		return (B_FALSE);

	mintime = (scn->scn_phys.scn_func == POOL_SCAN_RESILVER) ?
	    zfs_resilver_min_time_ms : zfs_scan_min_time_ms;
	elapsed_nanosecs = gethrtime() - scn->scn_sync_start_time;
	if (elapsed_nanosecs / NANOSEC > zfs_txg_timeout ||
	    (NSEC2MSEC(elapsed_nanosecs) > mintime &&
	    txg_sync_waiting(scn->scn_dp)) ||
	    spa_shutting_down(scn->scn_dp->dp_spa)) {
		if (zb) {
			dprintf("pausing at bookmark %llx/%llx/%llx/%llx\n",
			    (longlong_t)zb->zb_objset,
			    (longlong_t)zb->zb_object,
			    (longlong_t)zb->zb_level,
			    (longlong_t)zb->zb_blkid);
			scn->scn_phys.scn_bookmark = *zb;
		}
		dprintf("pausing at DDT bookmark %llx/%llx/%llx/%llx\n",
		    (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_class,
		    (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_type,
		    (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_checksum,
		    (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_cursor);
		scn->scn_pausing = B_TRUE;
		return (B_TRUE);
	}
	return (B_FALSE);
}
示例#4
0
/*ARGSUSED*/
static void
print_unformatted_stats(void)
{
	col_t *col;

#define	DELTA(field) \
	(col->col_src_stat.field - col->col_old_stat.field)

	col = col_head;
	while (col != NULL) {
		if (bcmp(&col->col_src_stat, &col->col_old_stat,
		    sizeof (col->col_src_stat)) == 0) {
			col = col->col_next;
			continue;
		}
		(void) printf("%s %s status: succeeded/attempted (k): "
		    "%llu/%llu, ineffective/scans/unenforced/samplings:  "
		    "%llu/%llu/%llu/%llu, RSS min/max (k): %llu/%llu, cap %llu "
		    "kB, processes/thpt: %llu/%llu, %llu scans over %lld ms\n",
		    mode, col->col_name, DELTA(lcols_pg_eff),
		    DELTA(lcols_pg_att), DELTA(lcols_scan_ineffective),
		    DELTA(lcols_scan), DELTA(lcols_unenforced_cap),
		    DELTA(lcols_rss_sample), col->col_src_stat.lcols_min_rss,
		    col->col_src_stat.lcols_max_rss, col->col_rsslimit,
		    (col->col_src_stat.lcols_proc_in -
		    col->col_old_stat.lcols_proc_out), DELTA(lcols_proc_out),
		    DELTA(lcols_scan_count),
		    NSEC2MSEC(DELTA(lcols_scan_time_complete)));
		col->col_old_stat = col->col_src_stat;

		col = col->col_next;
	}

	if (global)
		(void) printf(gettext("physical memory utilization: %3u%%   "
		    "cap enforcement threshold: %3u%%\n"), hdr.rs_pressure_cur,
		    hdr.rs_pressure_cap);
#undef DELTA
}
示例#5
0
static int
request_log(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	request_log_entry_t cur;
	hrtime_t dur;
	hrtime_t dursec;
	hrtime_t durnsec;
	char durstr[20];
	char stampstr[20];
	char requstr[30];
	char respstr[30];
	char typestr[30];
	uintptr_t node = 0;
	uintptr_t client = 0;
	uint64_t clientid = 0;

	int idx;
	int opt_v = FALSE;			/* verbose */

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("configd_log", "configd_log", argc,
		    argv) == -1) {
			mdb_warn("can't walk 'configd_log'");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (mdb_getopts(argc, argv,
	    'c', MDB_OPT_UINTPTR, &client,
	    'i', MDB_OPT_UINT64, &clientid,
	    'n', MDB_OPT_UINTPTR, &node,
	    'v', MDB_OPT_SETBITS, TRUE, &opt_v, NULL) != argc)
		return (DCMD_USAGE);

	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%<u>%-?s %-4s %-14s %9s %-22s %-17s\n%</u>",
		    "ADDR", "THRD", "START", "DURATION", "REQUEST",
		    "RESPONSE");
	}

	if (mdb_vread(&cur, sizeof (cur), addr) == -1) {
		mdb_warn("couldn't read log entry at %p", addr);
		return (DCMD_ERR);
	}

	/*
	 * apply filters, if any.
	 */
	if (clientid != 0 && clientid != cur.rl_clientid)
		return (DCMD_OK);

	if (client != 0 && client != (uintptr_t)cur.rl_client)
		return (DCMD_OK);

	if (node != 0) {
		for (idx = 0; idx < MIN(MAX_PTRS, cur.rl_num_ptrs); idx++) {
			if ((uintptr_t)cur.rl_ptrs[idx].rlp_data == node) {
				node = 0;		/* found it */
				break;
			}
		}
		if (node != 0)
			return (DCMD_OK);
	}

	enum_lookup(requstr, sizeof (requstr), request_enum, cur.rl_request,
	    "REP_PROTOCOL_", "");

	if (cur.rl_end != 0) {
		enum_lookup(respstr, sizeof (respstr), response_enum,
		    cur.rl_response, "REP_PROTOCOL_", "FAIL_");

		dur = cur.rl_end - cur.rl_start;
		dursec = dur / NANOSEC;
		durnsec = dur % NANOSEC;

		if (dursec <= 9)
			mdb_snprintf(durstr, sizeof (durstr),
			    "%lld.%06lld",
			    dursec, durnsec / (NANOSEC / MICROSEC));
		else if (dursec <= 9999)
			mdb_snprintf(durstr, sizeof (durstr),
			    "%lld.%03lld",
			    dursec, NSEC2MSEC(durnsec));
		else
			mdb_snprintf(durstr, sizeof (durstr),
			    "%lld", dursec);
	} else {
		(void) strcpy(durstr, "-");
		(void) strcpy(respstr, "-");
	}

	if (max_time_seen != 0 && max_time_seen >= cur.rl_start) {
		dur = max_time_seen - cur.rl_start;
		dursec = dur / NANOSEC;
		durnsec = dur % NANOSEC;

		if (dursec <= 99ULL)
			mdb_snprintf(stampstr, sizeof (stampstr),
			    "-%lld.%09lld", dursec, durnsec);
		else if (dursec <= 99999ULL)
			mdb_snprintf(stampstr, sizeof (stampstr),
			    "-%lld.%06lld",
			    dursec, durnsec / (NANOSEC / MICROSEC));
		else if (dursec <= 99999999ULL)
			mdb_snprintf(stampstr, sizeof (stampstr),
			    "-%lld.%03lld",
			    dursec, NSEC2MSEC(durnsec));
		else
			mdb_snprintf(stampstr, sizeof (stampstr),
			    "-%lld", dursec);
	} else {
		(void) strcpy(stampstr, "-");
	}

	mdb_printf("%0?x %4d T%13s %9s %-22s %-17s\n",
	    addr, cur.rl_tid, stampstr, durstr, requstr, respstr);

	if (opt_v) {
		mdb_printf("\tclient: %?p (%d)\tptrs: %d\tstamp: %llx\n",
		    cur.rl_client, cur.rl_clientid, cur.rl_num_ptrs,
		    cur.rl_start);
		for (idx = 0; idx < MIN(MAX_PTRS, cur.rl_num_ptrs); idx++) {
			enum_lookup(typestr, sizeof (typestr), ptr_type_enum,
			    cur.rl_ptrs[idx].rlp_type, "RC_PTR_TYPE_", "");
			mdb_printf("\t\t%-7s %5d %?p %?p\n", typestr,
			    cur.rl_ptrs[idx].rlp_id, cur.rl_ptrs[idx].rlp_ptr,
			    cur.rl_ptrs[idx].rlp_data);
		}
		mdb_printf("\n");
	}
	return (DCMD_OK);
}
示例#6
0
/*
 * Get a DLPI control message and/or data message from a stream. The inputs
 * for this function are:
 * 	dlpi_impl_t *dip: 	internal dlpi handle
 * 	int msec: 		timeout to wait for message
 *	dlpi_msg_t *dlreplyp:	reply message structure, the message size
 *				member on return stores actual size received
 *	t_uscalar_t dlreqprim: 	requested primitive
 *	t_uscalar_t dlreplyprim:acknowledged primitive in response to request
 *	size_t dlreplyminsz:	minimum size of acknowledged primitive size
 *	void *databuf: 		data buffer
 *	size_t *datalenp:	data buffer len
 *	size_t *totdatalenp: 	total data received. Greater than 'datalenp' if
 *				actual data received is larger than 'databuf'
 * Function returns DLPI_SUCCESS if requested message is retrieved
 * otherwise returns error code or timeouts. If a notification arrives on
 * the stream the callback is notified. However, error returned during the
 * handling of notification is ignored as it would be confusing to actual caller
 * of this function.
 */
static int
i_dlpi_strgetmsg(dlpi_impl_t *dip, int msec, dlpi_msg_t *dlreplyp,
    t_uscalar_t dlreqprim, t_uscalar_t dlreplyprim, size_t dlreplyminsz,
    void *databuf, size_t *datalenp, size_t *totdatalenp)
{
	int			retval;
	int			flags;
	int			fd = dip->dli_fd;
	struct strbuf		ctl, data;
	struct pollfd		pfd;
	hrtime_t		start, current;
	long			bufc[DLPI_CHUNKSIZE / sizeof (long)];
	long			bufd[DLPI_CHUNKSIZE / sizeof (long)];
	union DL_primitives	*dlprim;
	dl_notify_ind_t		*dlnotif;
	boolean_t		infinite = (msec < 0);	/* infinite timeout */

	/*
	 * dlreplyp and databuf can be NULL at the same time, to force a check
	 * for pending events on the DLPI link instance; dlpi_enabnotify(3DLPI).
	 * this will be true more so for DLPI_RAW mode with notifications
	 * enabled.
	 */
	if ((databuf == NULL && datalenp != NULL) ||
	    (databuf != NULL && datalenp == NULL))
		return (DLPI_EINVAL);

	pfd.fd = fd;
	pfd.events = POLLIN | POLLPRI;

	ctl.buf = (dlreplyp == NULL) ? bufc : (void *)dlreplyp->dlm_msg;
	ctl.len = 0;
	ctl.maxlen = (dlreplyp == NULL) ? sizeof (bufc) : dlreplyp->dlm_msgsz;

	data.buf = (databuf == NULL) ? bufd : databuf;
	data.len = 0;
	data.maxlen = (databuf == NULL) ? sizeof (bufd): *datalenp;

	for (;;) {
		if (!infinite)
			start = NSEC2MSEC(gethrtime());

		switch (poll(&pfd, 1, msec)) {
		default:
			if (pfd.revents & POLLHUP)
				return (DL_SYSERR);
			break;
		case 0:
			return (DLPI_ETIMEDOUT);
		case -1:
			return (DL_SYSERR);
		}

		flags = 0;
		if ((retval = getmsg(fd, &ctl, &data, &flags)) < 0)
			return (DL_SYSERR);

		if (totdatalenp != NULL)
			*totdatalenp = data.len;

		/*
		 * The supplied DLPI_CHUNKSIZE sized buffers are large enough
		 * to retrieve all valid DLPI responses in one iteration.
		 * If MORECTL or MOREDATA is set, we are not interested in the
		 * remainder of the message. Temporary buffers are used to
		 * drain the remainder of this message.
		 * The special case we have to account for is if
		 * a higher priority messages is enqueued  whilst handling
		 * this condition. We use a change in the flags parameter
		 * returned by getmsg() to indicate the message has changed.
		 */
		while (retval & (MORECTL | MOREDATA)) {
			struct strbuf   cscratch, dscratch;
			int		oflags = flags;

			cscratch.buf = (char *)bufc;
			dscratch.buf = (char *)bufd;
			cscratch.len = dscratch.len = 0;
			cscratch.maxlen = dscratch.maxlen =
			    sizeof (bufc);

			if ((retval = getmsg(fd, &cscratch, &dscratch,
			    &flags)) < 0)
				return (DL_SYSERR);

			if (totdatalenp != NULL)
				*totdatalenp += dscratch.len;
			/*
			 * In the special case of higher priority
			 * message received, the low priority message
			 * received earlier is discarded, if no data
			 * or control message is left.
			 */
			if ((flags != oflags) &&
			    !(retval & (MORECTL | MOREDATA)) &&
			    (cscratch.len != 0)) {
				ctl.len = MIN(cscratch.len, DLPI_CHUNKSIZE);
				if (dlreplyp != NULL)
					(void) memcpy(dlreplyp->dlm_msg, bufc,
					    ctl.len);
				break;
			}
		}

		/*
		 * Check if DL_NOTIFY_IND message received. If there is one,
		 * notify the callback function(s) and continue processing the
		 * requested message.
		 */
		if (dip->dli_notifylistp != NULL &&
		    ctl.len >= (int)(sizeof (t_uscalar_t)) &&
		    *(t_uscalar_t *)(void *)ctl.buf == DL_NOTIFY_IND) {
			/* process properly-formed DL_NOTIFY_IND messages */
			if (ctl.len >= DL_NOTIFY_IND_SIZE) {
				dlnotif = (dl_notify_ind_t *)(void *)ctl.buf;
				(void) i_dlpi_notifyind_process(dip, dlnotif);
			}
			goto update_timer;
		}

		/*
		 * If we were expecting a data message, and we got one, set
		 * *datalenp.  If we aren't waiting on a control message, then
		 * we're done.
		 */
		if (databuf != NULL && data.len >= 0) {
			*datalenp = data.len;
			if (dlreplyp == NULL)
				break;
		}

		/*
		 * If we were expecting a control message, and the message
		 * we received is at least big enough to be a DLPI message,
		 * then verify it's a reply to something we sent.  If it
		 * is a reply to something we sent, also verify its size.
		 */
		if (dlreplyp != NULL && ctl.len >= sizeof (t_uscalar_t)) {
			dlprim = dlreplyp->dlm_msg;
			if (dlprim->dl_primitive == dlreplyprim) {
				if (ctl.len < dlreplyminsz)
					return (DLPI_EBADMSG);
				dlreplyp->dlm_msgsz = ctl.len;
				break;
			} else if (dlprim->dl_primitive == DL_ERROR_ACK) {
				if (ctl.len < DL_ERROR_ACK_SIZE)
					return (DLPI_EBADMSG);

				/* Is it ours? */
				if (dlprim->error_ack.dl_error_primitive ==
				    dlreqprim)
					break;
			}
		}
update_timer:
		if (!infinite) {
			current = NSEC2MSEC(gethrtime());
			msec -= (current - start);

			if (msec <= 0)
				return (DLPI_ETIMEDOUT);
		}
	}

	return (DLPI_SUCCESS);
}