예제 #1
0
static struct storage *
smu_alloc(const struct stevedore *st, size_t size)
{
	struct smu *smu;

	Lck_Lock(&smu_mtx);
	VSC_C_main->sma_nreq++;
	if (VSC_C_main->sma_nbytes + size > smu_max)
		size = 0;
	else {
		VSC_C_main->sma_nobj++;
		VSC_C_main->sma_nbytes += size;
		VSC_C_main->sma_balloc += size;
	}
	Lck_Unlock(&smu_mtx);

	if (size == 0)
		return (NULL);

	smu = umem_zalloc(sizeof *smu, UMEM_DEFAULT);
	if (smu == NULL)
		return (NULL);
	smu->sz = size;
	smu->s.priv = smu;
	smu->s.ptr = umem_alloc(size, UMEM_DEFAULT);
	XXXAN(smu->s.ptr);
	smu->s.len = 0;
	smu->s.space = size;
	smu->s.fd = -1;
	smu->s.stevedore = st;
	smu->s.magic = STORAGE_MAGIC;
	return (&smu->s);
}
예제 #2
0
파일: taskq.c 프로젝트: jeffpc/suntaskq
/*ARGSUSED*/
taskq_t *
taskq_create(const char *name, int nthreads,
	int minalloc, int maxalloc, unsigned int flags)
{
	taskq_t *tq;
	int t;

	tq = umem_zalloc(sizeof(taskq_t), 0);
	if (!tq)
		return NULL;

	if (flags & TASKQ_THREADS_CPU_PCT) {
		int pct;
		assert(nthreads >= 0);
		assert(nthreads <= taskq_cpupct_max_percent);
		pct = MIN(nthreads, taskq_cpupct_max_percent);
		pct = MAX(pct, 0);

		nthreads = (sysconf(_SC_NPROCESSORS_ONLN) * pct) / 100;
		nthreads = MAX(nthreads, 1);	/* need at least 1 thread */
	} else {
		assert(nthreads >= 1);
	}

	rwinit(&tq->tq_threadlock);
	mxinit(&tq->tq_lock);
	condinit(&tq->tq_dispatch_cv);
	condinit(&tq->tq_wait_cv);
	condinit(&tq->tq_maxalloc_cv);
	(void) strncpy(tq->tq_name, name, TASKQ_NAMELEN + 1);
	tq->tq_flags = flags | TASKQ_ACTIVE;
	tq->tq_active = nthreads;
	tq->tq_nthreads = nthreads;
	tq->tq_minalloc = minalloc;
	tq->tq_maxalloc = maxalloc;
	tq->tq_task.tqent_next = &tq->tq_task;
	tq->tq_task.tqent_prev = &tq->tq_task;
	tq->tq_threadlist =
	    umem_alloc(nthreads * sizeof (pthread_t), UMEM_NOFAIL);

	if (flags & TASKQ_PREPOPULATE) {
		mxlock(&tq->tq_lock);
		while (minalloc-- > 0)
			task_free(tq, task_alloc(tq, UMEM_NOFAIL));
		mxunlock(&tq->tq_lock);
	}

	for (t = 0; t < nthreads; t++)
		pthread_create(&tq->tq_threadlist[t], NULL, taskq_thread, tq);

	return (tq);
}
예제 #3
0
파일: kernel.c 프로젝트: ColdCanuck/zfs
kthread_t *
zk_thread_create(caddr_t stk, size_t stksize, thread_func_t func, void *arg,
	      size_t len, proc_t *pp, int state, pri_t pri, int detachstate)
{
	kthread_t *kt;
	pthread_attr_t attr;
	size_t stack;

	ASSERT3S(state & ~TS_RUN, ==, 0);

	kt = umem_zalloc(sizeof(kthread_t), UMEM_NOFAIL);
	kt->t_func = func;
	kt->t_arg = arg;

	/*
	 * The Solaris kernel stack size is 24k for x86/x86_64.
	 * The Linux kernel stack size is 8k for x86/x86_64.
	 *
	 * We reduce the default stack size in userspace, to ensure
	 * we observe stack overruns in user space as well as in
	 * kernel space. In practice we can't set the userspace stack
	 * size to 8k because differences in stack usage between kernel
	 * space and userspace could lead to spurious stack overflows
	 * (especially when debugging is enabled). Nevertheless, we try
	 * to set it to the lowest value that works (currently 8k*4).
	 * PTHREAD_STACK_MIN is the minimum stack required for a NULL
	 * procedure in user space and is added in to the stack
	 * requirements.
	 *
	 * Some buggy NPTL threading implementations include the
	 * guard area within the stack size allocations.  In
	 * this case we allocate an extra page to account for the
	 * guard area since we only have two pages of usable stack
	 * on Linux.
	 */

	stack = PTHREAD_STACK_MIN + MAX(stksize, STACK_SIZE) * 4 +
			EXTRA_GUARD_BYTES;

	VERIFY3S(pthread_attr_init(&attr), ==, 0);
	VERIFY3S(pthread_attr_setstacksize(&attr, stack), ==, 0);
	VERIFY3S(pthread_attr_setguardsize(&attr, PAGESIZE), ==, 0);
	VERIFY3S(pthread_attr_setdetachstate(&attr, detachstate), ==, 0);

	VERIFY3S(pthread_create(&kt->t_tid, &attr, &zk_thread_helper, kt),
	    ==, 0);

	VERIFY3S(pthread_attr_destroy(&attr), ==, 0);

	return kt;
}
예제 #4
0
파일: kernel.c 프로젝트: ColinIanKing/zfs
kthread_t *
zk_thread_create(caddr_t stk, size_t stksize, thread_func_t func, void *arg,
    uint64_t len, proc_t *pp, int state, pri_t pri, int detachstate)
{
	kthread_t *kt;
	pthread_attr_t attr;
	char *stkstr;

	ASSERT0(state & ~TS_RUN);
	ASSERT0(len);

	kt = umem_zalloc(sizeof (kthread_t), UMEM_NOFAIL);
	kt->t_func = func;
	kt->t_arg = arg;
	kt->t_pri = pri;

	VERIFY0(pthread_attr_init(&attr));
	VERIFY0(pthread_attr_setdetachstate(&attr, detachstate));

	/*
	 * We allow the default stack size in user space to be specified by
	 * setting the ZFS_STACK_SIZE environment variable.  This allows us
	 * the convenience of observing and debugging stack overruns in
	 * user space.  Explicitly specified stack sizes will be honored.
	 * The usage of ZFS_STACK_SIZE is discussed further in the
	 * ENVIRONMENT VARIABLES sections of the ztest(1) man page.
	 */
	if (stksize == 0) {
		stkstr = getenv("ZFS_STACK_SIZE");

		if (stkstr == NULL)
			stksize = TS_STACK_MAX;
		else
			stksize = MAX(atoi(stkstr), TS_STACK_MIN);
	}

	VERIFY3S(stksize, >, 0);
	stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE);
	/*
	 * If this ever fails, it may be because the stack size is not a
	 * multiple of system page size.
	 */
	VERIFY0(pthread_attr_setstacksize(&attr, stksize));
	VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE));

	VERIFY0(pthread_create(&kt->t_tid, &attr, &zk_thread_helper, kt));
	VERIFY0(pthread_attr_destroy(&attr));

	return (kt);
}
예제 #5
0
파일: kernel.c 프로젝트: nkhare/zfs
kthread_t *
zk_thread_create(caddr_t stk, size_t stksize, thread_func_t func, void *arg,
	      size_t len, proc_t *pp, int state, pri_t pri)
{
	kthread_t *kt;
	pthread_attr_t attr;
	size_t stack;

	ASSERT3S(state & ~TS_RUN, ==, 0);

	kt = umem_zalloc(sizeof(kthread_t), UMEM_NOFAIL);
	kt->t_func = func;
	kt->t_arg = arg;

	/*
	 * The Solaris kernel stack size is 24k for x86/x86_64.
	 * The Linux kernel stack size is 8k for x86/x86_64.
	 *
	 * We reduce the default stack size in userspace, to ensure
	 * we observe stack overruns in user space as well as in
	 * kernel space.  PTHREAD_STACK_MIN is the minimum stack
	 * required for a NULL procedure in user space and is added
	 * in to the stack requirements.
	 *
	 * Some buggy NPTL threading implementations include the
	 * guard area within the stack size allocations.  In
	 * this case we allocate an extra page to account for the
	 * guard area since we only have two pages of usable stack
	 * on Linux.
	 */

	stack = PTHREAD_STACK_MIN + MAX(stksize, STACK_SIZE) +
			EXTRA_GUARD_BYTES;

	VERIFY3S(pthread_attr_init(&attr), ==, 0);
	VERIFY3S(pthread_attr_setstacksize(&attr, stack), ==, 0);
	VERIFY3S(pthread_attr_setguardsize(&attr, PAGESIZE), ==, 0);

	VERIFY3S(pthread_create(&kt->t_tid, &attr, &zk_thread_helper, kt),
	    ==, 0);

	VERIFY3S(pthread_attr_destroy(&attr), ==, 0);

	return kt;
}
예제 #6
0
파일: kernel.c 프로젝트: cbreak-black/zfs
void
thread_init(void)
{
	kthread_t *kt;

	VERIFY3S(pthread_key_create(&kthread_key, NULL), ==, 0);

	/* Create entry for primary kthread */
	kt = umem_zalloc(sizeof (kthread_t), UMEM_NOFAIL);
	kt->t_tid = pthread_self();
	kt->t_func = NULL;

	VERIFY3S(pthread_setspecific(kthread_key, kt), ==, 0);

	/* Only the main thread should be running at the moment */
	ASSERT3S(kthread_nr, ==, 0);
	kthread_nr = 1;
}
예제 #7
0
파일: util.c 프로젝트: lidongyang/zfs
static int
pool_active(void *unused, const char *name, uint64_t guid,
    boolean_t *isactive)
{
	zfs_cmd_t *zcp;
	nvlist_t *innvl;
	char *packed = NULL;
	size_t size = 0;
	int fd, ret;

	/*
	 * Use ZFS_IOC_POOL_SYNC to confirm if a pool is active
	 */

	fd = open("/dev/zfs", O_RDWR);
	if (fd < 0)
		return (-1);

	zcp = umem_zalloc(sizeof (zfs_cmd_t), UMEM_NOFAIL);

	innvl = fnvlist_alloc();
	fnvlist_add_boolean_value(innvl, "force", B_FALSE);

	(void) strlcpy(zcp->zc_name, name, sizeof (zcp->zc_name));
	packed = fnvlist_pack(innvl, &size);
	zcp->zc_nvlist_src = (uint64_t)(uintptr_t)packed;
	zcp->zc_nvlist_src_size = size;

	ret = ioctl(fd, ZFS_IOC_POOL_SYNC, zcp);

	fnvlist_pack_free(packed, size);
	free((void *)(uintptr_t)zcp->zc_nvlist_dst);
	nvlist_free(innvl);
	umem_free(zcp, sizeof (zfs_cmd_t));

	(void) close(fd);

	*isactive = (ret == 0);

	return (0);
}
예제 #8
0
파일: inj_umem.c 프로젝트: andreiw/polaris
void *
inj_zalloc(size_t sz)
{
	return (umem_zalloc(sz, UMEM_NOFAIL));
}
예제 #9
0
파일: piclsbl.c 프로젝트: andreiw/polaris
/*
 * Ontario SBL event handler, subscribed to:
 * 	PICLEVENT_SYSEVENT_DEVICE_ADDED
 * 	PICLEVENT_SYSEVENT_DEVICE_REMOVED
 */
