Exemple #1
0
void
lcbio_ctx_put(lcbio_CTX *ctx, const void *buf, unsigned nbuf)
{
    lcbio__EASYRB *erb = ctx->output;

    if (!erb) {
        ctx->output = erb = calloc(1, sizeof(*ctx->output));

        if (!erb) {
            lcbio_ctx_senderr(ctx, LCB_CLIENT_ENOMEM);
            return;
        }

        erb->parent = ctx;

        if (!ringbuffer_initialize(&erb->rb, nbuf)) {
            lcbio_ctx_senderr(ctx, LCB_CLIENT_ENOMEM);
            return;
        }
    }

    if (!ringbuffer_ensure_capacity(&erb->rb, nbuf)) {
        lcbio_ctx_senderr(ctx, LCB_CLIENT_ENOMEM);
        return;
    }

    ringbuffer_write(&erb->rb, buf, nbuf);
}
Exemple #2
0
ringbuffer_t* ringbuffer_allocate( unsigned int size )
{
	ringbuffer_t* buffer = memory_allocate( 0, sizeof( ringbuffer_t ) + size, 0, MEMORY_PERSISTENT );

	ringbuffer_initialize( buffer, size );

	return buffer;
}
Exemple #3
0
static int init_request(struct observe_st *reqinfo)
{
    if (!ringbuffer_initialize(&reqinfo->body, 512)) {
        return 0;
    }
    reqinfo->allocated = 1;
    return 1;
}
Exemple #4
0
static int init_request(struct observe_st *req)
{
    memset(&req->req, 0, sizeof(req->req));
    if (!ringbuffer_initialize(&req->body, 512)) {
        return 0;
    }
    req->allocated = 1;
    return 1;
}
Exemple #5
0
int ringbuffer_ensure_alignment(ringbuffer_t *c)
{
#if defined(__hpux__) || defined(__hpux) || defined(__sparc__) || defined(__sparc)
    intptr_t addr = (intptr_t)c->read_head;

    if (addr % 8 != 0) {
        ringbuffer_t copy;
        if (ringbuffer_initialize(&copy, c->size) == 0 || ringbuffer_memcpy(&copy, c, ringbuffer_get_nbytes(c)) == -1) {
            return -1;
        }
        ringbuffer_destruct(c);
        *c = copy;
    }
#else
    (void)c;
#endif
    return 0;
}
Exemple #6
0
static lcb_error_t reset_buffer(ringbuffer_t **rb, lcb_size_t defsz)
{
    if (*rb) {
        ringbuffer_reset(*rb);
        return LCB_SUCCESS;
    }

    *rb = calloc(1, sizeof(**rb));

    if (*rb == NULL) {
        return LCB_CLIENT_ENOMEM;
    }

    if (!ringbuffer_initialize(*rb, defsz)) {
        return LCB_CLIENT_ENOMEM;
    }

    return LCB_SUCCESS;
}
Exemple #7
0
void ringbuffer_stream_initialize( stream_ringbuffer_t* stream, unsigned int buffer_size, uint64_t total_size )
{
	memset( stream, 0, sizeof( stream_ringbuffer_t ) );

	stream_initialize( (stream_t*)stream, system_byteorder() );

	stream->type = STREAMTYPE_RINGBUFFER;
	stream->sequential = 1;
	stream->path = string_format( "ringbuffer://0x%" PRIfixPTR, stream );
	stream->mode = STREAM_OUT | STREAM_IN | STREAM_BINARY;

	ringbuffer_initialize( RINGBUFFER_FROM_STREAM( stream ), buffer_size );
	semaphore_initialize( &stream->signal_read, 0 );
	semaphore_initialize( &stream->signal_write, 0 );

	stream->total_size = total_size;

	stream->vtable = &_ringbuffer_stream_vtable;
}
LIBCOUCHBASE_API
lcb_error_t lcb_create(lcb_t *instance,
                       const struct lcb_create_st *options)
{
    const char *host = NULL;
    const char *user = NULL;
    const char *passwd = NULL;
    const char *bucket = NULL;

    struct lcb_io_opt_st *io = NULL;
    struct lcb_create_st options_container;
    struct lcb_create_st2 *e_options = &options_container.v.v2;

    lcb_type_t type = LCB_TYPE_BUCKET;
    lcb_t obj;
    lcb_error_t err;
    lcb_settings *settings;

    err = normalize_options(&options_container, options);

    if (err != LCB_SUCCESS) {
        return err;
    }

    host = get_nonempty_string(e_options->host);
    user = get_nonempty_string(e_options->user);
    passwd = get_nonempty_string(e_options->passwd);
    bucket = get_nonempty_string(e_options->bucket);
    io = e_options->io;
    type = e_options->type;

    if (type == LCB_TYPE_CLUSTER && user == NULL && passwd == NULL) {
        return LCB_EINVAL;
    }

    if (host == NULL) {
        host = "localhost";
    }

    if (bucket == NULL) {
        bucket = "default";
    }

    /* Do not allow people use Administrator account for data access */
    if (type == LCB_TYPE_BUCKET && user && strcmp(user, bucket) != 0) {
        return LCB_INVALID_USERNAME;
    }

    if ((obj = calloc(1, sizeof(*obj))) == NULL) {
        return LCB_CLIENT_ENOMEM;
    }

    obj->type = type;
    obj->compat.type = (lcb_compat_t)0xdead;

    if (io == NULL) {
        lcb_io_opt_t ops;
        if ((err = lcb_create_io_ops(&ops, NULL)) != LCB_SUCCESS) {
            /* You can't initialize the library without a io-handler! */
            free(obj);
            return err;
        }
        io = ops;
        io->v.v0.need_cleanup = 1;
    }

    settings = &obj->settings;
    settings->randomize_bootstrap_nodes = 1;
    settings->bummer = 0;
    settings->io = io;
    obj->syncmode = LCB_ASYNCHRONOUS;
    settings->ipv6 = LCB_IPV6_DISABLED;

    settings->operation_timeout = LCB_DEFAULT_TIMEOUT;
    settings->config_timeout = LCB_DEFAULT_CONFIGURATION_TIMEOUT;
    settings->config_node_timeout = LCB_DEFAULT_NODECONFIG_TIMEOUT;
    settings->views_timeout = LCB_DEFAULT_VIEW_TIMEOUT;
    settings->rbufsize = LCB_DEFAULT_RBUFSIZE;
    settings->wbufsize = LCB_DEFAULT_WBUFSIZE;
    settings->durability_timeout = LCB_DEFAULT_DURABILITY_TIMEOUT;
    settings->durability_interval = LCB_DEFAULT_DURABILITY_INTERVAL;
    settings->http_timeout = LCB_DEFAULT_HTTP_TIMEOUT;
    settings->weird_things_threshold = LCB_DEFAULT_CONFIG_ERRORS_THRESHOLD;
    settings->weird_things_delay = LCB_DEFAULT_CONFIG_ERRORS_DELAY;
    settings->max_redir = LCB_DEFAULT_CONFIG_MAXIMUM_REDIRECTS;
    settings->grace_next_cycle = LCB_DEFAULT_CLCONFIG_GRACE_CYCLE;
    settings->grace_next_provider = LCB_DEFAULT_CLCONFIG_GRACE_NEXT;
    settings->bc_http_stream_time = LCB_DEFAULT_BC_HTTP_DISCONNTMO;
    settings->bucket = strdup(bucket);
    settings->logger = lcb_init_console_logger();
    settings->iid = lcb_instance_index++;


    if (user) {
        settings->username = strdup(user);
    } else {
        settings->username = strdup(settings->bucket);
    }

    if (passwd) {
        settings->password = strdup(passwd);
    }

    lcb_initialize_packet_handlers(obj);

    obj->memd_sockpool = connmgr_create(settings, io);
    obj->memd_sockpool->max_idle = 1;
    obj->memd_sockpool->idle_timeout = 10000000;

    obj->confmon = lcb_confmon_create(settings);
    obj->usernodes = hostlist_create();

    /** We might want to sanitize this a bit more later on.. */
    if (strstr(host, "://") != NULL && strstr(host, "http://") == NULL) {
        lcb_destroy(obj);
        return LCB_INVALID_HOST_FORMAT;
    }


    err = hostlist_add_string(obj->usernodes, host, -1, LCB_CONFIG_HTTP_PORT);
    if (err != LCB_SUCCESS) {
        lcb_destroy(obj);
        return err;
    }

    err = lcb_init_providers(obj, e_options);
    if (err != LCB_SUCCESS) {
        lcb_destroy(obj);
        return err;
    }

    lcb_initialize_packet_handlers(obj);

    obj->timers = hashset_create();
    obj->http_requests = hashset_create();
    obj->durability_polls = hashset_create();
    /* No error has occurred yet. */
    obj->last_error = LCB_SUCCESS;
    if ((obj->cmdht = lcb_hashtable_szt_new(32)) == NULL) {
        lcb_destroy(obj);
        return LCB_CLIENT_ENOMEM;
    }


    if (!ringbuffer_initialize(&obj->purged_buf, 4096)) {
        lcb_destroy(obj);
        return LCB_CLIENT_ENOMEM;
    }
    if (!ringbuffer_initialize(&obj->purged_cookies, 4096)) {
        lcb_destroy(obj);
        return LCB_CLIENT_ENOMEM;
    }

    *instance = obj;
    return LCB_SUCCESS;
}
Exemple #9
0
static void purge_single_server(lcb_server_t *server, lcb_error_t error,
                                hrtime_t min_nonstale,
                                hrtime_t *tmo_next)
{
    protocol_binary_request_header req;
    struct lcb_command_data_st ct;
    lcb_size_t nr;
    char *packet;
    lcb_size_t packetsize;
    char *keyptr;
    ringbuffer_t rest;
    ringbuffer_t *stream = &server->cmd_log;
    ringbuffer_t *cookies;
    ringbuffer_t *mirror = NULL; /* mirror buffer should be purged with main stream */
    lcb_connection_t conn = &server->connection;
    lcb_size_t send_size = 0;
    lcb_size_t stream_size = ringbuffer_get_nbytes(stream);
    hrtime_t now = gethrtime();

    if (server->connection_ready) {
        cookies = &server->output_cookies;
    } else {
        cookies = &server->pending_cookies;
        mirror = &server->pending;
    }

    if (conn->output) {
        /* This will usually be false for v1 */
        send_size = ringbuffer_get_nbytes(conn->output);
    }

    lcb_assert(ringbuffer_initialize(&rest, 1024));


    do {
        int allocated = 0;
        lcb_uint32_t headersize;
        lcb_uint16_t nkey;

        nr = ringbuffer_peek(cookies, &ct, sizeof(ct));
        if (nr != sizeof(ct)) {
            break;
        }
        nr = ringbuffer_peek(stream, req.bytes, sizeof(req));
        if (nr != sizeof(req)) {
            break;
        }
        packetsize = (lcb_uint32_t)sizeof(req) + ntohl(req.request.bodylen);
        if (stream->nbytes < packetsize) {
            break;
        }
        if (min_nonstale && ct.start >= min_nonstale) {
            lcb_log(LOGARGS(server, INFO),
                    "Still have %d ms remaining for command",
                    (ct.start - min_nonstale) / 1000000);

            if (tmo_next) {
                *tmo_next = (ct.start - min_nonstale) + 1;
            }
            break;
        }

        lcb_log(LOGARGS(server, INFO),
                "Command with cookie=%p timed out from server %s:%s",
                ct.cookie,
                server->curhost.host,
                server->curhost.port);

        ringbuffer_consumed(cookies, sizeof(ct));

        lcb_assert(nr == sizeof(req));
        packet = stream->read_head;

        if (server->instance->histogram) {
            lcb_record_metrics(server->instance, now - ct.start,
                               req.request.opcode);
        }

        if (server->connection_ready &&
                stream_size > send_size && (stream_size - packetsize) < send_size) {
            /* Copy the rest of the current packet into the
               temporary stream */

            /* I do believe I have some IOV functions to do that? */
            lcb_size_t nbytes = packetsize - (stream_size - send_size);
            lcb_assert(ringbuffer_memcpy(&rest,
                                         conn->output,
                                         nbytes) == 0);
            ringbuffer_consumed(conn->output, nbytes);
            send_size -= nbytes;
        }
        stream_size -= packetsize;
        headersize = (lcb_uint32_t)sizeof(req) + req.request.extlen + htons(req.request.keylen);
        if (!ringbuffer_is_continous(stream, RINGBUFFER_READ, headersize)) {
            packet = malloc(headersize);
            if (packet == NULL) {
                lcb_error_handler(server->instance, LCB_CLIENT_ENOMEM, NULL);
                abort();
            }

            nr = ringbuffer_peek(stream, packet, headersize);
            if (nr != headersize) {
                lcb_error_handler(server->instance, LCB_EINTERNAL, NULL);
                free(packet);
                abort();
            }
            allocated = 1;
        }

        keyptr = packet + sizeof(req) + req.request.extlen;
        nkey = ntohs(req.request.keylen);

        failout_single_request(server, &req, &ct, error, keyptr, nkey, packet);

        if (allocated) {
            free(packet);
        }
        ringbuffer_consumed(stream, packetsize);
        if (mirror) {
            ringbuffer_consumed(mirror, packetsize);
        }
    } while (1); /* CONSTCOND */

    if (server->connection_ready && conn->output) {
        /* Preserve the rest of the stream */
        lcb_size_t nbytes = ringbuffer_get_nbytes(stream);
        send_size = ringbuffer_get_nbytes(conn->output);

        if (send_size >= nbytes) {
            ringbuffer_consumed(conn->output, send_size - nbytes);
            lcb_assert(ringbuffer_memcpy(&rest, conn->output, nbytes) == 0);
        }
        ringbuffer_reset(conn->output);
        ringbuffer_append(&rest, conn->output);
    }

    ringbuffer_destruct(&rest);
    lcb_maybe_breakout(server->instance);
}
Exemple #10
0
static libcouchbase_error_t create_memcached(const struct libcouchbase_memcached_st *user,
                                             VBUCKET_CONFIG_HANDLE vbconfig)
{
    ringbuffer_t buffer;
    char *copy = strdup(user->serverlist);
    char head[1024];
    int first;
    char *ptr = copy;
    int fail;
    libcouchbase_ssize_t offset = 0;

    if (copy == NULL) {
        return LIBCOUCHBASE_CLIENT_ENOMEM;
    }

    if (ringbuffer_initialize(&buffer, 1024) == -1) {
        free(copy);
        return LIBCOUCHBASE_CLIENT_ENOMEM;
    }

    head[0] = '\0';
    offset += snprintf(head + offset, sizeof(head) - offset, "%s", "{");
    offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                       "\"bucketType\":\"memcached\",");
    offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                       "\"nodeLocator\":\"ketama\",");
    if (user->username != NULL) {
        offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                           "\"authType\":\"sasl\",");
        offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                           "\"name\":\"");
        offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                           user->username);
        offset += snprintf(head + offset, sizeof(head) - offset, "%s", "\",");
        if (user->password != NULL) {
            offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                               "\"saslPassword\":\"");
            offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                               user->password);
            offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                               "\",");
        }
    }

    offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                       "\"nodes\": [");
    ringbuffer_write(&buffer, head, strlen(head));

    /* Let's add the hosts... */
    first = 1;
    do {
        char *tok;
        char *next = strchr(ptr, ';');
        const char *port = "11211";
        libcouchbase_ssize_t length;

        if (next != NULL) {
            *next = '\0';
        }

        tok = strchr(ptr, ':');
        if (tok != NULL) {
            *tok = '\0';
            port = tok + 1;
            if ((tok = strchr(ptr, ':')) != NULL) {
                *tok = '\0'; /* Remove weight for now */
            }
        }

        length = snprintf(head, sizeof(head),
                          "%c{\"hostname\":\"%s\",\"ports\":{\"direct\":%s}}",
                          first ? ' ' : ',', ptr, port);
        first = 0;

        if (ringbuffer_ensure_capacity(&buffer, length) == -1) {
            free(copy);
            return LIBCOUCHBASE_CLIENT_ENOMEM;
        }

        ringbuffer_write(&buffer, head, length);

        if (next != NULL) {
            ptr = next + 1;
        } else {
            ptr = NULL;
        }
    } while (ptr != NULL);

    if (ringbuffer_ensure_capacity(&buffer, 3) == -1) {
        free(copy);
        return LIBCOUCHBASE_CLIENT_ENOMEM;
    }

    ringbuffer_write(&buffer, "]}", 3); /* Include '\0' */

    /* Now let's parse the config! */
    fail = vbucket_config_parse(vbconfig, LIBVBUCKET_SOURCE_MEMORY,
                                (char *)ringbuffer_get_read_head(&buffer));
    free(copy);
    ringbuffer_destruct(&buffer);

    if (fail) {
        /* Hmm... internal error! */
        return LIBCOUCHBASE_EINTERNAL;
    }

    return LIBCOUCHBASE_SUCCESS;
}