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); }
/*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); }
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; }
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); }
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; }
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; }
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); }
void * inj_zalloc(size_t sz) { return (umem_zalloc(sz, UMEM_NOFAIL)); }
/* * 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); }
char * mk_str(size_t sz) { return (umem_zalloc(sz, UMEM_DEFAULT)); }
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); } }