Ejemplo n.º 1
0
Archivo: mcs.c Proyecto: 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;
}
Ejemplo n.º 2
0
memcached_return_t memcached_server_push(memcached_st *ptr, const memcached_server_list_st list)
{
  uint32_t count;
  memcached_server_st *new_host_list;
  uint32_t x;

  if (! list)
    return MEMCACHED_SUCCESS;

  count= memcached_server_list_count(list);
  new_host_list= libmemcached_realloc(ptr, memcached_server_list(ptr),
                                      sizeof(memcached_server_st) * (count + memcached_server_count(ptr)));

  if (! new_host_list)
    return MEMCACHED_MEMORY_ALLOCATION_FAILURE;

  memcached_server_list_set(ptr, new_host_list);

  for (x= 0; x < count; x++)
  {
    memcached_server_write_instance_st instance;

    if ((ptr->flags.use_udp && list[x].type != MEMCACHED_CONNECTION_UDP)
            || ((list[x].type == MEMCACHED_CONNECTION_UDP)
            && ! (ptr->flags.use_udp)) )
      return MEMCACHED_INVALID_HOST_PROTOCOL;

    WATCHPOINT_ASSERT(list[x].hostname[0] != 0);

    instance= memcached_server_instance_fetch(ptr, memcached_server_count(ptr));

    /* TODO check return type */
    (void)memcached_server_create_with(ptr, instance, list[x].hostname,
                                       list[x].port, list[x].weight, list[x].type);
    ptr->number_of_hosts++;
  }

  /* Provides backwards compatibility with server list. */
  {
    memcached_server_write_instance_st instance;
    instance= memcached_server_instance_fetch(ptr, 0);
    instance->number_of_hosts= memcached_server_count(ptr);
  }

  return run_distribution(ptr);
}
Ejemplo n.º 3
0
memcached_server_list_st 
memcached_server_list_append_with_weight(memcached_server_list_st ptr,
                                         const char *hostname, in_port_t port,
                                         uint32_t weight,
                                         memcached_return_t *error)
{
  uint32_t count;
  memcached_server_list_st new_host_list;

  if (hostname == NULL || error == NULL)
    return NULL;

  if (! port)
    port= MEMCACHED_DEFAULT_PORT;

  /* Increment count for hosts */
  count= 1;
  if (ptr != NULL)
  {
    count+= memcached_server_list_count(ptr);
  }

  new_host_list= (memcached_server_write_instance_st)realloc(ptr, sizeof(memcached_server_st) * count);
  if (!new_host_list)
  {
    *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
    return NULL;
  }

  /* TODO: Check return type */
  memcached_server_create_with(NULL, &new_host_list[count-1], hostname, port, weight, MEMCACHED_CONNECTION_TCP);

  /* Backwards compatibility hack */
  memcached_servers_set_count(new_host_list, count);

  *error= MEMCACHED_SUCCESS;
  return new_host_list;
}
Ejemplo n.º 4
0
void server_startup(server_startup_st *construct)
{
  unsigned int x;

  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 (x= 0; x < construct->count; x++)
      {
        char buffer[1024]; /* Nothing special for number */
        int count;
        int status;

        sprintf(buffer, "/tmp/%umemc.pid", x);
        if (access(buffer, F_OK) == 0)
        {
          FILE *fp= fopen(buffer, "r");
          remove(buffer);

          if (fp != NULL)
          {
            if (fgets(buffer, sizeof(buffer), fp) != NULL)
            {
              pid_t pid = atol(buffer);
              if (pid != 0)
                kill(pid, SIGTERM);
            }

            fclose(fp);
          }
        }

        if (x == 0)
        {
          sprintf(buffer, "%s -d -P /tmp/%umemc.pid -t 1 -p %u -U %u -m 128",
                    MEMCACHED_BINARY, x, x + TEST_PORT_BASE, x + TEST_PORT_BASE);
        }
        else
        {
          sprintf(buffer, "%s -d -P /tmp/%umemc.pid -t 1 -p %u -U %u",
                    MEMCACHED_BINARY, x, x + TEST_PORT_BASE, x + TEST_PORT_BASE);
        }
        fprintf(stderr, "STARTING SERVER: %s\n", buffer);
        status= system(buffer);
        count= sprintf(end_ptr, "localhost:%u,", x + TEST_PORT_BASE);
        end_ptr+= count;
      }
      *end_ptr= 0;

      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(time(NULL));

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

  printf("\n");
}
Ejemplo n.º 5
0
pr_memcache_t *pr_memcache_conn_new(pool *p, module *m, unsigned long flags,
    uint64_t nreplicas) {
  pr_memcache_t *mcache;
  pool *sub_pool;
  memcached_st *mc;
  memcached_return res;

  if (p == NULL) {
    errno = EINVAL;
    return NULL;
  }

  if (configured_server_list == NULL) {
    pr_trace_msg(trace_channel, 9, "%s",
      "unable to create new memcache connection: No servers configured");
    errno = EPERM;
    return NULL;
  }

  mc = memcached_create(NULL);
  if (mc == NULL) {
    errno = ENOMEM;
    return NULL;
  }

  res = memcached_server_push(mc, configured_server_list); 
  if (res != MEMCACHED_SUCCESS) {
    unsigned int count;

    count = memcached_server_list_count(configured_server_list);
    pr_trace_msg(trace_channel, 2,
      "error adding %u memcached %s to connection: %s",
      count, count != 1 ? "servers" : "server", memcached_strerror(mc, res));
    memcached_free(mc);

    errno = EPERM;
    return NULL;
  }

  sub_pool = make_sub_pool(p);
  pr_pool_tag(sub_pool, "Memcache connection pool");

  mcache = pcalloc(sub_pool, sizeof(pr_memcache_t));
  mcache->pool = sub_pool;
  mcache->owner = m;
  mcache->mc = mc;
  mcache->refcount = 1;

  /* The namespace table is null; it will be created if/when callers
   * configure namespace prefixes.
   */
  mcache->namespace_tab = NULL;

  /* Set some of the desired behavior flags on the connection */
  if (mcache_set_options(mcache, flags, nreplicas) < 0) {
    int xerrno = errno;

    pr_memcache_conn_close(mcache);
    destroy_pool(mcache->pool);

    errno = xerrno;
    return NULL;    
  }

  /* Check that all of the configured servers are alive and usable. */
  if (mcache_ping_servers(mcache) < 0) {
    int xerrno = errno;

    pr_memcache_conn_close(mcache);
    destroy_pool(mcache->pool);

    errno = xerrno;
    return NULL;    
  }

  /* Make sure we are connected to the configured servers by querying
   * some stats/info from them.
   */
  if (mcache_stat_servers(mcache) < 0) {
    int xerrno = errno;

    pr_memcache_conn_close(mcache);
    destroy_pool(mcache->pool);

    errno = xerrno;
    return NULL;    
  }

  if (sess_mcache == NULL) {
    sess_mcache = mcache;
  }

  return mcache;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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");
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
void server_startup(server_startup_st *construct)
{
  unsigned int x;

  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 (x= 0; x < construct->count; x++)
      {
        char buffer[1024]; /* Nothing special for number */
        int count;
        int status;

        if (construct->udp){
          if(x == 0) {
            sprintf(buffer, "memcached -d -P /tmp/%umemc.pid -t 1 -U %u -m 128", x, x+ TEST_PORT_BASE);
          } else {
            sprintf(buffer, "memcached -d -P /tmp/%umemc.pid -t 1 -U %u", x, x+ TEST_PORT_BASE);
          }
        }
        else{
          if(x == 0) {
            sprintf(buffer, "memcached -d -P /tmp/%umemc.pid -t 1 -p %u -m 128", x, x+ TEST_PORT_BASE);
          } else {
            sprintf(buffer, "memcached -d -P /tmp/%umemc.pid -t 1 -p %u", x, x+ TEST_PORT_BASE);
          }
        }
        status= system(buffer);
        count= sprintf(end_ptr, "localhost:%u,", x + TEST_PORT_BASE);
        end_ptr+= count;
      }
      *end_ptr= 0;

      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(time(NULL));

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

  printf("\n");
}