int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset)
{
	struct parasite_dump_sa_args *args;
	int ret, sig, fd;
	SaEntry se = SA_ENTRY__INIT;

	args = parasite_args(ctl, struct parasite_dump_sa_args);

	ret = parasite_execute(PARASITE_CMD_DUMP_SIGACTS, ctl);
	if (ret < 0)
		return ret;

	fd = fdset_fd(cr_fdset, CR_FD_SIGACT);

	for (sig = 1; sig <= SIGMAX; sig++) {
		int i = sig - 1;

		if (sig == SIGSTOP || sig == SIGKILL)
			continue;

		ASSIGN_TYPED(se.sigaction, encode_pointer(args->sas[i].rt_sa_handler));
		ASSIGN_TYPED(se.flags, args->sas[i].rt_sa_flags);
		ASSIGN_TYPED(se.restorer, encode_pointer(args->sas[i].rt_sa_restorer));
		ASSIGN_TYPED(se.mask, args->sas[i].rt_sa_mask.sig[0]);

		if (pb_write_one(fd, &se, PB_SIGACT) < 0)
			return -1;
	}

	return 0;
}
Beispiel #2
0
static couchstore_error_t mr_push_pointerinfo(node_pointer *ptr,
                                              couchfile_modify_result *dst)
{
    nodelist *pel = encode_pointer(dst->arena, ptr);
    if (!pel) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }
    dst->values_end->next = pel;
    dst->values_end = pel;
    dst->node_len += pel->key.size + pel->data.size + 5;
    dst->count++;
    return maybe_flush(dst);
}
int parasite_dump_thread_seized(struct parasite_ctl *ctl, struct pid *tid,
		CoreEntry *core)
{
	struct parasite_dump_thread *args;
	int ret;

	args = parasite_args(ctl, struct parasite_dump_thread);

	ret = parasite_execute_by_pid(PARASITE_CMD_DUMP_THREAD, ctl, tid->real);

	memcpy(&core->thread_core->blk_sigset, &args->blocked, sizeof(args->blocked));
	CORE_THREAD_ARCH_INFO(core)->clear_tid_addr = encode_pointer(args->tid_addr);
	tid->virt = args->tid;
	core_put_tls(core, args->tls);

	return ret;
}
Beispiel #4
0
//Write a node using enough items from the values list to create a node
//with uncompressed size of at least mr_quota
static couchstore_error_t flush_mr_partial(couchfile_modify_result *res, size_t mr_quota)
{
    char *dst;
    int errcode = COUCHSTORE_SUCCESS;
    int itmcount = 0;
    char *nodebuf = NULL;
    sized_buf writebuf;
    char reducebuf[30];
    size_t reducesize = 0;
    uint64_t subtreesize = 0;
    off_t diskpos;
    size_t disk_size;
    sized_buf final_key = {NULL, 0};

    if (res->values_end == res->values || ! res->modified) {
        //Empty
        return COUCHSTORE_SUCCESS;
    }

    // nodebuf/writebuf is very short-lived and can be large, so use regular malloc heap for it:
    nodebuf = malloc(res->node_len + 1);
    if (!nodebuf) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }

    writebuf.buf = nodebuf;

    dst = nodebuf;
    *(dst++) = (char) res->node_type;

    nodelist *i = res->values->next;
    //We don't care that we've reached mr_quota if we haven't written out
    //at least two items and we're not writing a leaf node.
    while (i != NULL && (mr_quota > 0 || (itmcount < 2 && res->node_type == KP_NODE))) {
        dst = write_kv(dst, i->key, i->data);
        if (i->pointer) {
            subtreesize += i->pointer->subtreesize;
        }
        mr_quota -= i->key.size + i->data.size + 5;
        final_key = i->key;
        i = i->next;
        res->count--;
        itmcount++;
    }

    writebuf.size = dst - nodebuf;

    errcode = db_write_buf_compressed(res->rq->db, &writebuf, &diskpos, &disk_size);
    free(nodebuf);  // here endeth the nodebuf.
    if (errcode != COUCHSTORE_SUCCESS) {
        return errcode;
    }

    if (res->node_type == KV_NODE && res->rq->reduce) {
        res->rq->reduce(reducebuf, &reducesize, res->values->next, itmcount);
    }

    if (res->node_type == KP_NODE && res->rq->rereduce) {
        res->rq->rereduce(reducebuf, &reducesize, res->values->next, itmcount);
    }

    node_pointer *ptr = (node_pointer *) arena_alloc(res->arena, sizeof(node_pointer) + final_key.size + reducesize);
    if (!ptr) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }

    ptr->key.buf = ((char *)ptr) + sizeof(node_pointer);
    ptr->reduce_value.buf = ((char *)ptr) + sizeof(node_pointer) + final_key.size;

    ptr->key.size = final_key.size;
    ptr->reduce_value.size = reducesize;

    memcpy(ptr->key.buf, final_key.buf, final_key.size);
    memcpy(ptr->reduce_value.buf, reducebuf, reducesize);

    ptr->subtreesize = subtreesize + disk_size;
    ptr->pointer = diskpos;

    nodelist *pel = encode_pointer(res->arena, ptr);
    if (!pel) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }

    res->pointers_end->next = pel;
    res->pointers_end = pel;

    res->node_len -= (writebuf.size - 1);

    res->values->next = i;
    if(i == NULL) {
        res->values_end = res->values;
    }

    return COUCHSTORE_SUCCESS;
}
Beispiel #5
0
/* Write a node using enough items from the values list to create a node
 * with uncompressed size of at least mr_quota */