static void
piclsbl_handler(const char *ename, const void *earg, size_t size,
		void *cookie)
{
	char		*devfs_path;
	char		hdd_location[PICL_PROPNAMELEN_MAX];
	nvlist_t	*nvlp = NULL;
	pcp_msg_t	send_msg;
	pcp_msg_t	recv_msg;
	pcp_sbl_req_t	*req_ptr = NULL;
	pcp_sbl_resp_t	*resp_ptr = NULL;
	int		status = -1;
	int		target;
	disk_lookup_t	lookup;
	int		channel_fd;

	/*
	 * setup the request data to attach to the libpcp msg
	 */
	if ((req_ptr = (pcp_sbl_req_t *)umem_zalloc(sizeof (pcp_sbl_req_t),
			UMEM_DEFAULT)) == NULL)
		goto sbl_return;

	/*
	 * This plugin serves to enable or disable the blue RAS
	 * 'ok-to-remove' LED that is on each of the 4 disks on the
	 * Ontario.  We catch the event via the picl handler, and
	 * if the event is DEVICE_ADDED for one of our onboard disks,
	 * then we'll be turning off the LED. Otherwise, if the event
	 * is DEVICE_REMOVED, then we turn it on.
	 */
	if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_ADDED) == 0)
		req_ptr->sbl_action = PCP_SBL_DISABLE;
	else if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_REMOVED) == 0)
		req_ptr->sbl_action = PCP_SBL_ENABLE;
	else
		goto sbl_return;

	/*
	 * retrieve the device's physical path from the event payload
	 */
	if (nvlist_unpack((char *)earg, size, &nvlp, NULL))
		goto sbl_return;
	if (nvlist_lookup_string(nvlp, "devfs-path", &devfs_path))
		goto sbl_return;

	/*
	 * look for this disk in the picl tree, and if it's
	 * location indicates that it's one of our internal
	 * disks, then set sbl_id to incdicate which one.
	 * otherwise, return as it is not one of our disks.
	 */
	lookup.path = strdup(devfs_path);
	lookup.disk = NULL;
	lookup.result = DISK_NOT_FOUND;

	/* first, find the disk */
	status = ptree_walk_tree_by_class(root_node, "disk", (void *)&lookup,
						cb_find_disk);
	if (status != PICL_SUCCESS)
		goto sbl_return;

	if (lookup.result == DISK_FOUND) {
		/* now, lookup it's location in the node */
		status = ptree_get_propval_by_name(lookup.disk, "Location",
				(void *)&hdd_location, PICL_PROPNAMELEN_MAX);
		if (status != PICL_SUCCESS) {
			syslog(LOG_ERR, "piclsbl: failed hdd discovery");
			goto sbl_return;
		}
	}

	if (strcmp(hdd_location, HDD0) == 0) {
		req_ptr->sbl_id = PCP_SBL_HDD0;
		target = 0;
	} else if (strcmp(hdd_location, HDD1) == 0) {
		req_ptr->sbl_id = PCP_SBL_HDD1;
		target = 1;
	} else if (strcmp(hdd_location, HDD2) == 0) {
		req_ptr->sbl_id = PCP_SBL_HDD2;
		target = 2;
	} else if (strcmp(hdd_location, HDD3) == 0) {
		req_ptr->sbl_id = PCP_SBL_HDD3;
		target = 3;
	} else {
		/* this is not one of the onboard disks */
		goto sbl_return;
	}

	/*
	 * check the onboard RAID configuration for this disk. if it is
	 * a member of a RAID and is not the RAID itself, ignore the event
	 */
	if (check_raid(target))
		goto sbl_return;

	/*
	 * we have the information we need, init the platform channel.
	 * the platform channel driver will only allow one connection
	 * at a time on this socket. on the offchance that more than
	 * one event comes in, we'll retry to initialize this connection
	 * up to 3 times
	 */
	if ((channel_fd = (*pcp_init_ptr)(LED_CHANNEL)) < 0) {
		/* failed to init; wait and retry up to 3 times */
		int s = PCPINIT_TIMEOUT;
		int retries = 0;
		while (++retries) {
			(void) sleep(s);
			if ((channel_fd = (*pcp_init_ptr)(LED_CHANNEL)) >= 0)
				break;
			else if (retries == 3) {
				syslog(LOG_ERR, "piclsbl: ",
					"SC channel initialization failed");
				goto sbl_return;
			}
			/* continue */
		}
	}

	/*
	 * populate the message for libpcp
	 */
	send_msg.msg_type = PCP_SBL_CONTROL;
	send_msg.sub_type = NULL;
	send_msg.msg_len = sizeof (pcp_sbl_req_t);
	send_msg.msg_data = (uint8_t *)req_ptr;

	/*
	 * send the request, receive the response
	 */
	if ((*pcp_send_recv_ptr)(channel_fd, &send_msg, &recv_msg,
		PCPCOMM_TIMEOUT) < 0) {
		/* we either timed out or erred; either way try again */
		int s = PCPCOMM_TIMEOUT;
		(void) sleep(s);
		if ((*pcp_send_recv_ptr)(channel_fd, &send_msg, &recv_msg,
				PCPCOMM_TIMEOUT) < 0) {
			syslog(LOG_ERR, "piclsbl: communication failure");
			goto sbl_return;
		}
	}

	/*
	 * validate that this data was meant for us
	 */
	if (recv_msg.msg_type != PCP_SBL_CONTROL_R) {
		syslog(LOG_ERR, "piclsbl: unbound packet received");
		goto sbl_return;
	}

	/*
	 * verify that the LED action has taken place
	 */
	resp_ptr = (pcp_sbl_resp_t *)recv_msg.msg_data;
	if (resp_ptr->status == PCP_SBL_ERROR) {
		syslog(LOG_ERR, "piclsbl: OK2RM LED action error");
		goto sbl_return;
	}

	/*
	 * ensure the LED action taken is the one requested
	 */
	if ((req_ptr->sbl_action == PCP_SBL_DISABLE) &&
		(resp_ptr->sbl_state != SBL_STATE_OFF))
		syslog(LOG_ERR, "piclsbl: OK2RM LED not OFF after disk "
				"configuration");
	else if ((req_ptr->sbl_action == PCP_SBL_ENABLE) &&
			(resp_ptr->sbl_state != SBL_STATE_ON))
		syslog(LOG_ERR, "piclsbl: OK2RM LED not ON after disk "
				"unconfiguration");
	else if (resp_ptr->sbl_state == SBL_STATE_UNKNOWN)
		syslog(LOG_ERR, "piclsbl: OK2RM LED set to unknown state");

