* XXX: selected by some kind of heuristics based on size, lifetime
* XXX: etc etc. For now we support only one.
*/
-extern struct stevedore *stevedore;
+extern struct stevedore_head *stevedore_h;
/* -------------------------------------------------------------------*/
#include "shmlog.h"
#include "cache.h"
-struct stevedore *stevedore;
+struct stevedore_head *stevedore_h;
/*--------------------------------------------------------------------
* XXX: Think more about which order we start things
void
child_main(void)
{
+ struct stevedore *st;
setbuf(stdout, NULL);
setbuf(stderr, NULL);
HSH_Init();
BAN_Init();
- stevedore = heritage.stevedore;
- if (stevedore->open != NULL)
- stevedore->open(stevedore);
+ stevedore_h = &heritage.stevedore_h;
+ TAILQ_FOREACH(st, stevedore_h, stevedore_list) {
+ if (st->open != NULL)
+ st->open(st);
+ }
printf("Ready\n");
VSL_stats->start_time = (time_t)TIM_real();
};
TAILQ_HEAD(listen_sock_head, listen_sock);
+TAILQ_HEAD(stevedore_head, stevedore);
struct heritage {
unsigned vsl_size;
/* Storage method */
- struct stevedore *stevedore;
+ struct stevedore_head stevedore_h;
/* Hash method */
struct hash_slinger *hash;
* $Id$
*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "cache.h"
+#include "heritage.h"
+
+extern struct stevedore sma_stevedore;
+extern struct stevedore smf_stevedore;
+
struct storage *
STV_alloc(size_t size)
{
struct storage *st;
+ struct stevedore *stv, *stv_first;
- AN(stevedore);
- AN(stevedore->alloc);
+ /* Simple round robin selecting of a stevedore.
+ */
+ stv_first = TAILQ_FIRST(stevedore_h);
+ stv = stv_first;
+ do {
+ AN(stv->alloc);
+ st = stv->alloc(stv, size);
+ TAILQ_REMOVE(stevedore_h, stv, stevedore_list);
+ TAILQ_INSERT_TAIL(stevedore_h, stv, stevedore_list);
+ if (st != NULL)
+ return (st);
+ } while ((stv = TAILQ_FIRST(stevedore_h)) != stv_first);
+
+ /* No stevedore with enough space is found. Make room in the first
+ * one in the list, and move it to the end. Ensuring the round-robin.
+ */
+ stv = TAILQ_FIRST(stevedore_h);
+ TAILQ_REMOVE(stevedore_h, stv, stevedore_list);
+ TAILQ_INSERT_TAIL(stevedore_h, stv, stevedore_list);
+
do {
- if ((st = stevedore->alloc(stevedore, size)) == NULL)
+ if ((st = stv->alloc(stv, size)) == NULL)
AN(LRU_DiscardOne());
} while (st == NULL);
+
return (st);
}
{
AN(st->stevedore);
- AN(stevedore->free);
+ AN(st->stevedore->free);
st->stevedore->free(st);
}
+
+static int
+cmp_storage(struct stevedore *s, const char *p, const char *q)
+{
+ if (strlen(s->name) != q - p)
+ return (1);
+ if (strncmp(s->name, p, q - p))
+ return (1);
+ return (0);
+}
+
+
+void
+STV_add(const char *spec)
+{
+ const char *p, *q;
+ struct stevedore *stp;
+
+ p = strchr(spec, ',');
+ if (p == NULL)
+ q = p = strchr(spec, '\0');
+ else
+ q = p + 1;
+ xxxassert(p != NULL);
+ xxxassert(q != NULL);
+
+ stp = malloc(sizeof *stp);
+
+ if (!cmp_storage(&sma_stevedore, spec, p)) {
+ *stp = sma_stevedore;
+ } else if (!cmp_storage(&smf_stevedore, spec, p)) {
+ *stp = smf_stevedore;
+ } else {
+ fprintf(stderr, "Unknown storage method \"%.*s\"\n",
+ (int)(p - spec), spec);
+ exit (2);
+ }
+ TAILQ_INSERT_HEAD(&heritage.stevedore_h, stp, stevedore_list);
+ if (stp->init != NULL)
+ stp->init(stp, q);
+}
*
* $Id$
*/
+
+
+#include "queue.h"
struct stevedore;
struct sess;
/* private fields */
void *priv;
+ TAILQ_ENTRY(stevedore) stevedore_list;
};
struct storage *STV_alloc(size_t size);
void STV_trim(struct storage *st, size_t size);
void STV_free(struct storage *st);
+void STV_add(const char *spec);
/*--------------------------------------------------------------------*/
-static int
-cmp_storage(struct stevedore *s, const char *p, const char *q)
-{
- if (strlen(s->name) != q - p)
- return (1);
- if (strncmp(s->name, p, q - p))
- return (1);
- return (0);
-}
-
-static void
-setup_storage(const char *s_arg)
-{
- const char *p, *q;
- struct stevedore *stp;
-
- p = strchr(s_arg, ',');
- if (p == NULL)
- q = p = strchr(s_arg, '\0');
- else
- q = p + 1;
- xxxassert(p != NULL);
- xxxassert(q != NULL);
- if (!cmp_storage(&sma_stevedore, s_arg, p)) {
- stp = &sma_stevedore;
- } else if (!cmp_storage(&smf_stevedore, s_arg, p)) {
- stp = &smf_stevedore;
- } else {
- fprintf(stderr, "Unknown storage method \"%.*s\"\n",
- (int)(p - s_arg), s_arg);
- exit (2);
- }
- heritage.stevedore = malloc(sizeof *heritage.stevedore);
- *heritage.stevedore = *stp;
- if (stp->init != NULL)
- stp->init(heritage.stevedore, q);
-}
-
-/*--------------------------------------------------------------------*/
-
static void
usage(void)
{
const char *n_arg = NULL;
const char *P_arg = NULL;
const char *s_arg = "file";
+ int s_arg_given = 0;
const char *T_arg = NULL;
char *p;
struct cli cli[1];
cli[0].result = CLIS_OK;
TAILQ_INIT(&heritage.socks);
+ TAILQ_INIT(&heritage.stevedore_h);
+
mgt_vcc_init();
MCF_ParamInit(cli);
cli_check(cli);
break;
case 's':
- s_arg = optarg;
+ s_arg_given = 1;
+ STV_add(optarg);
break;
case 't':
MCF_ParamSet(cli, "default_ttl", optarg);
if (C_flag)
exit (0);
- setup_storage(s_arg);
+ if (!s_arg_given)
+ STV_add(s_arg);
+
setup_hash(h_arg);
VSL_MgtInit(SHMLOG_FILENAME, 8*1024*1024);