static couchstore_error_t flush_spatial_partial(couchfile_modify_result *res,
                                                size_t mr_quota)
{
    char *dst;
    couchstore_error_t errcode = COUCHSTORE_SUCCESS;
    int itmcount = 0;
    char *nodebuf = NULL;
    sized_buf writebuf;
    char reducebuf[MAX_REDUCTION_SIZE];
    size_t reducesize = 0;
    uint64_t subtreesize = 0;
    cs_off_t diskpos;
    size_t disk_size;
    nodelist *i, *pel;
    node_pointer *ptr;

    if (res->values_end == res->values || ! res->modified) {
        /* Empty */
        return COUCHSTORE_SUCCESS;
    }

    /* nodebuf/writebuf is very short-lived and can be large, so use regular
     * malloc heap for it: */
    nodebuf = (char *) cb_malloc(res->node_len + 1);
    if (nodebuf == NULL) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }

    writebuf.buf = nodebuf;

    dst = nodebuf;
    *(dst++) = (char) res->node_type;

    i = res->values->next;
    /* We don't care that we've reached mr_quota if we haven't written out
     * at least two items and we're not writing a leaf node. */
    while (i != NULL &&
           (mr_quota > 0 || (itmcount < 2 && res->node_type == KP_NODE))) {
        dst = (char *) write_kv(dst, i->key, i->data);
        if (i->pointer) {
            subtreesize += i->pointer->subtreesize;
        }
        mr_quota -= i->key.size + i->data.size + sizeof(raw_kv_length);
        i = i->next;
        res->count--;
        itmcount++;
    }

    writebuf.size = dst - nodebuf;

    errcode = (couchstore_error_t) db_write_buf_compressed(
        res->rq->file, &writebuf, &diskpos, &disk_size);
    cb_free(nodebuf);  /* here endeth the nodebuf. */
    if (errcode != COUCHSTORE_SUCCESS) {
        return errcode;
    }

    /* Store the enclosing MBB in the reducebuf */
    if (res->node_type == KV_NODE && res->rq->reduce) {
        errcode = res->rq->reduce(
            reducebuf, &reducesize, res->values->next, itmcount,
            res->rq->user_reduce_ctx);
        if (errcode != COUCHSTORE_SUCCESS) {
            return errcode;
        }
        cb_assert(reducesize <= sizeof(reducebuf));
    }

    if (res->node_type == KP_NODE && res->rq->rereduce) {
        errcode = res->rq->rereduce(
            reducebuf, &reducesize, res->values->next, itmcount,
            res->rq->user_reduce_ctx);
        if (errcode != COUCHSTORE_SUCCESS) {
            return errcode;
        }
        cb_assert(reducesize <= sizeof(reducebuf));
    }

    /* `reducesize` one time for the key, one time for the actual reduce */
    ptr = (node_pointer *) arena_alloc(
        res->arena, sizeof(node_pointer) + 2 * reducesize);
    if (ptr == NULL) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }

    ptr->key.buf = ((char *)ptr) + sizeof(node_pointer);
    ptr->reduce_value.buf = ((char *)ptr) + sizeof(node_pointer) + reducesize;

    ptr->key.size = reducesize;
    ptr->reduce_value.size = reducesize;

    /* Store the enclosing MBB that was calculate in the reduce function
     * as the key. The reduce also stores it as it is the "Original MBB"
     * used in the RR*-tree algorithm */
    memcpy(ptr->key.buf, reducebuf, reducesize);
    memcpy(ptr->reduce_value.buf, reducebuf, reducesize);

    ptr->subtreesize = subtreesize + disk_size;
    ptr->pointer = diskpos;

    pel = encode_pointer(res->arena, ptr);
    if (pel == NULL) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }

    res->pointers_end->next = pel;
    res->pointers_end = pel;

    res->node_len -= (writebuf.size - 1);

    res->values->next = i;
    if(i == NULL) {
        res->values_end = res->values;
    }

    return COUCHSTORE_SUCCESS;
}
Beispiel #6
0
static void iovec2psi(struct iovec *iov, struct page_server_iov *ps)
{
	ps->vaddr = encode_pointer(iov->iov_base);
	ps->nr_pages = iov->iov_len / PAGE_SIZE;
}