sbl_return:

	(*pcp_close_ptr)(channel_fd);
	if (req_ptr != NULL)
		umem_free(req_ptr, sizeof (pcp_sbl_req_t));
	if (resp_ptr != NULL)
		free(resp_ptr);
	if (nvlp != NULL)
		nvlist_free(nvlp);
}
예제 #10
0
char *
mk_str(size_t sz)
{
	return (umem_zalloc(sz, UMEM_DEFAULT));
}
예제 #11
0
파일: util.c 프로젝트: lidongyang/zfs
static void
show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent)
{
	vdev_stat_t *vs;
	vdev_stat_t *v0 = { 0 };
	uint64_t sec;
	uint64_t is_log = 0;
	nvlist_t **child;
	uint_t c, children;
	char used[6], avail[6];
	char rops[6], wops[6], rbytes[6], wbytes[6], rerr[6], werr[6], cerr[6];

	v0 = umem_zalloc(sizeof (*v0), UMEM_NOFAIL);

	if (indent == 0 && desc != NULL) {
		(void) printf("                           "
		    " capacity   operations   bandwidth  ---- errors ----\n");
		(void) printf("description                "
		    "used avail  read write  read write  read write cksum\n");
	}

	if (desc != NULL) {
		char *suffix = "", *bias = NULL;
		char bias_suffix[32];

		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log);
		(void) nvlist_lookup_string(nv, ZPOOL_CONFIG_ALLOCATION_BIAS,
		    &bias);
		if (nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
		    (uint64_t **)&vs, &c) != 0)
			vs = v0;

		if (bias != NULL) {
			(void) snprintf(bias_suffix, sizeof (bias_suffix),
			    " (%s)", bias);
			suffix = bias_suffix;
		} else if (is_log) {
			suffix = " (log)";
		}

		sec = MAX(1, vs->vs_timestamp / NANOSEC);

		nicenum(vs->vs_alloc, used, sizeof (used));
		nicenum(vs->vs_space - vs->vs_alloc, avail, sizeof (avail));
		nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops, sizeof (rops));
		nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops, sizeof (wops));
		nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes,
		    sizeof (rbytes));
		nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes,
		    sizeof (wbytes));
		nicenum(vs->vs_read_errors, rerr, sizeof (rerr));
		nicenum(vs->vs_write_errors, werr, sizeof (werr));
		nicenum(vs->vs_checksum_errors, cerr, sizeof (cerr));

		(void) printf("%*s%s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n",
		    indent, "",
		    desc,
		    (int)(indent+strlen(desc)-25-(vs->vs_space ? 0 : 12)),
		    suffix,
		    vs->vs_space ? 6 : 0, vs->vs_space ? used : "",
		    vs->vs_space ? 6 : 0, vs->vs_space ? avail : "",
		    rops, wops, rbytes, wbytes, rerr, werr, cerr);
	}
	free(v0);

	if (nvlist_lookup_nvlist_array(nv, ctype, &child, &children) != 0)
		return;

	for (c = 0; c < children; c++) {
		nvlist_t *cnv = child[c];
		char *cname = NULL, *tname;
		uint64_t np;
		int len;
		if (nvlist_lookup_string(cnv, ZPOOL_CONFIG_PATH, &cname) &&
		    nvlist_lookup_string(cnv, ZPOOL_CONFIG_TYPE, &cname))
			cname = "<unknown>";
		len = strlen(cname) + 2;
		tname = umem_zalloc(len, UMEM_NOFAIL);
		(void) strlcpy(tname, cname, len);
		if (nvlist_lookup_uint64(cnv, ZPOOL_CONFIG_NPARITY, &np) == 0)
			tname[strlen(tname)] = '0' + np;
		show_vdev_stats(tname, ctype, cnv, indent + 2);
		free(tname);
	}
}