X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Fstats.cc;h=ab00d4b8051363f891a6853f743d10db61c15619;hb=e2688497603c56929e6dd2b4e6139dd85edcb0e0;hp=78fed03d7d0b8e389d344b0ebd70454a391810ea;hpb=5c104c25a61292fd9552cb9587ea595916d554f7;p=m6w6%2Flibmemcached diff --git a/libmemcached/stats.cc b/libmemcached/stats.cc index 78fed03d..ab00d4b8 100644 --- a/libmemcached/stats.cc +++ b/libmemcached/stats.cc @@ -1,7 +1,40 @@ -/* -*/ +/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: + * + * Libmemcached library + * + * Copyright (C) 2011 Data Differential, http://datadifferential.com/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * The names of its contributors may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ -#include "common.h" +#include static const char *memcached_stat_keys[] = { "pid", @@ -34,18 +67,21 @@ struct local_context memcached_stat_fn func; void *context; const char *args; + const size_t args_length; local_context(memcached_stat_fn func_arg, - void *context_arg, - const char *args_arg) : + void *context_arg, + const char *args_arg, + const size_t args_length_arg) : func(func_arg), context(context_arg), - args(args_arg) + args(args_arg), + args_length(args_length_arg) { } }; -static memcached_return_t set_data(memcached_stat_st *memc_stat, char *key, char *value) +static memcached_return_t set_data(memcached_stat_st *memc_stat, const char *key, const char *value) { if (strlen(key) < 1) @@ -53,7 +89,7 @@ static memcached_return_t set_data(memcached_stat_st *memc_stat, char *key, char WATCHPOINT_STRING(key); return MEMCACHED_UNKNOWN_STAT_KEY; } - else if (not strcmp("pid", key)) + else if (strcmp("pid", key) == 0) { int64_t temp= strtoll(value, (char **)NULL, 10); @@ -91,7 +127,7 @@ static memcached_return_t set_data(memcached_stat_st *memc_stat, char *key, char else if (not strcmp("rusage_user", key)) { char *walk_ptr; - for (walk_ptr= value; (!ispunct(*walk_ptr)); walk_ptr++) {}; + for (walk_ptr= (char*)value; (!ispunct(*walk_ptr)); walk_ptr++) {}; *walk_ptr= 0; walk_ptr++; memc_stat->rusage_user_seconds= strtoul(value, (char **)NULL, 10); @@ -100,7 +136,7 @@ static memcached_return_t set_data(memcached_stat_st *memc_stat, char *key, char else if (not strcmp("rusage_system", key)) { char *walk_ptr; - for (walk_ptr= value; (!ispunct(*walk_ptr)); walk_ptr++) {}; + for (walk_ptr= (char*)value; (!ispunct(*walk_ptr)); walk_ptr++) {}; *walk_ptr= 0; walk_ptr++; memc_stat->rusage_system_seconds= strtoul(value, (char **)NULL, 10); @@ -200,7 +236,7 @@ char *memcached_stat_get_value(const memcached_st *ptr, memcached_stat_st *memc_ *error= MEMCACHED_SUCCESS; - if (not memcmp("pid", key, sizeof("pid") -1)) + if (memcmp("pid", key, sizeof("pid") -1) == 0) { length= snprintf(buffer, SMALL_STRING_LEN,"%lld", (signed long long)memc_stat->pid); } @@ -309,32 +345,27 @@ char *memcached_stat_get_value(const memcached_st *ptr, memcached_stat_st *memc_ static memcached_return_t binary_stats_fetch(memcached_stat_st *memc_stat, const char *args, - memcached_server_write_instance_st instance, + const size_t args_length, + org::libmemcached::Instance* instance, struct local_context *check) { char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; protocol_binary_request_stats request= {}; // = {.bytes= {0}}; - request.message.header.request.magic= PROTOCOL_BINARY_REQ; + + initialize_binary_request(instance, request.message.header); + request.message.header.request.opcode= PROTOCOL_BINARY_CMD_STAT; request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES; - if (args) + if (args_length) { - size_t len= strlen(args); - - memcached_return_t rc= memcached_validate_key_length(len, true); - if (rc != MEMCACHED_SUCCESS) - { - return rc; - } + request.message.header.request.keylen= htons(uint16_t(args_length)); + request.message.header.request.bodylen= htonl(uint32_t( args_length)); - request.message.header.request.keylen= htons((uint16_t)len); - request.message.header.request.bodylen= htonl((uint32_t) len); - - struct libmemcached_io_vector_st vector[]= + libmemcached_io_vector_st vector[]= { { request.bytes, sizeof(request.bytes) }, - { args, len } + { args, args_length } }; if (memcached_vdo(instance, vector, 2, true) != MEMCACHED_SUCCESS) @@ -345,8 +376,12 @@ static memcached_return_t binary_stats_fetch(memcached_stat_st *memc_stat, } else { - if (memcached_do(instance, request.bytes, - sizeof(request.bytes), true) != MEMCACHED_SUCCESS) + libmemcached_io_vector_st vector[]= + { + { request.bytes, sizeof(request.bytes) } + }; + + if (memcached_vdo(instance, vector, 1, true) != MEMCACHED_SUCCESS) { memcached_io_reset(instance); return MEMCACHED_WRITE_FAILURE; @@ -359,23 +394,16 @@ static memcached_return_t binary_stats_fetch(memcached_stat_st *memc_stat, memcached_return_t rc= memcached_response(instance, buffer, sizeof(buffer), NULL); if (rc == MEMCACHED_END) + { break; + } - unlikely (rc != MEMCACHED_SUCCESS) + if (rc != MEMCACHED_SUCCESS) { memcached_io_reset(instance); return rc; } - if (memc_stat) - { - unlikely((set_data(memc_stat, buffer, buffer + strlen(buffer) + 1)) == MEMCACHED_UNKNOWN_STAT_KEY) - { - WATCHPOINT_ERROR(MEMCACHED_UNKNOWN_STAT_KEY); - WATCHPOINT_ASSERT(0); - } - } - if (check && check->func) { size_t key_length= strlen(buffer); @@ -385,80 +413,93 @@ static memcached_return_t binary_stats_fetch(memcached_stat_st *memc_stat, buffer+key_length+1, strlen(buffer+key_length+1), check->context); } + + if (memc_stat) + { + if ((set_data(memc_stat, buffer, buffer + strlen(buffer) + 1)) == MEMCACHED_UNKNOWN_STAT_KEY) + { + WATCHPOINT_ERROR(MEMCACHED_UNKNOWN_STAT_KEY); + WATCHPOINT_ASSERT(0); + } + } } while (1); - /* shit... memcached_response will decrement the counter, so I need to - ** reset it.. todo: look at this and try to find a better solution. - */ - instance->cursor_active= 0; + /* + * memcached_response will decrement the counter, so I need to reset it.. + * todo: look at this and try to find a better solution. + * */ + instance->cursor_active_= 0; return MEMCACHED_SUCCESS; } static memcached_return_t ascii_stats_fetch(memcached_stat_st *memc_stat, const char *args, - memcached_server_write_instance_st instance, + const size_t args_length, + org::libmemcached::Instance* instance, struct local_context *check) { - char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; - int send_length; - - if (args) + libmemcached_io_vector_st vector[]= { - send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "stats %s\r\n", args); - } - else - { - send_length= (size_t) snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "stats\r\n"); - } + { memcached_literal_param("stats ") }, + { args, args_length }, + { memcached_literal_param("\r\n") } + }; - if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0) - { - return memcached_set_error(*instance, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, - memcached_literal_param("snprintf(MEMCACHED_DEFAULT_COMMAND_SIZE)")); - } - - memcached_return_t rc= memcached_do(instance, buffer, (size_t)send_length, true); + memcached_return_t rc= memcached_vdo(instance, vector, 3, true); if (memcached_success(rc)) { - while ((rc= memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL)) == MEMCACHED_STAT) + char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; + while ((rc= memcached_response(instance, buffer, sizeof(buffer), NULL)) == MEMCACHED_STAT) { - char *string_ptr, *end_ptr; - char *key, *value; - - string_ptr= buffer; + char *string_ptr= buffer; string_ptr+= 5; /* Move past STAT */ + + char *end_ptr; for (end_ptr= string_ptr; isgraph(*end_ptr); end_ptr++) {}; - key= string_ptr; - key[(size_t)(end_ptr-string_ptr)]= 0; + char *key= string_ptr; + key[size_t(end_ptr-string_ptr)]= 0; string_ptr= end_ptr + 1; for (end_ptr= string_ptr; !(isspace(*end_ptr)); end_ptr++) {}; - value= string_ptr; + char *value= string_ptr; value[(size_t)(end_ptr -string_ptr)]= 0; - if (memc_stat) - { - unlikely((set_data(memc_stat, key, value)) == MEMCACHED_UNKNOWN_STAT_KEY) - { - WATCHPOINT_ERROR(MEMCACHED_UNKNOWN_STAT_KEY); - WATCHPOINT_ASSERT(0); - } - } +#if 0 + bool check_bool= bool(check); + bool check_func_bool= bool(check) ? bool(check->func) : false; + fprintf(stderr, "%s:%d %s %s %d:%d\n", __FILE__, __LINE__, key, value, check_bool, check_func_bool); +#endif - if (check && check->func) + if (check and check->func) { check->func(instance, key, strlen(key), value, strlen(value), check->context); } + + if (memc_stat) + { + if((set_data(memc_stat, key, value)) == MEMCACHED_UNKNOWN_STAT_KEY) + { + WATCHPOINT_ERROR(MEMCACHED_UNKNOWN_STAT_KEY); + WATCHPOINT_ASSERT(0); + } + } } } + if (rc == MEMCACHED_ERROR) + { + return MEMCACHED_INVALID_ARGUMENTS; + } + if (rc == MEMCACHED_END) + { return MEMCACHED_SUCCESS; - else - return rc; + } + + return rc; } memcached_stat_st *memcached_stat(memcached_st *self, char *args, memcached_return_t *error) @@ -469,29 +510,36 @@ memcached_stat_st *memcached_stat(memcached_st *self, char *args, memcached_retu error= &unused; } - memcached_return_t rc; - if (memcached_failed(rc= initialize_query(self))) + if (memcached_failed(*error= initialize_query(self, true))) { - *error= rc; - return NULL; } - WATCHPOINT_ASSERT(error); - - if (self->flags.use_udp) + if (memcached_is_udp(self)) { *error= memcached_set_error(*self, MEMCACHED_NOT_SUPPORTED, MEMCACHED_AT); - return NULL; } - memcached_stat_st *stats= static_cast(libmemcached_calloc(self, memcached_server_count(self), sizeof(memcached_stat_st))); - - if (not stats) + memcached_return_t rc; + size_t args_length= 0; + if (args) { - *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; + args_length= strlen(args); + rc= memcached_validate_key_length(args_length, self->flags.binary_protocol); + if (memcached_failed(rc)) + { + *error= memcached_set_error(*self, rc, MEMCACHED_AT); + return NULL; + } + } + WATCHPOINT_ASSERT(error); + + memcached_stat_st *stats= libmemcached_xcalloc(self, memcached_server_count(self), memcached_stat_st); + if (stats == NULL) + { + *error= memcached_set_error(*self, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT); return NULL; } @@ -499,24 +547,28 @@ memcached_stat_st *memcached_stat(memcached_st *self, char *args, memcached_retu rc= MEMCACHED_SUCCESS; for (uint32_t x= 0; x < memcached_server_count(self); x++) { - memcached_return_t temp_return; - memcached_server_write_instance_st instance; - memcached_stat_st *stat_instance; - - stat_instance= stats +x; + memcached_stat_st* stat_instance= stats +x; stat_instance->pid= -1; stat_instance->root= self; - instance= memcached_server_instance_fetch(self, x); + org::libmemcached::Instance* instance= memcached_instance_fetch(self, x); - if (self->flags.binary_protocol) + memcached_return_t temp_return; + if (memcached_is_binary(self)) { - temp_return= binary_stats_fetch(stat_instance, args, instance, NULL); + temp_return= binary_stats_fetch(stat_instance, args, args_length, instance, NULL); } else { - temp_return= ascii_stats_fetch(stat_instance, args, instance, NULL); + temp_return= ascii_stats_fetch(stat_instance, args, args_length, instance, NULL); + } + + // Special case where "args" is invalid + if (temp_return == MEMCACHED_INVALID_ARGUMENTS) + { + rc= MEMCACHED_INVALID_ARGUMENTS; + break; } if (memcached_failed(temp_return)) @@ -534,31 +586,43 @@ memcached_return_t memcached_stat_servername(memcached_stat_st *memc_stat, char const char *hostname, in_port_t port) { memcached_st memc; - memcached_server_write_instance_st instance; memset(memc_stat, 0, sizeof(memcached_stat_st)); memcached_st *memc_ptr= memcached_create(&memc); - if (not memc_ptr) + if (memc_ptr == NULL) + { return MEMCACHED_MEMORY_ALLOCATION_FAILURE; - - memcached_server_add(&memc, hostname, port); + } memcached_return_t rc; - if ((rc= initialize_query(memc_ptr)) != MEMCACHED_SUCCESS) + if (memcached_failed(rc= memcached_server_add(&memc, hostname, port))) { + memcached_free(&memc); return rc; } - instance= memcached_server_instance_fetch(memc_ptr, 0); - - if (memc.flags.binary_protocol) + if (memcached_success(rc= initialize_query(memc_ptr, true))) { - rc= binary_stats_fetch(memc_stat, args, instance, NULL); - } - else - { - rc= ascii_stats_fetch(memc_stat, args, instance, NULL); + size_t args_length= 0; + if (args) + { + args_length= strlen(args); + rc= memcached_validate_key_length(args_length, memc.flags.binary_protocol); + } + + if (memcached_success(rc)) + { + org::libmemcached::Instance* instance= memcached_instance_fetch(memc_ptr, 0); + if (memc.flags.binary_protocol) + { + rc= binary_stats_fetch(memc_stat, args, args_length, instance, NULL); + } + else + { + rc= ascii_stats_fetch(memc_stat, args, args_length, instance, NULL); + } + } } memcached_free(&memc); @@ -574,8 +638,10 @@ char ** memcached_stat_get_keys(memcached_st *ptr, memcached_stat_st *, memcached_return_t *error) { - if (not ptr) + if (ptr == NULL) + { return NULL; + } char **list= static_cast(libmemcached_malloc(ptr, sizeof(memcached_stat_keys))); if (not list) @@ -609,19 +675,19 @@ void memcached_stat_free(const memcached_st *, memcached_stat_st *memc_stat) } static memcached_return_t call_stat_fn(memcached_st *ptr, - memcached_server_write_instance_st instance, + org::libmemcached::Instance* instance, void *context) { memcached_return_t rc; - struct local_context *check= (struct local_context *)context; + local_context *check= (struct local_context *)context; - if (ptr->flags.binary_protocol) + if (memcached_is_binary(ptr)) { - rc= binary_stats_fetch(NULL, check->args, instance, check); + rc= binary_stats_fetch(NULL, check->args, check->args_length, instance, check); } else { - rc= ascii_stats_fetch(NULL, check->args, instance, check); + rc= ascii_stats_fetch(NULL, check->args, check->args_length, instance, check); } return rc; @@ -631,7 +697,7 @@ memcached_return_t memcached_stat_execute(memcached_st *memc, const char *args, { memcached_version(memc); - struct local_context check(func, context, args); + local_context check(func, context, args, args ? strlen(args) : 0); return memcached_server_execute(memc, call_stat_fn, (void *)&check); }