Example #1
0
static void print_analysis_report(memcached_st *memc,
                                  memcached_analysis_st *report,
                                  memcached_server_st *server_list)
{
  uint32_t server_count= memcached_server_count(memc);

  printf("Memcached Cluster Analysis Report\n\n");

  printf("\tNumber of Servers Analyzed         : %d\n", server_count);
  printf("\tAverage Item Size (incl/overhead)  : %u bytes\n",
         report->average_item_size);

  if (server_count == 1)
  {
    printf("\nFor a detailed report, you must supply multiple servers.\n");
    return;
  }

  printf("\n");
  printf("\tNode with most memory consumption  : %s:%u (%u bytes)\n",
         memcached_server_name(memc, server_list[report->most_consumed_server]),
         memcached_server_port(memc, server_list[report->most_consumed_server]),
         report->most_used_bytes);
  printf("\tNode with least free space         : %s:%u (%u bytes remaining)\n",
         memcached_server_name(memc, server_list[report->least_free_server]),
         memcached_server_port(memc, server_list[report->least_free_server]),
         report->least_remaining_bytes);
  printf("\tNode with longest uptime           : %s:%u (%us)\n",
         memcached_server_name(memc, server_list[report->oldest_server]),
         memcached_server_port(memc, server_list[report->oldest_server]),
         report->longest_uptime);
  printf("\tPool-wide Hit Ratio                : %1.f%%\n", report->pool_hit_ratio);
  printf("\n");
}
Example #2
0
static void print_server_listing(memcached_st *memc, memcached_stat_st *stat,
                                 memcached_server_st *server_list)
{
  unsigned int x;
  memcached_return rc;

  printf("Listing %u Server\n\n", memcached_server_count(memc));
  for (x= 0; x < memcached_server_count(memc); x++)
  {
    char **list;
    char **ptr;

    list= memcached_stat_get_keys(memc, &stat[x], &rc);

    printf("Server: %s (%u)\n", memcached_server_name(memc, server_list[x]),
           memcached_server_port(memc, server_list[x]));
    for (ptr= list; *ptr; ptr++)
    {
      memcached_return rc;
      char *value= memcached_stat_get_value(memc, &stat[x], *ptr, &rc);

      printf("\t %s: %s\n", *ptr, value);
      free(value);
    }

    free(list);
    printf("\n");
  }
}
Example #3
0
/*doc Memcached stats
Returns a Map with servers' statistics. Keys are server addresses,
values are maps with actual stats.
*/
IoObject *IoMemcached_stats(IoMemcached *self, IoObject *locals, IoMessage *m)
{
	IoMap *results_map = IoMap_new(IOSTATE);

	int errors = 0;
	uint32_t pos = 0;
	while(pos < memcached_server_count(DATA(self)->mc)) {
		memcached_server_instance_st server = memcached_server_instance_by_position(DATA(self)->mc, pos);
		if(server == NULL)
			continue;

		const char *hostname = memcached_server_name(server);
		const in_port_t port = memcached_server_port(server);

		memcached_stat_st stats;
		memcached_return_t rc = memcached_stat_servername(&stats, "", hostname, port);
		if(rc != MEMCACHED_SUCCESS) {
			errors++;
			continue;
		}

		char **ckeys = memcached_stat_get_keys(DATA(self)->mc, &stats, &rc);
		if(rc != MEMCACHED_SUCCESS) {
			errors++;
			continue;
		}

		IoMap *per_server_map = IoMap_new(IOSTATE);
		char *ckey = *ckeys;
		while(ckey != NULL) {
			char *cvalue = memcached_stat_get_value(DATA(self)->mc, &stats, ckey, &rc);
			if(rc != MEMCACHED_SUCCESS) {
				errors++;
				continue;
			}

			IoMap_rawAtPut(per_server_map, IOSYMBOL(ckey), IOSYMBOL(cvalue));
			free(cvalue);
			ckey++;
		}

		free(ckeys);

		// "127.0.0.1:11211"
		char *server_key = (char *) malloc((strlen(hostname) + 1 + 5 + 1) * sizeof(char));
		sprintf(server_key, "%s:%d", hostname, port);

		IoMap_rawAtPut(results_map, IOSYMBOL(server_key), per_server_map);
		free(server_key);

		pos++;
	}

	if(errors > 0)
		IoState_error_(IOSTATE, m, memcached_strerror(DATA(self)->mc, MEMCACHED_SOME_ERRORS));

	return results_map;
}
Example #4
0
File: mcs.c Project: MediaMath/moxi
mcs_st *lmc_create(mcs_st *ptr, const char *config) {
    assert(ptr);
    memset(ptr, 0, sizeof(*ptr));
    ptr->kind = MCS_KIND_LIBMEMCACHED;

    memcached_st *mst = memcached_create(NULL);
    if (mst != NULL) {
        memcached_behavior_set(mst, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
        memcached_behavior_set(mst, MEMCACHED_BEHAVIOR_KETAMA, 1);
        memcached_behavior_set(mst, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);

        memcached_server_st *mservers;

        mservers = memcached_servers_parse(config);
        if (mservers != NULL) {
            memcached_server_push(mst, mservers);

            ptr->data     = mst;
            ptr->nservers = (int) memcached_server_list_count(mservers);
            if (ptr->nservers > 0) {
                ptr->servers = calloc(sizeof(mcs_server_st), ptr->nservers);
                if (ptr->servers != NULL) {
                    for (int i = 0; i < ptr->nservers; i++) {
                        ptr->servers[i].fd = -1;
                    }

                    int j = 0;
                    for (; j < ptr->nservers; j++) {
                        strncpy(ptr->servers[j].hostname,
                                memcached_server_name(mservers + j),
                                sizeof(ptr->servers[j].hostname) - 1);
                        ptr->servers[j].port = (int) memcached_server_port(mservers + j);
                        if (ptr->servers[j].port <= 0) {
                            moxi_log_write("lmc_create failed, could not parse port: %s\n",
                                           config);
                            break;
                        }
                    }

                    if (j >= ptr->nservers) {
                        memcached_server_list_free(mservers);

                        return ptr;
                    }
                }
            }

            memcached_server_list_free(mservers);
        }
    }

    mcs_free(ptr);

    return NULL;
}
Example #5
0
int pr_memcache_kadd(pr_memcache_t *mcache, module *m, const char *key,
    size_t keysz, void *value, size_t valuesz, time_t expires, uint32_t flags) {
  memcached_return res;

  /* XXX Should we allow null values to be added, thus allowing use of keys
   * as sentinels?
   */
  if (mcache == NULL ||
      m == NULL ||
      key == NULL ||
      value == NULL) {
    errno = EINVAL;
    return -1;
  }

  mcache_set_module_namespace(mcache, m);
  res = memcached_add(mcache->mc, key, keysz, value, valuesz, expires, flags); 
  mcache_set_module_namespace(mcache, NULL);

  switch (res) {
    case MEMCACHED_SUCCESS:
      return 0;

    case MEMCACHED_ERRNO:
      if (errno != EINPROGRESS) {
        int xerrno = errno;

        pr_trace_msg(trace_channel, 3,
          "error adding key (%lu bytes), value (%lu bytes): system error: %s",
          (unsigned long) keysz, (unsigned long) valuesz, strerror(xerrno));

        errno = xerrno;

      } else {
        /* We know that we're not using nonblocking IO; this value usually
         * means that libmemcached could not connect to the configured
         * memcached servers.  So set the value to something more
         * indicative, and fall through.
         */
        res = MEMCACHED_CONNECTION_FAILURE;
      }
      break;

    case MEMCACHED_SERVER_MARKED_DEAD:
    case MEMCACHED_CONNECTION_FAILURE: {
      memcached_server_instance_st server;

      server = memcached_server_get_last_disconnect(mcache->mc);
      if (server != NULL) {
        pr_trace_msg(trace_channel, 3,
          "unable to connect to %s:%d", memcached_server_name(server),
          memcached_server_port(server));
      }

      break;
    }

    default:
      pr_trace_msg(trace_channel, 2,
        "error adding key (%lu bytes), value (%lu bytes): %s",
        (unsigned long) keysz, (unsigned long) valuesz,
        memcached_strerror(mcache->mc, res));
      errno = EPERM;
      break;
  }

  return -1;
}
Example #6
0
static int mcache_stat_servers(pr_memcache_t *mcache) {
  memcached_stat_st *mst;
  memcached_return res;

  mst = memcached_stat(mcache->mc, NULL, &res);
  if (mst != NULL) {
    if (res == MEMCACHED_SUCCESS) {
      register unsigned int i;
      const char *stat_keys[] = {
        "version",
        "uptime",
        "curr_connections",
        "curr_items",
        "bytes",
        "limit_maxbytes",
        NULL
      };

      /* Log some of the stats about the memcached servers to which we just
       * connected.
       */  

      for (i = 0; stat_keys[i] != NULL; i++) {
        char *info;

        info = memcached_stat_get_value(mcache->mc, mst, stat_keys[i], &res);
        if (info != NULL) {
          pr_trace_msg(trace_channel, 9,
            "memcached server stats: %s = %s", stat_keys[i], info);
          free(info);

        } else {
          pr_trace_msg(trace_channel, 6,
            "unable to obtain '%s' stat: %s", stat_keys[i],
            memcached_strerror(mcache->mc, res));
        }
      }

    } else {
      switch (res) {
        case MEMCACHED_ERRNO:
          if (errno != EINPROGRESS) {
            pr_trace_msg(trace_channel, 3,
              "error requesting memcached stats: system error: %s",
              strerror(errno));

          } else {
            /* We know that we're not using nonblocking IO; this value usually
             * means that libmemcached could not connect to the configured
             * memcached servers.  So set the value to something more
             * indicative, and fall through.
             */
            res = MEMCACHED_CONNECTION_FAILURE;
          }
          break;

          case MEMCACHED_SOME_ERRORS:
          case MEMCACHED_SERVER_MARKED_DEAD:
          case MEMCACHED_CONNECTION_FAILURE: {
            memcached_server_instance_st server;

            server = memcached_server_get_last_disconnect(mcache->mc);
            if (server != NULL) {
              pr_trace_msg(trace_channel, 3,
                "unable to connect to %s:%d", memcached_server_name(server),
                memcached_server_port(server));
            }

            break;
          }

        default:
          pr_trace_msg(trace_channel, 6,
            "error requesting memcached stats: %s",
            memcached_strerror(mcache->mc, res));
          break;
      }
    }

    memcached_stat_free(mcache->mc, mst);
  }

  return 0;
}
Example #7
0
static int mcache_ping_servers(pr_memcache_t *mcache) {
  memcached_server_st *alive_server_list;
  memcached_return res;
  memcached_st *clone;
  uint32_t server_count;
  register unsigned int i;

  /* We always start with the configured list of servers. */
  clone = memcached_clone(NULL, mcache->mc);
  if (clone == NULL) {
    errno = ENOMEM;
    return -1;
  }

  memcached_servers_reset(clone);

  /* Bug#4242: Don't use memcached_server_push() if we're using
   * libmemcached-1.0.18 or earlier.  Doing so leads to a segfault, due to
   * this libmemcached bug:
   *
   *  https://bugs.launchpad.net/libmemcached/+bug/1154159
   */
#if LIBMEMCACHED_VERSION_HEX > 0x01000018
  memcached_server_push(clone, configured_server_list);
#endif

  server_count = memcached_server_count(clone);
  pr_trace_msg(trace_channel, 16,
    "pinging %lu memcached %s", (unsigned long) server_count,
    server_count != 1 ? "servers" : "server");

  alive_server_list = NULL;
  for (i = 0; i < server_count; i++) {
    memcached_server_instance_st server;

    server = memcached_server_instance_by_position(clone, i);

    pr_trace_msg(trace_channel, 17, "pinging server %s:%d",
      memcached_server_name(server), memcached_server_port(server));

    if (libmemcached_util_ping(memcached_server_name(server),
        memcached_server_port(server), &res) == FALSE) {
      pr_trace_msg(trace_channel, 4,
        "error pinging %s:%d: %s", memcached_server_name(server),
        memcached_server_port(server), memcached_strerror(clone, res));

    } else {
      pr_trace_msg(trace_channel, 17, "server %s:%d is alive",
        memcached_server_name(server), memcached_server_port(server));

       alive_server_list = memcached_server_list_append(alive_server_list,    
         memcached_server_name(server), memcached_server_port(server), &res);
       if (alive_server_list == NULL) {
         pr_trace_msg(trace_channel, 1,
           "error appending server %s:%d to list: %s",
           memcached_server_name(server), memcached_server_port(server),
           memcached_strerror(clone, res));

         memcached_free(clone);
         errno = EPERM;
         return -1;
       }
    }
  }

  if (alive_server_list != NULL) {
    memcached_servers_reset(mcache->mc);
    res = memcached_server_push(mcache->mc, alive_server_list);
    if (res != MEMCACHED_SUCCESS) {
      unsigned int count;

      count = memcached_server_list_count(alive_server_list);
      pr_trace_msg(trace_channel, 2,
        "error adding %u alive memcached %s to connection: %s",
        count, count != 1 ? "servers" : "server",
        memcached_strerror(mcache->mc, res));
      memcached_free(clone);
 
      errno = EPERM;
      return -1;

    } else {
      unsigned int count;

      count = memcached_server_list_count(alive_server_list);
      pr_trace_msg(trace_channel, 9,
        "now using %d alive memcached %s", count,
        count != 1 ? "servers" : "server");

      memcached_server_list_free(alive_server_list);
    }
  }

  memcached_free(clone);
  return 0;
}
Example #8
0
int pr_memcache_kincr(pr_memcache_t *mcache, module *m, const char *key,
    size_t keysz, uint32_t incr, uint64_t *value) {
  memcached_return res;

  if (mcache == NULL ||
      m == NULL ||
      key == NULL ||
      incr == 0) {
    errno = EINVAL;
    return -1;
  }

  /* Note: libmemcached automatically handles the case where value might be
   * NULL.
   */

  mcache_set_module_namespace(mcache, m);
  res = memcached_increment(mcache->mc, key, keysz, incr, value);
  mcache_set_module_namespace(mcache, NULL);

  if (res == MEMCACHED_NOTFOUND) {
    /* Automatically create a value for this key, with the given increment. */

    pr_trace_msg(trace_channel, 18,
      "unable to increment nonexistent key (%lu bytes), automatically "
      "creating one", (unsigned long) keysz);
    return pr_memcache_kset(mcache, m, key, keysz, &incr, sizeof(uint32_t),
      0, 0);
  }

  switch (res) {
    case MEMCACHED_SUCCESS:
      return 0;

    case MEMCACHED_ERRNO:
      if (errno != EINPROGRESS) {
        int xerrno = errno;

        pr_trace_msg(trace_channel, 3,
          "error incrementing key (%lu bytes) by %lu: system error: %s",
          (unsigned long) keysz, (unsigned long) incr, strerror(xerrno));

        errno = xerrno;

      } else {
        /* We know that we're not using nonblocking IO; this value usually
         * means that libmemcached could not connect to the configured
         * memcached servers.  So set the value to something more
         * indicative, and fall through.
         */
        res = MEMCACHED_CONNECTION_FAILURE;
      }
      break;

    case MEMCACHED_SERVER_MARKED_DEAD:
    case MEMCACHED_CONNECTION_FAILURE: {
      memcached_server_instance_st server;

      server = memcached_server_get_last_disconnect(mcache->mc);
      if (server != NULL) {
        pr_trace_msg(trace_channel, 3,
          "unable to connect to %s:%d", memcached_server_name(server),
          memcached_server_port(server));
      }

      break;
    }

    default:
      pr_trace_msg(trace_channel, 2,
        "error incrementing key (%lu bytes) by %lu: %s",
        (unsigned long) keysz, (unsigned long) incr,
        memcached_strerror(mcache->mc, res));
      errno = EPERM;
      break;
  }

  return -1;
}
Example #9
0
char *pr_memcache_kget_str(pr_memcache_t *mcache, module *m, const char *key,
    size_t keysz, uint32_t *flags) {
  char *data = NULL, *ptr = NULL;
  size_t valuesz = 0;
  memcached_return res;
  int xerrno = 0;

  if (mcache == NULL ||
      m == NULL ||
      key == NULL ||
      flags == NULL) {
    errno = EINVAL;
    return NULL;
  }

  mcache_set_module_namespace(mcache, m);
  data = memcached_get(mcache->mc, key, keysz, &valuesz, flags, &res);
  xerrno = errno;
  mcache_set_module_namespace(mcache, NULL);

  if (data == NULL) {
    switch (res) {
      case MEMCACHED_NOTFOUND:
        pr_trace_msg(trace_channel, 8,
          "no data found for key (%lu bytes)", (unsigned long) keysz);
        errno = ENOENT;
        break;

      case MEMCACHED_ERRNO:
        if (errno != EINPROGRESS) {
          pr_trace_msg(trace_channel, 3,
            "no data found for key (%lu bytes): system error: %s",
            (unsigned long) keysz, strerror(xerrno));

          errno = xerrno;

        } else {
          /* We know that we're not using nonblocking IO; this value usually
           * means that libmemcached could not connect to the configured
           * memcached servers.  So set the value to something more
           * indicative, and fall through.
           */
          res = MEMCACHED_CONNECTION_FAILURE;
        }
        break;

      case MEMCACHED_SERVER_MARKED_DEAD:
      case MEMCACHED_CONNECTION_FAILURE: {
        memcached_server_instance_st server;

        server = memcached_server_get_last_disconnect(mcache->mc);
        if (server != NULL) {
          pr_trace_msg(trace_channel, 3,
            "unable to connect to %s:%d", memcached_server_name(server),
            memcached_server_port(server));
        }

        break;
      }

      default:
        pr_trace_msg(trace_channel, 6,
          "error getting data for key (%lu bytes): [%d] %s",
          (unsigned long) keysz, res, memcached_strerror(mcache->mc, res));
        errno = EPERM;
        break;
    }

    return NULL;
  }

  /* Create a duplicate of the returned data from the mcache's pool, so that
   * we can call free(3) on the data returned by libmemcached.
   */

  ptr = pcalloc(mcache->pool, valuesz + 1);
  memcpy(ptr, data, valuesz);
  free(data);

  return ptr;
}
Example #10
0
void server_startup(server_startup_st *construct)
{
  if ((construct->server_list= getenv("MEMCACHED_SERVERS")))
  {
    printf("servers %s\n", construct->server_list);
    construct->servers= memcached_servers_parse(construct->server_list);
    construct->server_list= NULL;
    construct->count= 0;
  }
  else
  {
    {
      char server_string_buffer[8096];
      char *end_ptr;
      end_ptr= server_string_buffer;

      for (uint32_t x= 0; x < construct->count; x++)
      {
        int count;
        int status;
        in_port_t port;

        {
          char *var;
          char variable_buffer[1024];

          snprintf(variable_buffer, sizeof(variable_buffer), "LIBMEMCACHED_PORT_%u", x);

          if ((var= getenv(variable_buffer)))
          {
            port= (in_port_t)atoi(var);
          }
          else
          {
            port= (in_port_t)(x + TEST_PORT_BASE);
          }
        }

        char buffer[PATH_MAX];
        snprintf(buffer, sizeof(buffer), PID_FILE_BASE, x);
        kill_file(buffer);

        if (x == 0)
        {
          snprintf(buffer, sizeof(buffer), "%s -d -u root -P "PID_FILE_BASE" -t 1 -p %u -U %u -m 128",
                   MEMCACHED_BINARY, x, port, port);
        }
        else
        {
          snprintf(buffer, sizeof(buffer), "%s -d -u root -P "PID_FILE_BASE" -t 1 -p %u -U %u",
                   MEMCACHED_BINARY, x, port, port);
        }
	if (libmemcached_util_ping("localhost", port, NULL))
	{
	  fprintf(stderr, "Server on port %u already exists\n", port);
	}
	else
	{
	  status= system(buffer);
	  fprintf(stderr, "STARTING SERVER: %s  status:%d\n", buffer, status);
	}
        count= sprintf(end_ptr, "localhost:%u,", port);
        end_ptr+= count;
      }
      *end_ptr= 0;


      int *pids= calloc(construct->count, sizeof(int));
      for (uint32_t x= 0; x < construct->count; x++)
      {
        char buffer[PATH_MAX]; /* Nothing special for number */

        snprintf(buffer, sizeof(buffer), PID_FILE_BASE, x);

        uint32_t counter= 3000; // Absurd, just to catch run away process
        while (pids[x] <= 0  && --counter)
        {
          FILE *file= fopen(buffer, "r");
          if (file)
          {
            char pid_buffer[1024];
            char *found= fgets(pid_buffer, sizeof(pid_buffer), file);

            if (found)
            {
              pids[x]= atoi(pid_buffer);
              fclose(file);

              if (pids[x] > 0)
                break;
            }
            fclose(file);
          }
          global_sleep();
        }

        bool was_started= false;
        if (pids[x] > 0)
        {
          counter= 30;
          while (--counter)
          {
            if (kill(pids[x], 0) == 0)
            {
              was_started= true;
              break;
            }
            global_sleep();
          }
        }

        if (was_started == false)
        {
          fprintf(stderr, "Failed to open buffer %s(%d)\n", buffer, pids[x]);
          for (uint32_t y= 0; y < construct->count; y++)
          {
            if (pids[y] > 0)
              kill(pids[y], SIGTERM);
          }
          abort();
        }
      }
      free(pids);

      construct->server_list= strdup(server_string_buffer);
    }
    printf("servers %s\n", construct->server_list);
    construct->servers= memcached_servers_parse(construct->server_list);
  }

  assert(construct->servers);

  srandom((unsigned int)time(NULL));

  for (uint32_t x= 0; x < memcached_server_list_count(construct->servers); x++)
  {
    printf("\t%s : %d\n", memcached_server_name(&construct->servers[x]), memcached_server_port(&construct->servers[x]));
    assert(construct->servers[x].fd == -1);
    assert(construct->servers[x].cursor_active == 0);
  }

  printf("\n");
}
Example #11
0
mcs_st *lmc_create(mcs_st *ptr, const char *config,
                   const char *default_usr,
                   const char *default_pwd,
                   const char *opts) {
    assert(ptr);
    memset(ptr, 0, sizeof(*ptr));
    ptr->kind = MCS_KIND_LIBMEMCACHED;

    memcached_st *mst = memcached_create(NULL);
    if (mst != NULL) {
        memcached_behavior_t b = MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED;
        uint64_t             v = 1;

        if (opts != NULL) {
            if (strstr(opts, "distribution:ketama-weighted") != NULL) {
                b = MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED;
                v = 1;
            } else if (strstr(opts, "distribution:ketama") != NULL) {
                b = MEMCACHED_BEHAVIOR_KETAMA;
                v = 1;
            } else if (strstr(opts, "distribution:modula") != NULL) {
                b = MEMCACHED_BEHAVIOR_KETAMA;
                v = 0;
            }
        }

        memcached_behavior_set(mst, b, v);
        memcached_behavior_set(mst, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
        memcached_behavior_set(mst, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);

        memcached_server_st *mservers;

        mservers = memcached_servers_parse(config);
        if (mservers != NULL) {
            memcached_server_push(mst, mservers);

            ptr->data     = mst;
            ptr->nservers = (int) memcached_server_list_count(mservers);
            if (ptr->nservers > 0) {
                ptr->servers = calloc(sizeof(mcs_server_st), ptr->nservers);
                if (ptr->servers != NULL) {
                    for (int i = 0; i < ptr->nservers; i++) {
                        ptr->servers[i].fd = -1;
                    }

                    int j = 0;
                    for (; j < ptr->nservers; j++) {
                        strncpy(ptr->servers[j].hostname,
                                memcached_server_name(mservers + j),
                                sizeof(ptr->servers[j].hostname) - 1);
                        ptr->servers[j].port =
                            (int) memcached_server_port(mservers + j);
                        if (ptr->servers[j].port <= 0) {
                            moxi_log_write("lmc_create failed, could not parse port: %s\n",
                                           config);
                            break;
                        }

                        if (default_usr != NULL) {
                            ptr->servers[j].usr = strdup(default_usr);
                        }

                        if (default_pwd != NULL) {
                            ptr->servers[j].pwd = strdup(default_pwd);
                        }
                    }

                    if (j >= ptr->nservers) {
                        memcached_server_list_free(mservers);

                        return ptr;
                    }
                }
            }

            memcached_server_list_free(mservers);
        }
    }

    mcs_free(ptr);

    return NULL;
}