diff --git a/items.c b/items.c index faa20cf9c8..ee6a292a94 100644 --- a/items.c +++ b/items.c @@ -335,7 +335,7 @@ char *do_item_cachedump(const unsigned int slabs_clsid, const unsigned int limit char *do_item_stats(uint32_t (*add_stats)(char *buf, const char *key, const uint16_t klen, const char *val, - const uint32_t vlen), int *bytes) { + const uint32_t vlen, void *cookie), void *c, int *bytes) { size_t bufleft = (size_t) LARGEST_ID * 240; char *buffer = malloc(bufleft); @@ -358,31 +358,31 @@ char *do_item_stats(uint32_t (*add_stats)(char *buf, sprintf(key, "items:%d:number", i); sprintf(val, "%u", sizes[i]); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; sprintf(key, "items:%d:age", i); sprintf(val, "%u", now - tails[i]->time); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; sprintf(key, "items:%d:evicted", i); sprintf(val, "%u", itemstats[i].evicted); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; sprintf(key, "items:%d:evicted_time", i); sprintf(val, "%u", itemstats[i].evicted_time); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; sprintf(key, "items:%d:outofmemory", i); sprintf(val, "%u", itemstats[i].outofmemory); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; @@ -397,7 +397,7 @@ char *do_item_stats(uint32_t (*add_stats)(char *buf, } /* getting here means both ascii and binary terminators fit */ - linelen += add_stats(bufcurr, NULL, 0, NULL, 0); + linelen += add_stats(bufcurr, NULL, 0, NULL, 0, c); *bytes = linelen; return buffer; @@ -405,9 +405,9 @@ char *do_item_stats(uint32_t (*add_stats)(char *buf, /** dumps out a list of objects of each size, with granularity of 32 bytes */ /*@null@*/ -char *do_item_stats_sizes(uint32_t (*add_stats)(char *buf, const char *key, - const uint16_t klen, const char *val, - const uint32_t vlen), int *bytes) { +char *do_item_stats_sizes(uint32_t (*add_stats)(char *buf, + const char *key, const uint16_t klen, const char *val, + const uint32_t vlen, void *cookie), void *c, int *bytes) { const int num_buckets = 32768; /* max 1MB object, divided into 32 bytes size buckets */ unsigned int *histogram = (unsigned int *)malloc((size_t)num_buckets * sizeof(int)); @@ -445,13 +445,13 @@ char *do_item_stats_sizes(uint32_t (*add_stats)(char *buf, const char *key, if (histogram[i] != 0) { sprintf(key, "%d", i * 32); sprintf(val, "%u", histogram[i]); - nbytes = add_stats(ptr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(ptr, key, strlen(key), val, strlen(val), c); linelen += nbytes; ptr += nbytes; } } - nbytes = add_stats(ptr, NULL, 0, NULL, 0); + nbytes = add_stats(ptr, NULL, 0, NULL, 0, c); *bytes = linelen + nbytes; free(histogram); diff --git a/items.h b/items.h index c41265e72f..660cc8ad45 100644 --- a/items.h +++ b/items.h @@ -15,11 +15,11 @@ int do_item_replace(item *it, item *new_it); char *do_item_cachedump(const unsigned int slabs_clsid, const unsigned int limit, unsigned int *bytes); char *do_item_stats(uint32_t (*add_stats)(char *buf, const char *key, const uint16_t klen, const char *val, - const uint32_t vlen), int *bytes); + const uint32_t vlen, void *cookie), void *c, int *bytes); /*@null@*/ -char *do_item_stats_sizes(uint32_t (*add_stats)(char *buf, const char *key, - const uint16_t klen, const char *val, - const uint32_t vlen), int *bytes); +char *do_item_stats_sizes(uint32_t (*add_stats)(char *buf, + const char *key, const uint16_t klen, const char *val, + const uint32_t vlen, void *cookie), void *c, int *bytes); void do_item_flush_expired(void); diff --git a/memcached.c b/memcached.c index f098198407..3698f891c7 100644 --- a/memcached.c +++ b/memcached.c @@ -67,7 +67,10 @@ static void conn_set_state(conn *c, enum conn_states state); /* stats */ static void stats_reset(void); static void stats_init(void); -static char *server_stats(bool binprot, int *size); +static char *server_stats(uint32_t (*add_stats)(char *buf, const char *key, + const uint16_t klen, const char *val, + const uint32_t vlen, void *cookie), conn *c, + int *buflen); /* defaults */ static void settings_init(void); @@ -1227,11 +1230,12 @@ static void process_bin_get(conn *c) { } uint32_t append_bin_stats(char *buf, const char *key, const uint16_t klen, - const char *val, const uint32_t vlen) { + const char *val, const uint32_t vlen, void *cookie) { protocol_binary_response_header *header; char *ptr = buf; uint32_t bodylen = klen + vlen; header = (protocol_binary_response_header *)ptr; + conn *c = (conn *)cookie; header->response.magic = (uint8_t)PROTOCOL_BINARY_RES; header->response.opcode = PROTOCOL_BINARY_CMD_STAT; @@ -1240,8 +1244,8 @@ uint32_t append_bin_stats(char *buf, const char *key, const uint16_t klen, header->response.datatype = (uint8_t)PROTOCOL_BINARY_RAW_BYTES; header->response.status = (uint16_t)htons(0); header->response.bodylen = htonl(bodylen); - header->response.opaque = htonl(0); - header->response.cas = swap64(0); /* this can be anything... */ + header->response.opaque = c->opaque; + header->response.cas = swap64(0); ptr += sizeof(header->response); if (klen > 0) { @@ -1276,12 +1280,13 @@ static void process_bin_stat(conn *c) { int server_statlen, engine_statlen; char *ptr, *server_statbuf, *engine_statbuf; - if ((server_statbuf = server_stats(true, &server_statlen)) == NULL) { + if ((server_statbuf = server_stats(&append_bin_stats, (void *)c, + &server_statlen)) == NULL) { write_bin_error(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, 0); return; } - if ((engine_statbuf = get_stats(NULL, &append_bin_stats, + if ((engine_statbuf = get_stats(NULL, &append_bin_stats, (void *)c, &engine_statlen)) == NULL) { free(server_statbuf); write_bin_error(c, PROTOCOL_BINARY_RESPONSE_ENOMEM, 0); @@ -1304,7 +1309,8 @@ static void process_bin_stat(conn *c) { memcpy(ptr, engine_statbuf, engine_statlen); ptr += engine_statlen; - append_bin_stats(ptr, NULL, 0, NULL, 0); /* append termination packet */ + /* append termination packet */ + append_bin_stats(ptr, NULL, 0, NULL, 0, (void *)c); free(server_statbuf); free(engine_statbuf); @@ -1319,7 +1325,7 @@ static void process_bin_stat(conn *c) { stats_reset(); - append_bin_stats(buf, NULL, 0, NULL, 0); + append_bin_stats(buf, NULL, 0, NULL, 0, (void *)c); write_and_free(c, buf, sizeof(header->response)); } else if (strncmp(subcommand, "detail", 6) == 0) { char *subcmd_pos = subcommand + 6; @@ -1346,9 +1352,9 @@ static void process_bin_stat(conn *c) { bufpos = buf; nbytes = append_bin_stats(bufpos, "detailed", strlen("detailed"), - dump_buf, len); + dump_buf, len, (void *)c); bufpos += nbytes; - nbytes += append_bin_stats(bufpos, NULL, 0, NULL, 0); + nbytes += append_bin_stats(bufpos, NULL, 0, NULL, 0, (void *)c); free(dump_buf); write_and_free(c, buf, nbytes); @@ -1372,12 +1378,12 @@ static void process_bin_stat(conn *c) { return; } - len = append_bin_stats(bufpos, NULL, 0, NULL, 0); + len = append_bin_stats(bufpos, NULL, 0, NULL, 0, (void *)c); write_and_free(c, buf, len); return; } else { int len = 0; - buf = get_stats(subcommand, &append_bin_stats, &len); + buf = get_stats(subcommand, &append_bin_stats, (void *)c, &len); memset(subcommand, 0, strlen(subcommand)); /* len is set to -1 in get_stats if memory couldn't be allocated */ @@ -1972,11 +1978,17 @@ inline static void process_stats_detail(conn *c, const char *command) { } /* return server specific stats only */ -static char *server_stats(bool binprot, int *buflen) { +static char *server_stats(uint32_t (*add_stats)(char *buf, const char *key, + const uint16_t klen, const char *val, + const uint32_t vlen, void *cookie), conn *c, + int *buflen) { char temp[1024]; - char *buf; - pid_t pid = getpid(); + char val[128]; + char *buf = NULL; char *pos = temp; + size_t nbytes; + int vlen = 0; + pid_t pid = getpid(); rel_time_t now = current_time; *buflen = 0; @@ -1986,84 +1998,126 @@ static char *server_stats(bool binprot, int *buflen) { #endif /* !WIN32 */ STATS_LOCK(); - pos += sprintf(pos, "STAT pid %lu\r\n", (long)pid); - pos += sprintf(pos, "STAT uptime %u\r\n", now); - pos += sprintf(pos, "STAT time %ld\r\n", now + stats.started); - pos += sprintf(pos, "STAT version " VERSION "\r\n"); - pos += sprintf(pos, "STAT pointer_size %d\r\n", (int)(8 * sizeof(void *))); + memset(val, 0, 128); + + vlen = sprintf(val, "%lu", (long)pid); + nbytes = add_stats(pos, "pid", strlen("pid"), val, vlen, (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%u", now); + nbytes = add_stats(pos, "uptime", strlen("uptime"), val, vlen, (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%ld", now + stats.started); + nbytes = add_stats(pos, "time", strlen("time"), val, vlen, (void *)c); + pos += nbytes; + *buflen += nbytes; + + nbytes = add_stats(pos, "version", strlen("version"), VERSION, + strlen(VERSION), (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%d", (int)(8 * sizeof(void *))); + nbytes = add_stats(pos, "pointer_size", strlen("pointer_size"), val, vlen, + (void *)c); + pos += nbytes; + *buflen += nbytes; + #ifndef WIN32 - pos += sprintf(pos, "STAT rusage_user %ld.%06ld\r\n", (long)usage.ru_utime.tv_sec, (long)usage.ru_utime.tv_usec); - pos += sprintf(pos, "STAT rusage_system %ld.%06ld\r\n", (long)usage.ru_stime.tv_sec, (long)usage.ru_stime.tv_usec); + vlen = sprintf(val, "%ld.%06ld", (long)usage.ru_utime.tv_sec, + (long)usage.ru_utime.tv_usec); + nbytes = add_stats(pos, "rusage_user", strlen("rusage_user"), val, vlen, + (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%ld.%06ld", (long)usage.ru_stime.tv_sec, + (long)usage.ru_stime.tv_usec); + nbytes = add_stats(pos, "rusage_system", strlen("rusage_system"), val, + vlen, (void *)c); + pos += nbytes; + *buflen += nbytes; #endif /* !WIN32 */ - pos += sprintf(pos, "STAT curr_connections %u\r\n", stats.curr_conns - 1); /* ignore listening conn */ - pos += sprintf(pos, "STAT total_connections %u\r\n", stats.total_conns); - pos += sprintf(pos, "STAT connection_structures %u\r\n", stats.conn_structs); - pos += sprintf(pos, "STAT cmd_get %llu\r\n", - (unsigned long long)stats.get_cmds); - pos += sprintf(pos, "STAT cmd_set %llu\r\n", - (unsigned long long)stats.set_cmds); - pos += sprintf(pos, "STAT get_hits %llu\r\n", - (unsigned long long)stats.get_hits); - pos += sprintf(pos, "STAT get_misses %llu\r\n", - (unsigned long long)stats.get_misses); - pos += sprintf(pos, "STAT bytes_read %llu\r\n", - (unsigned long long)stats.bytes_read); - pos += sprintf(pos, "STAT bytes_written %llu\r\n", - (unsigned long long)stats.bytes_written); - pos += sprintf(pos, "STAT limit_maxbytes %llu\r\n", - (unsigned long long)settings.maxbytes); - pos += sprintf(pos, "STAT threads %u\r\n", settings.num_threads); - /* "END" removed since the storage related stats is appended to this output */ - STATS_UNLOCK(); - /* our work is done for ascii protocol */ - if(!binprot) { - if((buf = malloc(strlen(temp))) == NULL) - return NULL; - - *buflen = strlen(temp); - memcpy(buf, temp, strlen(temp)); - return buf; - } - - /* from here on is for the binary protocol */ - if((buf = malloc(1024)) == NULL) + vlen = sprintf(val, "%u", stats.curr_conns - 1); /* ignore listening conn */ + nbytes = add_stats(pos, "curr_connections", strlen("curr_connections"), + val, vlen, (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%u", stats.total_conns); + nbytes = add_stats(pos, "total_connections", strlen("total_connections"), + val, vlen, (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%u", stats.conn_structs); + nbytes = add_stats(pos, "connection_structures", + strlen("connection_structures"), val, vlen, (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%llu", (unsigned long long)stats.get_cmds); + nbytes = add_stats(pos, "cmd_get", strlen("cmd_get"), val, vlen, (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%llu", (unsigned long long)stats.set_cmds); + nbytes = add_stats(pos, "cmd_set", strlen("cmd_set"), val, vlen, (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%llu", (unsigned long long)stats.get_hits); + nbytes = add_stats(pos, "get_hits", strlen("get_hits"), val, vlen, + (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%llu", (unsigned long long)stats.get_misses); + nbytes = add_stats(pos, "get_misses", strlen("get_misses"), val, vlen, + (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%llu", (unsigned long long)stats.bytes_read); + nbytes = add_stats(pos, "bytes_read", strlen("bytes_read"), val, vlen, + (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%llu", (unsigned long long)stats.bytes_written); + nbytes = add_stats(pos, "bytes_written", strlen("bytes_written"), val, + vlen, (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%llu", (unsigned long long)settings.maxbytes); + nbytes = add_stats(pos, "limit_maxbytes", strlen("limit_maxbytes"), val, + vlen, (void *)c); + pos += nbytes; + *buflen += nbytes; + + vlen = sprintf(val, "%u", settings.num_threads); + nbytes = add_stats(pos, "threads", strlen("threads"), val, vlen, (void *)c); + pos += nbytes; + *buflen += nbytes; + + if(*buflen > 0 && (buf = malloc(*buflen)) == NULL) { + STATS_UNLOCK(); return NULL; - - char *end_attr, *end_row, *end_stats; - char *bufptr = buf; - char key[128]; - char val[256]; - uint32_t bodylen; - - pos = temp; - end_stats = strchr(pos, '\0'); - - while(pos < end_stats) { - memset(key, 0, 128); - memset(val, 0, 256); - - end_row = strchr(pos, '\n'); - pos += strlen("STATS"); - - for (end_attr = pos; isgraph(*end_attr); end_attr++); - memcpy(key, pos, (size_t)(end_attr - pos)); - - pos = end_attr + 1; - for (end_attr = pos; !(isspace(*end_attr)); end_attr++); - memcpy(val, pos, (size_t)(end_attr - pos)); - - pos = end_row + 1; /* increment pointer to next row */ - bodylen = append_bin_stats(bufptr, key, strlen(key), val, strlen(val)); - bufptr += bodylen; - *buflen += bodylen; } + memcpy(buf, temp, *buflen); + STATS_UNLOCK(); + return buf; } uint32_t append_ascii_stats(char *buf, const char *key, const uint16_t klen, - const char *val, const uint32_t vlen) { + const char *val, const uint32_t vlen, void *cookie) { char *pos = buf; uint32_t nbytes = 0; @@ -2094,23 +2148,24 @@ static void process_stat(conn *c, token_t *tokens, const size_t ntokens) { command = tokens[COMMAND_TOKEN].value; if (ntokens == 2 && strcmp(command, "stats") == 0) { - int server_statlen, engine_statlen; + int server_len, engine_len; char *buf, *ptr, *server_statbuf, *engine_statbuf; - if ((server_statbuf = server_stats(false, &server_statlen)) == NULL) { + if ((server_statbuf = server_stats(&append_ascii_stats, c, + &server_len)) == NULL) { out_string(c, "SERVER_ERROR out of memory writing stats"); return; } - if ((engine_statbuf = get_stats(NULL, &append_ascii_stats, - &engine_statlen)) == NULL) { + if ((engine_statbuf = get_stats(NULL, &append_ascii_stats, (void *)c, + &engine_len)) == NULL) { free(server_statbuf); out_string(c, "SERVER_ERROR out of memory writing stats"); return; } /* 6 is: strlen("END\r\n") + sizeof("\0") */ - buf = calloc(1, server_statlen + engine_statlen + 6); + buf = calloc(1, server_len + engine_len + 6); if (buf == NULL) { free(server_statbuf); @@ -2121,18 +2176,18 @@ static void process_stat(conn *c, token_t *tokens, const size_t ntokens) { ptr = buf; - memcpy(ptr, server_statbuf, server_statlen); - ptr += server_statlen; - memcpy(ptr, engine_statbuf, engine_statlen); - ptr += engine_statlen; + memcpy(ptr, server_statbuf, server_len); + ptr += server_len; + memcpy(ptr, engine_statbuf, engine_len); + ptr += engine_len; /* append terminator */ - engine_statlen += append_ascii_stats(ptr, NULL, 0, NULL, 0); + engine_len += append_ascii_stats(ptr, NULL, 0, NULL, 0, (void *)c); free(server_statbuf); free(engine_statbuf); - write_and_free(c, buf, server_statlen + engine_statlen); + write_and_free(c, buf, server_len + engine_len); return; } @@ -2148,7 +2203,7 @@ static void process_stat(conn *c, token_t *tokens, const size_t ntokens) { #ifdef HAVE_STRUCT_MALLINFO if (strcmp(subcommand, "malloc") == 0) { int len = 0; - char *buf = get_stats("malloc", &append_ascii_stats, &len); + char *buf = get_stats("malloc", &append_ascii_stats, (void *)c, &len); write_and_free(c, buf, len); return; } @@ -2229,7 +2284,7 @@ static void process_stat(conn *c, token_t *tokens, const size_t ntokens) { /* getting here means that the subcommand is either engine specific or is invalid. query the engine and see. */ int bytes = 0; - char *buf = get_stats(subcommand, &append_ascii_stats, &bytes); + char *buf = get_stats(subcommand, &append_ascii_stats, (void *)c, &bytes); if (buf && bytes > 0) { write_and_free(c, buf, bytes); diff --git a/memcached.h b/memcached.h index 03cadbdf9f..b905cd4ba2 100644 --- a/memcached.h +++ b/memcached.h @@ -281,9 +281,9 @@ char *do_add_delta(conn *c, item *item, const bool incr, const int64_t delta, int do_store_item(item *item, int comm, conn* c); conn *conn_new(const int sfd, const enum conn_states init_state, const int event_flags, const int read_buffer_size, enum protocol prot, struct event_base *base); uint32_t append_bin_stats(char *buf, const char *key, const uint16_t klen, - const char *val, const uint32_t vlen); + const char *val, const uint32_t vlen, void *cookie); uint32_t append_ascii_stats(char *buf, const char *key, const uint16_t klen, - const char *val, const uint32_t vlen); + const char *val, const uint32_t vlen, void *cookie); extern int daemonize(int nochdir, int noclose); @@ -323,10 +323,10 @@ void item_remove(item *it); int item_replace(item *it, item *new_it); char *item_stats(uint32_t (*add_stats)(char *buf, const char *key, const uint16_t klen, const char *val, - const uint32_t vlen), int *bytes); -char *item_stats_sizes(uint32_t (*add_stats)(char *buf, const char *key, - const uint16_t klen, const char *val, - const uint32_t vlen), int *bytes); + const uint32_t vlen, void *cookie), void *c, int *bytes); +char *item_stats_sizes(uint32_t (*add_stats)(char *buf, + const char *key, const uint16_t klen, const char *val, + const uint32_t vlen, void *cookie), void *c, int *bytes); void item_unlink(item *it); void item_update(item *it); void *slabs_alloc(size_t size, unsigned int id); @@ -334,7 +334,7 @@ void slabs_free(void *ptr, size_t size, unsigned int id); int slabs_reassign(unsigned char srcid, unsigned char dstid); char *slabs_stats(uint32_t (*add_stats)(char *buf, const char *key, const uint16_t klen, const char *val, - const uint32_t vlen), int *buflen); + const uint32_t vlen, void *cookie), void *c, int *buflen); void STATS_LOCK(void); void STATS_UNLOCK(void); int store_item(item *item, int comm, conn *c); diff --git a/slabs.c b/slabs.c index 1767253b21..27d040f369 100644 --- a/slabs.c +++ b/slabs.c @@ -310,12 +310,11 @@ void do_slabs_free(void *ptr, const size_t size, unsigned int id) { char *get_stats(const char *stat_type, uint32_t (*add_stats)(char *buf, const char *key, const uint16_t klen, const char *val, - const uint32_t vlen), int *buflen) { - + const uint32_t vlen, void *cookie), void *c, int *buflen) { char *buf, *pos; char val[128]; - int size = 0; - *buflen = 0; + int size, vlen; + *buflen = size = vlen = 0; if (add_stats == NULL) return NULL; @@ -329,40 +328,38 @@ char *get_stats(const char *stat_type, uint32_t (*add_stats)(char *buf, pos = buf; /* prepare general statistics for the engine */ - sprintf(val, "%llu", (unsigned long long)stats.curr_bytes); - size = add_stats(pos, "bytes", strlen("bytes"), val, strlen(val)); + vlen = sprintf(val, "%llu", (unsigned long long)stats.curr_bytes); + size = add_stats(pos, "bytes", strlen("bytes"), val, vlen, c); *buflen += size; pos += size; - sprintf(val, "%u", stats.curr_items); - size = add_stats(pos, "curr_items", strlen("curr_items"), val, - strlen(val)); + vlen = sprintf(val, "%u", stats.curr_items); + size = add_stats(pos, "curr_items", strlen("curr_items"), val, vlen, c); *buflen += size; pos += size; - sprintf(val, "%u", stats.total_items); - size = add_stats(pos, "total_items", strlen("total_items"), val, - strlen(val)); + vlen = sprintf(val, "%u", stats.total_items); + size = add_stats(pos, "total_items", strlen("total_items"), val, vlen, + c); *buflen += size; pos += size; - sprintf(val, "%llu", (unsigned long long)stats.evictions); - size = add_stats(pos, "evictions", strlen("evictions"), val, - strlen(val)); + vlen = sprintf(val, "%llu", (unsigned long long)stats.evictions); + size = add_stats(pos, "evictions", strlen("evictions"), val, vlen, c); *buflen += size; pos += size; return buf; } else if (strcmp(stat_type, "items") == 0) { - buf = item_stats(add_stats, &size); + buf = item_stats(add_stats, c, &size); *buflen = size; return buf; } else if (strcmp(stat_type, "slabs") == 0) { - buf = slabs_stats(add_stats, &size); + buf = slabs_stats(add_stats, c, &size); *buflen = size; return buf; } else if (strcmp(stat_type, "sizes") == 0) { - buf = item_stats_sizes(add_stats, &size); + buf = item_stats_sizes(add_stats, c, &size); *buflen = size; return buf; } @@ -385,67 +382,67 @@ char *get_stats(const char *stat_type, uint32_t (*add_stats)(char *buf, char val[128]; uint32_t nbytes = 0; - sprintf(val, "%ld", (long)info.arena); + vlen = sprintf(val, "%ld", (long)info.arena); nbytes = add_stats(pos, "arena_size", strlen("arena_size"), val, - strlen(val)); + vlen, c); linelen += nbytes; pos += nbytes; - sprintf(val, "%ld", (long)info.ordblks); + vlen = sprintf(val, "%ld", (long)info.ordblks); nbytes = add_stats(pos, "free_chunks", strlen("free_chunks"), val, - strlen(val)); + vlen, c); linelen += nbytes; pos += nbytes; - sprintf(val, "%ld", (long)info.smblks); + vlen = sprintf(val, "%ld", (long)info.smblks); nbytes = add_stats(pos, "fastbin_blocks", strlen("fastbin_blocks"), - val, strlen(val)); + val, vlen, c); linelen += nbytes; pos += nbytes; - sprintf(val, "%ld", (long)info.hblks); + vlen = sprintf(val, "%ld", (long)info.hblks); nbytes = add_stats(pos, "mmapped_regions", strlen("mmapped_regions"), - val, strlen(val)); + val, vlen, c); linelen += nbytes; pos += nbytes; - sprintf(val, "%ld", (long)info.hblkhd); + vlen = sprintf(val, "%ld", (long)info.hblkhd); nbytes = add_stats(pos, "mmapped_space", strlen("mmapped_space"), - val, strlen(val)); + val, vlen, c); linelen += nbytes; pos += nbytes; - sprintf(val, "%ld", (long)info.usmblks); + vlen = sprintf(val, "%ld", (long)info.usmblks); nbytes = add_stats(pos, "max_total_alloc", strlen("max_total_alloc"), - val, strlen(val)); + val, vlen, c); linelen += nbytes; pos += nbytes; - sprintf(val, "%ld", (long)info.fsmblks); + vlen = sprintf(val, "%ld", (long)info.fsmblks); nbytes = add_stats(pos, "fastbin_space", strlen("fastbin_space"), - val, strlen(val)); + val, vlen, c); linelen += nbytes; pos += nbytes; - sprintf(val, "%ld", (long)info.uordblks); + vlen = sprintf(val, "%ld", (long)info.uordblks); nbytes = add_stats(pos, "total_alloc", strlen("total_alloc"), val, - strlen(val)); + vlen, c); linelen += nbytes; pos += nbytes; - sprintf(val, "%ld", (long)info.fordblks); + vlen = sprintf(val, "%ld", (long)info.fordblks); nbytes = add_stats(pos, "total_free", strlen("total_free"), val, - strlen(val)); + vlen, c); linelen += nbytes; pos += nbytes; - sprintf(val, "%ld", (long)info.keepcost); - nbytes = add_stats(pos, "releasable_space", - strlen("releasable_space"), val, strlen(val)); + vlen = sprintf(val, "%ld", (long)info.keepcost); + nbytes = add_stats(pos, "releasable_space", strlen("releasable_space"), + val, vlen, c); linelen += nbytes; pos += nbytes; - linelen += add_stats(pos, NULL, 0, NULL, 0); + linelen += add_stats(pos, NULL, 0, NULL, 0, c); *buflen = linelen; return buf; @@ -457,9 +454,9 @@ char *get_stats(const char *stat_type, uint32_t (*add_stats)(char *buf, } /*@null@*/ -char *do_slabs_stats(uint32_t (*add_stats)(char *buf, const char *key, - const uint16_t klen, const char *val, - const uint32_t vlen), int *buflen) { +char *do_slabs_stats(uint32_t (*add_stats)(char *buf, + const char *key, const uint16_t klen, const char *val, + const uint32_t vlen, void *cookie), void *c, int *buflen) { int i, total, linelen; char *buf = (char *)malloc(power_largest * 200 + 100); char *bufcurr = buf; @@ -486,43 +483,43 @@ char *do_slabs_stats(uint32_t (*add_stats)(char *buf, const char *key, sprintf(key, "%d:chunk_size", i); sprintf(val, "%u", p->size); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; sprintf(key, "%d:chunks_per_page", i); sprintf(val, "%u", perslab); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; sprintf(key, "%d:total_page", i); sprintf(val, "%u", slabs); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; sprintf(key, "%d:total_chunks", i); sprintf(val, "%u", slabs*perslab); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; sprintf(key, "%d:used_chunks", i); sprintf(val, "%u", ((slabs*perslab) - p->sl_curr)); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; sprintf(key, "%d:free_chunks", i); sprintf(val, "%u", p->sl_curr); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; sprintf(key, "%d:free_chunks_end", i); sprintf(val, "%u", p->end_page_free); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; @@ -537,17 +534,17 @@ char *do_slabs_stats(uint32_t (*add_stats)(char *buf, const char *key, sprintf(key, "active_slabs"); sprintf(val, "%d", total); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; sprintf(key, "total_malloced"); sprintf(val, "%llu", (unsigned long long)mem_malloced); - nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val)); + nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c); linelen += nbytes; bufcurr += nbytes; - linelen += add_stats(bufcurr, NULL, 0, NULL, 0); + linelen += add_stats(bufcurr, NULL, 0, NULL, 0, c); *buflen = linelen; return buf; diff --git a/slabs.h b/slabs.h index 42af9ccd09..78f28645a4 100644 --- a/slabs.h +++ b/slabs.h @@ -25,12 +25,12 @@ void do_slabs_free(void *ptr, size_t size, unsigned int id); /** Return a datum for stats in binary protocol */ char *get_stats(const char *stat_type, uint32_t (*add_stats)(char *buf, const char *key, const uint16_t klen, const char *val, - const uint32_t vlen), int *buflen); + const uint32_t vlen, void *cookie), void *arg, int *buflen); /** Fill buffer with stats */ /*@null@*/ -char *do_slabs_stats(uint32_t (*add_stats)(char *buf, const char *key, - const uint16_t klen, const char *val, - const uint32_t vlen), int *buflen); +char *do_slabs_stats(uint32_t (*add_stats)(char *buf, + const char *key, const uint16_t klen, const char *val, + const uint32_t vlen, void *cookie), void *c, int *buflen); /* Request some slab be moved between classes 1 = success diff --git a/t/binary.t b/t/binary.t index afd6284e81..1c62a5a578 100755 --- a/t/binary.t +++ b/t/binary.t @@ -257,7 +257,7 @@ sub _do_command { $extra_header = '' unless defined $extra_header; my $opaque = int(rand(2**32)); $self->send_command($cmd, $key, $val, $opaque, $extra_header, $cas); - (undef, my $rv, my $rcas) = $self->_handle_single_response($opaque); + my (undef, $rv, $rcas) = $self->_handle_single_response($opaque); return ($rv, $rcas); } diff --git a/thread.c b/thread.c index c21c990971..60d9e5a39c 100644 --- a/thread.c +++ b/thread.c @@ -506,12 +506,12 @@ char *item_cachedump(unsigned int slabs_clsid, unsigned int limit, unsigned int * Dumps statistics about slab classes */ char *item_stats(uint32_t (*add_stats)(char *buf, const char *key, - const uint16_t klen, const char *val, const uint32_t vlen), - int *bytes) { + const uint16_t klen, const char *val, const uint32_t vlen, + void *cookie), void *c, int *bytes) { char *ret; pthread_mutex_lock(&cache_lock); - ret = do_item_stats(add_stats, bytes); + ret = do_item_stats(add_stats, c, bytes); pthread_mutex_unlock(&cache_lock); return ret; } @@ -519,13 +519,13 @@ char *item_stats(uint32_t (*add_stats)(char *buf, const char *key, /* * Dumps a list of objects of each size in 32-byte increments */ -char *item_stats_sizes(uint32_t (*add_stats)(char *buf, const char *key, - const uint16_t klen, const char *val, - const uint32_t vlen), int *bytes) { +char *item_stats_sizes(uint32_t (*add_stats)(char *buf, + const char *key, const uint16_t klen, const char *val, + const uint32_t vlen, void *cookie), void *c, int *bytes) { char *ret; pthread_mutex_lock(&cache_lock); - ret = do_item_stats_sizes(add_stats, bytes); + ret = do_item_stats_sizes(add_stats, c, bytes); pthread_mutex_unlock(&cache_lock); return ret; } @@ -555,13 +555,13 @@ void slabs_free(void *ptr, size_t size, unsigned int id) { pthread_mutex_unlock(&slabs_lock); } -char *slabs_stats(uint32_t (*add_stats)(char *buf, const char *key, - const uint16_t klen, const char *val, - const uint32_t vlen), int *buflen) { +char *slabs_stats(uint32_t (*add_stats)(char *buf, + const char *key, const uint16_t klen, const char *val, + const uint32_t vlen, void *cookie), void *c, int *buflen) { char *ret; pthread_mutex_lock(&slabs_lock); - ret = do_slabs_stats(add_stats, buflen); + ret = do_slabs_stats(add_stats, c, buflen); pthread_mutex_unlock(&slabs_lock); return ret; }