This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project iwhd.git.
The branch, dyn-provider has been created at 7b312ae175275f44da7922103c28220c85dbb55e (commit)
- Log ----------------------------------------------------------------- http://repo.or.cz/w/iwhd.git/commit/7b312ae175275f44da7922103c28220c85dbb55e
commit 7b312ae175275f44da7922103c28220c85dbb55e Author: Jim Meyering meyering@redhat.com Date: Thu Dec 23 22:04:41 2010 +0100
remove functions and struct members that are no longer needed
* rest.c (free_ms): Remove function and all uses. * setup.c (delete_provider): Remove function and sole use. * setup.h (refcnt): Remove struct member and all uses. * state_defs.h (cleanup, refcnt): Remove struct members. Remove all uses. * replica.c: Remove uses of the above.
diff --git a/replica.c b/replica.c index 1910747..266da20 100644 --- a/replica.c +++ b/replica.c @@ -205,7 +205,6 @@ repl_worker (void *notused ATTRIBUTE_UNUSED) error(0,0,"bad repl type %d (url=%s) skipped", item->type, item->path); } - free_ms(item->ms); free(item->path); free(item); /* No atomic dec without test? Lame. */ @@ -338,7 +337,6 @@ replicate (const char *url, size_t size, const char *policy, my_state *ms) item->server = prov; item->size = size; item->ms = ms; - g_atomic_int_inc(&ms->refcnt); pthread_mutex_lock(&queue_lock); if (queue_tail) { item->next = queue_tail->next; @@ -388,7 +386,6 @@ replicate_namespace_action (const char *name, repl_t action, my_state *ms) } item->server = (provider_t *)value; item->ms = ms; - g_atomic_int_inc(&ms->refcnt); pthread_mutex_lock(&queue_lock); if (queue_tail) { item->next = queue_tail->next; diff --git a/rest.c b/rest.c index 059d7bf..dfa84b4 100644 --- a/rest.c +++ b/rest.c @@ -75,44 +75,6 @@ static const char *const (reserved_name[]) = {"_default", "_new", "_policy", "_q static const char *const (reserved_attr[]) = {"_bucket", "_date", "_etag", "_key", "_loc", "_size", NULL}; static const char *const (reserved_bucket_name[]) = {"_new", "_providers", NULL};
-void -free_ms (my_state *ms) -{ - if (!g_atomic_int_dec_and_test(&ms->refcnt)) { - return; - } - - if (ms->cleanup & CLEANUP_BUF_PTR) { - free(ms->pipe.data_ptr); - } - - if (ms->cleanup & CLEANUP_POST) { - MHD_destroy_post_processor(ms->post); - } - - if (ms->cleanup & CLEANUP_DICT) { - g_hash_table_destroy(ms->dict); - } - - if (ms->cleanup & CLEANUP_QUERY) { - meta_query_stop(ms->query); - } - - if (ms->cleanup & CLEANUP_TMPL) { - free(ms->gen_ctx); - } - - if (ms->cleanup & CLEANUP_URL) { - free(ms->url); - } - - if (ms->cleanup & CLEANUP_AQUERY) { - meta_attr_stop(ms->aquery); - } - - free(ms); -} - static int validate_put (struct MHD_Connection *conn) { @@ -203,7 +165,6 @@ simple_closer (void *ctx) my_state *ms = ctx;
DPRINTF("%s: cleaning upn",__func__); - free_ms(ms); }
static void @@ -266,7 +227,6 @@ proxy_get_cons (void *ctx, uint64_t pos, char *buf, size_t max) pthread_join(ms->cache_th,NULL); /* TBD: do something about cache failure? */ } - free_ms(ms); }
return done; @@ -297,7 +257,6 @@ proxy_get_data (void *cctx, struct MHD_Connection *conn, const char *url, if (!ms->url) { return MHD_NO; } - ms->cleanup |= CLEANUP_URL;
my_etag = meta_has_copy(ms->bucket,ms->key,me); if (!my_etag) { @@ -326,7 +285,6 @@ proxy_get_data (void *cctx, struct MHD_Connection *conn, const char *url, MHD_NO,MHD_NO); MHD_queue_response(conn,MHD_HTTP_NOT_FOUND,resp); MHD_destroy_response(resp); - free_ms(ms); return MHD_YES; } DPRINTF(" will fetch from %s:%un", master_host,master_port); @@ -448,7 +406,6 @@ proxy_put_data (void *cctx, struct MHD_Connection *conn, const char *url, } MHD_queue_response(conn,MHD_HTTP_FORBIDDEN,resp); MHD_destroy_response(resp); - free_ms(ms); return MHD_YES; } ms->state = MS_NORMAL; @@ -456,7 +413,6 @@ proxy_put_data (void *cctx, struct MHD_Connection *conn, const char *url, if (!ms->url) { return MHD_NO; } - ms->cleanup |= CLEANUP_URL; ms->size = 0; pipe_init_shared(&ms->pipe,ms,1); pp = pipe_init_private(&ms->pipe); @@ -539,7 +495,6 @@ proxy_put_data (void *cctx, struct MHD_Connection *conn, const char *url, recheck_replication(ms,NULL); rc = MHD_HTTP_OK; } - free_ms(ms); resp = MHD_create_response_from_data(0,NULL,MHD_NO,MHD_NO); if (!resp) { free(etag); @@ -587,7 +542,6 @@ proxy_get_attr (void *cctx, struct MHD_Connection *conn, const char *url, MHD_queue_response(conn,rc,resp); MHD_destroy_response(resp);
- free_ms(ms); return MHD_YES; }
@@ -613,7 +567,6 @@ proxy_put_attr (void *cctx, struct MHD_Connection *conn, const char *url, if (!ms->url) { return MHD_NO; } - ms->cleanup |= CLEANUP_URL; attrval = MHD_lookup_connection_value(conn,MHD_HEADER_KIND, "X-redhat-value"); if (attrval) { @@ -638,7 +591,6 @@ proxy_put_attr (void *cctx, struct MHD_Connection *conn, const char *url, return MHD_NO; } ((char *)ms->pipe.data_ptr)[0] = '0'; - ms->cleanup |= CLEANUP_BUF_PTR; } (void)strncat(ms->pipe.data_ptr,data,*data_size); /* TBD: check return value */ @@ -657,22 +609,15 @@ proxy_put_attr (void *cctx, struct MHD_Connection *conn, const char *url, MHD_queue_response(conn,MHD_HTTP_BAD_REQUEST, resp); MHD_destroy_response(resp); - free_ms(ms); return MHD_YES; } meta_set_value(ms->bucket,ms->key,ms->attr,ms->pipe.data_ptr); - /* This might get stomped by replication. */ - if (ms->cleanup & CLEANUP_BUF_PTR) { - free(ms->pipe.data_ptr); - ms->cleanup &= ~CLEANUP_BUF_PTR; - } /* * We should always re-replicate, because the replication * policy might refer to this attr. */ DPRINTF("rereplicate (attr PUT)n"); recheck_replication(ms,NULL); - free_ms(ms); send_resp = 1; }
@@ -744,7 +689,6 @@ proxy_query_func (void *ctx, uint64_t pos, char *buf, size_t max) if (!ms->gen_ctx) { return -1; } - ms->cleanup |= CLEANUP_TMPL; len = tmpl_list_header(ms->gen_ctx); if (!len) { return -1; @@ -787,7 +731,6 @@ proxy_query_func (void *ctx, uint64_t pos, char *buf, size_t max) } memcpy(buf,ms->gen_ctx->buf,len); free(ms->gen_ctx); - ms->cleanup &= ~CLEANUP_TMPL; ms->gen_ctx = TMPL_CTX_DONE; return len; } @@ -810,7 +753,6 @@ proxy_query (void *cctx, struct MHD_Connection *conn, const char *url, ms->state = MS_NORMAL; ms->post = MHD_create_post_processor(conn,4096, query_iterator,ms); - ms->cleanup |= CLEANUP_POST; } else if (*data_size) { MHD_post_process(ms->post,data,*data_size); @@ -829,7 +771,6 @@ proxy_query (void *cctx, struct MHD_Connection *conn, const char *url, return MHD_NO; } ((char *)ms->pipe.data_ptr)[0] = '0'; - ms->cleanup |= CLEANUP_BUF_PTR; } (void)strncat(ms->pipe.data_ptr,data,*data_size); /* TBD: check return value */ @@ -840,7 +781,6 @@ proxy_query (void *cctx, struct MHD_Connection *conn, const char *url, return MHD_NO; } ms->query = meta_query_new(ms->bucket,NULL,ms->pipe.data_ptr); - ms->cleanup |= CLEANUP_QUERY; resp = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 65536, proxy_query_func, ms, simple_closer); if (!resp) { @@ -850,7 +790,6 @@ proxy_query (void *cctx, struct MHD_Connection *conn, const char *url, } MHD_queue_response(conn,MHD_HTTP_OK,resp); MHD_destroy_response(resp); - free_ms(ms); }
return MHD_YES; @@ -872,7 +811,6 @@ proxy_list_objs (void *cctx, struct MHD_Connection *conn, const char *url, (void)data_size;
ms->query = meta_query_new((char *)ms->bucket,NULL,NULL); - ms->cleanup |= CLEANUP_QUERY;
resp = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 65536, proxy_query_func, ms, simple_closer); @@ -925,14 +863,12 @@ proxy_delete (void *cctx, struct MHD_Connection *conn, const char *url,
resp = MHD_create_response_from_data(0,NULL,MHD_NO,MHD_NO); if (!resp) { - free_ms(ms); return MHD_NO; } error (0, 0, "DELETE BUCKET: rc=%d", rc); MHD_queue_response(conn,rc,resp); MHD_destroy_response(resp);
- free_ms(ms); return MHD_YES; }
@@ -971,7 +907,6 @@ root_blob_generator (void *ctx, uint64_t pos, char *buf, size_t max) if (!ms->gen_ctx) { return -1; } - ms->cleanup |= CLEANUP_TMPL; ms->gen_ctx->base = host; len = tmpl_root_header(ms->gen_ctx,"image_warehouse",VERSION); if (!len) { @@ -1022,7 +957,6 @@ root_blob_generator (void *ctx, uint64_t pos, char *buf, size_t max) } memcpy(buf,ms->gen_ctx->buf,len); free(ms->gen_ctx); - ms->cleanup &= ~CLEANUP_TMPL; ms->gen_ctx = TMPL_CTX_DONE; return len; } @@ -1045,11 +979,8 @@ proxy_api_root (void *cctx, struct MHD_Connection *conn, const char *url,
ms->query = meta_query_new(NULL,"_default",NULL); if (!ms->query) { - free_ms(ms); return MHD_NO; } - ms->cleanup |= CLEANUP_QUERY; - resp = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 65536, root_blob_generator, ms, simple_closer); if (!resp) { @@ -1188,10 +1119,8 @@ control_api_root (void *cctx, struct MHD_Connection *conn, const char *url, ms->url = (char *)url; ms->dict = g_hash_table_new_full( g_str_hash,g_str_equal,NULL,NULL); - ms->cleanup |= CLEANUP_DICT; ms->post = MHD_create_post_processor(conn,4096, post_iterator,ms->dict); - ms->cleanup |= CLEANUP_POST; return MHD_YES; }
@@ -1231,7 +1160,6 @@ control_api_root (void *cctx, struct MHD_Connection *conn, const char *url, MHD_queue_response(conn,rc,resp); MHD_destroy_response(resp);
- free_ms(ms); return MHD_YES; }
@@ -1256,10 +1184,8 @@ proxy_bucket_post (void *cctx, struct MHD_Connection *conn, const char *url, ms->url = (char *)url; ms->dict = g_hash_table_new_full( g_str_hash,g_str_equal,NULL,NULL); - ms->cleanup |= CLEANUP_DICT; ms->post = MHD_create_post_processor(conn,4096, post_iterator,ms->dict); - ms->cleanup |= CLEANUP_POST; } else if (*data_size) { MHD_post_process(ms->post,data,*data_size); @@ -1294,7 +1220,6 @@ proxy_bucket_post (void *cctx, struct MHD_Connection *conn, const char *url, } MHD_queue_response(conn,rc,resp); MHD_destroy_response(resp); - free_ms(ms); }
return MHD_YES; @@ -1369,7 +1294,6 @@ parts_callback (void *ctx, uint64_t pos, char *buf, size_t max) if (!ms->gen_ctx) { return -1; } - ms->cleanup |= CLEANUP_TMPL; ms->gen_ctx->base = host; len = tmpl_obj_header(ms->gen_ctx,ms->bucket,ms->key); if (!len) { @@ -1415,7 +1339,6 @@ parts_callback (void *ctx, uint64_t pos, char *buf, size_t max) } memcpy(buf,ms->gen_ctx->buf,len); free(ms->gen_ctx); - ms->cleanup &= ~CLEANUP_TMPL; ms->gen_ctx = TMPL_CTX_DONE; return len; } @@ -1429,7 +1352,6 @@ show_parts (struct MHD_Connection *conn, my_state *ms) if (!ms->aquery) { return MHD_HTTP_NOT_FOUND; } - ms->cleanup |= CLEANUP_AQUERY;
resp = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 65536, parts_callback, ms, simple_closer); @@ -1464,10 +1386,8 @@ proxy_object_post (void *cctx, struct MHD_Connection *conn, const char *url, ms->url = (char *)url; ms->dict = g_hash_table_new_full( g_str_hash,g_str_equal,NULL,NULL); - ms->cleanup |= CLEANUP_DICT; ms->post = MHD_create_post_processor(conn,4096, post_iterator,ms->dict); - ms->cleanup |= CLEANUP_POST; } else if (*data_size) { MHD_post_process(ms->post,data,*data_size); @@ -1511,12 +1431,10 @@ proxy_object_post (void *cctx, struct MHD_Connection *conn, const char *url, MHD_NO,MHD_NO); if (!resp) { fprintf(stderr,"MHD_crfd failedn"); - free_ms(ms); return MHD_NO; } MHD_queue_response(conn,rc,resp); MHD_destroy_response(resp); - free_ms(ms); } }
@@ -1544,7 +1462,6 @@ prov_list_generator (void *ctx, uint64_t pos, char *buf, size_t max) if (!ms->gen_ctx) { return -1; } - ms->cleanup |= CLEANUP_TMPL; init_prov_iter(&ms->prov_iter); len = tmpl_prov_header(ms->gen_ctx); if (!len) { @@ -1585,7 +1502,6 @@ prov_list_generator (void *ctx, uint64_t pos, char *buf, size_t max) } memcpy(buf,ms->gen_ctx->buf,len); free(ms->gen_ctx); - ms->cleanup &= ~CLEANUP_TMPL; ms->gen_ctx = TMPL_CTX_DONE; return len; } @@ -1657,10 +1573,8 @@ proxy_update_prov (void *cctx, struct MHD_Connection *conn, const char *url, ms->url = (char *)url; ms->dict = g_hash_table_new_full( g_str_hash,g_str_equal,NULL,NULL); - ms->cleanup |= CLEANUP_DICT; ms->post = MHD_create_post_processor(conn,4096, prov_iterator,ms->dict); - ms->cleanup |= CLEANUP_POST; } else if (*data_size) { MHD_post_process(ms->post,data,*data_size); @@ -1681,12 +1595,10 @@ proxy_update_prov (void *cctx, struct MHD_Connection *conn, const char *url, resp = MHD_create_response_from_data(0,NULL,MHD_NO,MHD_NO); if (!resp) { fprintf(stderr,"MHD_crfd failedn"); - free_ms(ms); return MHD_NO; } MHD_queue_response(conn,rc,resp); MHD_destroy_response(resp); - free_ms(ms); }
return MHD_YES; @@ -1813,7 +1725,6 @@ proxy_delete_prov (void *cctx, struct MHD_Connection *conn, const char *url, struct MHD_Response *resp = MHD_create_response_from_data(0,NULL,MHD_NO,MHD_NO); if (!resp) { - free_ms(ms); return MHD_NO; }
@@ -1829,19 +1740,13 @@ proxy_delete_prov (void *cctx, struct MHD_Connection *conn, const char *url, DPRINTF("PROXY DELETE PROVIDER prov=%s rc=%dn", prov_name, rc);
if (prov) { - /* Delete for real if no one is using it. - Otherwise, just mark it as deleted. */ - if (g_atomic_int_get (&prov->refcnt) == 0) - delete_provider (prov); - else - prov->deleted = 1; + prov->deleted = 1; }
free (prov_name); MHD_queue_response(conn,rc,resp); MHD_destroy_response(resp);
- free_ms(ms); return MHD_YES; }
@@ -1863,10 +1768,8 @@ proxy_add_prov (void *cctx, struct MHD_Connection *conn, const char *url, ms->url = (char *)url; ms->dict = g_hash_table_new_full( g_str_hash,g_str_equal,NULL,NULL); - ms->cleanup |= CLEANUP_DICT; ms->post = MHD_create_post_processor(conn,4096, prov_iterator,ms->dict); - ms->cleanup |= CLEANUP_POST; } else if (*data_size) { MHD_post_process(ms->post,data,*data_size); @@ -1916,7 +1819,6 @@ proxy_add_prov (void *cctx, struct MHD_Connection *conn, const char *url, } MHD_queue_response(conn,rc,resp); MHD_destroy_response(resp); - free_ms(ms); }
return MHD_YES; @@ -1949,7 +1851,6 @@ proxy_create_bucket (void *cctx, struct MHD_Connection *conn, const char *url, MHD_queue_response(conn,rc,resp); MHD_destroy_response(resp);
- free_ms(ms); return MHD_YES; }
@@ -2077,7 +1978,6 @@ access_handler (void *cctx, struct MHD_Connection *conn, const char *url, if (!ms) { return MHD_NO; } - ms->refcnt = 1;
utype = parse_url(url,ms);
@@ -2101,9 +2001,6 @@ access_handler (void *cctx, struct MHD_Connection *conn, const char *url, data,data_size,rctx); }
- /* Don't need this after all. Free before the next check. */ - free_ms(ms); - if (!strcmp(method,"QUIT")) { (void)sem_post((sem_t *)cctx); return MHD_NO; diff --git a/setup.c b/setup.c index b3173ff..505c9cb 100644 --- a/setup.c +++ b/setup.c @@ -331,7 +331,6 @@ convert_provider (int i, provider_t *out)
out->token = NULL; out->deleted = 0; - out->refcnt = 0;
return 1; } @@ -595,19 +594,6 @@ find_provider (const char *name) return p; }
-void -delete_provider (provider_t *prov) -{ - // Remove from prov_hash, then free - - g_hash_table_destroy(prov->attrs); - // FIXME: free other members, too? - - // FIXME: unchecked strdup - char *name = strdup (prov->name); - g_hash_table_remove(prov_hash, prov->name); -} - const char * get_provider_value (const provider_t *prov, const char *fname) { diff --git a/setup.h b/setup.h index 54a4ca3..fb50944 100644 --- a/setup.h +++ b/setup.h @@ -27,7 +27,6 @@ typedef struct _provider { const char *host; int port; int deleted; - gint refcnt; const char *username; const char *password; const char *path; @@ -51,7 +50,6 @@ const char *auto_config (void); int validate_provider (GHashTable *h); provider_t *find_provider (const char *name); int add_provider (GHashTable *h); -void delete_provider (provider_t *prov); provider_t *get_main_provider (void); void set_main_provider (provider_t *prov);
diff --git a/state_defs.h b/state_defs.h index 1443236..a35cd8d 100644 --- a/state_defs.h +++ b/state_defs.h @@ -44,8 +44,6 @@ typedef struct { } backend_thunk_t;
typedef struct _my_state { - volatile gint refcnt; - int cleanup; /* for everyone */ MHD_AccessHandlerCallback handler; ms_state state; @@ -90,6 +88,4 @@ typedef struct _my_state {
#define BACKEND_GET_SIZE 0x01 /* used in put_child_func */
-void free_ms (my_state *ms); - #endif
http://repo.or.cz/w/iwhd.git/commit/2b64c1ad809e9b657a7a52d8d49e2f3604f526fc
commit 2b64c1ad809e9b657a7a52d8d49e2f3604f526fc Author: Jim Meyering meyering@redhat.com Date: Thu Dec 23 18:36:38 2010 +0100
garbage-collection fix-up
Do not instruct libraries to free things that they do not allocate, since they would use the system "free" function. * setup.c, rest.c: Do not tell g_hash_table_new_full to free anything. * rest.c (proxy_get_attr): Do not tell MHD to free anything.
diff --git a/rest.c b/rest.c index 3585020..059d7bf 100644 --- a/rest.c +++ b/rest.c @@ -316,7 +316,6 @@ proxy_get_data (void *cctx, struct MHD_Connection *conn, const char *url, MHD_destroy_response(resp); return MHD_YES; } - free(my_etag); ms->from_master = 0; } else { @@ -384,7 +383,6 @@ static void recheck_replication (my_state * ms, char *policy) { int rc; - int free_it = FALSE; char fixed[MAX_FIELD_LEN];
if (is_reserved(ms->key,reserved_name)) { @@ -398,8 +396,6 @@ recheck_replication (my_state * ms, char *policy) }
if (!policy) { - /* If we get a policy here or below, we have to free it. */ - free_it = TRUE; DPRINTF("fetching policy for %s/%sn",ms->bucket,ms->key); rc = meta_get_value(ms->bucket,ms->key, "_policy", &policy); } @@ -418,9 +414,6 @@ recheck_replication (my_state * ms, char *policy) */ snprintf(fixed,sizeof(fixed),"%s/%s",ms->bucket,ms->key); replicate(fixed,0,policy,ms); - if (free_it) { - free(policy); - } } else { DPRINTF(" could not find a policy anywhere!n"); @@ -554,7 +547,6 @@ proxy_put_data (void *cctx, struct MHD_Connection *conn, const char *url, } if (etag) { MHD_add_response_header(resp,"ETag",etag); - free(etag); } MHD_queue_response(conn,rc,resp); MHD_destroy_response(resp); @@ -583,7 +575,7 @@ proxy_get_attr (void *cctx, struct MHD_Connection *conn, const char *url,
if (meta_get_value(ms->bucket,ms->key,ms->attr,&fixed) == 0) { resp = MHD_create_response_from_data(strlen(fixed),fixed, - MHD_YES,MHD_NO); + MHD_NO,MHD_NO); rc = MHD_HTTP_OK; } else { @@ -1195,7 +1187,7 @@ control_api_root (void *cctx, struct MHD_Connection *conn, const char *url, ms->state = MS_NORMAL; ms->url = (char *)url; ms->dict = g_hash_table_new_full( - g_str_hash,g_str_equal,free,free); + g_str_hash,g_str_equal,NULL,NULL); ms->cleanup |= CLEANUP_DICT; ms->post = MHD_create_post_processor(conn,4096, post_iterator,ms->dict); @@ -1263,7 +1255,7 @@ proxy_bucket_post (void *cctx, struct MHD_Connection *conn, const char *url, ms->state = MS_NORMAL; ms->url = (char *)url; ms->dict = g_hash_table_new_full( - g_str_hash,g_str_equal,free,free); + g_str_hash,g_str_equal,NULL,NULL); ms->cleanup |= CLEANUP_DICT; ms->post = MHD_create_post_processor(conn,4096, post_iterator,ms->dict); @@ -1471,7 +1463,7 @@ proxy_object_post (void *cctx, struct MHD_Connection *conn, const char *url, ms->state = MS_NORMAL; ms->url = (char *)url; ms->dict = g_hash_table_new_full( - g_str_hash,g_str_equal,free,free); + g_str_hash,g_str_equal,NULL,NULL); ms->cleanup |= CLEANUP_DICT; ms->post = MHD_create_post_processor(conn,4096, post_iterator,ms->dict); @@ -1664,7 +1656,7 @@ proxy_update_prov (void *cctx, struct MHD_Connection *conn, const char *url, ms->state = MS_NORMAL; ms->url = (char *)url; ms->dict = g_hash_table_new_full( - g_str_hash,g_str_equal,free,free); + g_str_hash,g_str_equal,NULL,NULL); ms->cleanup |= CLEANUP_DICT; ms->post = MHD_create_post_processor(conn,4096, prov_iterator,ms->dict); @@ -1870,7 +1862,7 @@ proxy_add_prov (void *cctx, struct MHD_Connection *conn, const char *url, ms->state = MS_NORMAL; ms->url = (char *)url; ms->dict = g_hash_table_new_full( - g_str_hash,g_str_equal,free,free); + g_str_hash,g_str_equal,NULL,NULL); ms->cleanup |= CLEANUP_DICT; ms->post = MHD_create_post_processor(conn,4096, prov_iterator,ms->dict); diff --git a/setup.c b/setup.c index d1daa19..b3173ff 100644 --- a/setup.c +++ b/setup.c @@ -307,7 +307,7 @@ convert_provider (int i, provider_t *out) out->func_tbl = &bad_func_tbl; }
- out->attrs = g_hash_table_new_full(g_str_hash,g_str_equal,free,free); + out->attrs = g_hash_table_new_full(g_str_hash,g_str_equal,NULL,NULL); iter = json_object_iter(server); while (iter) { key = json_object_iter_key(iter); @@ -385,7 +385,7 @@ add_provider (GHashTable *h) else prov->func_tbl = &bad_func_tbl;
- prov->attrs = g_hash_table_new_full(g_str_hash,g_str_equal,free,free); + prov->attrs = g_hash_table_new_full(g_str_hash,g_str_equal,NULL,NULL); // FIXME: can't the above fail?
GHashTableIter iter; @@ -453,7 +453,7 @@ parse_config_inner (void)
/* Everything looks OK. */ printf("%u replication servers definedn",nservers-1); - prov_hash = g_hash_table_new_full(g_str_hash,g_str_equal,free,free); + prov_hash = g_hash_table_new_full(g_str_hash,g_str_equal,NULL,NULL); if (!prov_hash) { error(0,0,"could not allocate provider hash"); goto err;
http://repo.or.cz/w/iwhd.git/commit/ae15a4eabca8853eb16bb4e9df6c235a1ce15b1a
commit ae15a4eabca8853eb16bb4e9df6c235a1ce15b1a Author: Jim Meyering meyering@redhat.com Date: Thu Dec 23 18:17:23 2010 +0100
don't use xstrndup via base_name
* rest.c (url_to_provider_name): Rewrite not to use base_name, since that function uses xstrndup, which exits on OOM.
diff --git a/rest.c b/rest.c index 978ef89..3585020 100644 --- a/rest.c +++ b/rest.c @@ -1703,12 +1703,15 @@ proxy_update_prov (void *cctx, struct MHD_Connection *conn, const char *url, static char * url_to_provider_name (const char *url) { - char *prov_name = base_name (url); - if (prov_name) - strip_trailing_slashes (prov_name); + char *p = strdup (url); + if (p == NULL) + return NULL; + /* Ensure we handle trailing slashes (i.e., remove them). */ - assert (prov_name == NULL - || (*prov_name && prov_name[strlen(prov_name)-1] != '/')); + strip_trailing_slashes (p); + + char *prov_name = strdup (last_component (p)); + free (p); return prov_name; }
http://repo.or.cz/w/iwhd.git/commit/ed0b229107cca6b51adfb1ffb6079a2a23546a75
commit ed0b229107cca6b51adfb1ffb6079a2a23546a75 Author: Jim Meyering meyering@redhat.com Date: Wed Dec 22 17:25:19 2010 +0100
use garbage collection
Add -lgc when linking. * gc-wrap.h: New file, to map malloc, realloc, free, etc. to GC'd equivalents. * iwh.h: Include it. * template.c: Include it. * Makefile.am (iwhd_LDADD): Add -lgc and -lpthread. * t/Makefile.am (parser_LDADD): Likewise. * Makefile.am (iwhd_SOURCES): Add gc-wrap.h. (TESTS): Move the simpler parser-test to precede all others. * iwhd.spec.in (BuildRequires): Require gc-devel. * qparser.y (free_value): Remove function. * meta.cpp, replica.c: Remove all uses. * query.h: Remove declaration. * rest.c (main): Call GC_INIT. * qparser.y (main) [PARSER_UNIT_TEST]: Likewise. * mpipe.c: Include unistd.h here, ... * mpipe.h: ...not here. Don't include the following, either: fcntl.h, stdlib.h, string.h, strings.h, sys/stat.h. They were not used, and got in the way of gc-wrap's redefinitions.
diff --git a/Makefile.am b/Makefile.am index 4360dd4..cbf2fc2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -40,6 +40,7 @@ iwhd_SOURCES = auto.c backend.c backend.h + gc-wrap.h iwh.h meta.cpp meta.h @@ -94,6 +95,7 @@ rpm: dist iwhd.spec iwhd_CPPFLAGS = $(HAIL_CFLAGS) -I$(top_srcdir)/lib iwhd_LDADD = lib/libiwhd.a + -lgc -lpthread -lmongoclient $(BOOST_SYSTEM_LIB) $(BOOST_THREAD_LIB) diff --git a/gc-wrap.h b/gc-wrap.h new file mode 100644 index 0000000..70c4b9d --- /dev/null +++ b/gc-wrap.h @@ -0,0 +1,35 @@ +#include <string.h> +#define GC_THREADS +#include "gc.h" + +#ifndef __cplusplus +# define malloc(n) GC_MALLOC(n) +# define calloc(m,n) GC_MALLOC((m)*(n)) +# define free(p) GC_FREE(p) +# define realloc(p,n) GC_REALLOC((p),(n)) +#endif + +static inline char * +my_strdup (char const *s) +{ + size_t len = strlen (s); + void *t = GC_MALLOC (len + 1); + if (t == NULL) + return NULL; + return (char *) memcpy (t, s, len + 1); +} +# undef strdup +# define strdup(s) my_strdup(s) + +static inline char * +my_strndup (char const *s, size_t n) +{ + size_t len = strnlen (s, n); + char *t = (char *) GC_MALLOC (len + 1); + if (t == NULL) + return NULL; + t[len] = '0'; + return (char *) memcpy (t, s, len); +} +# undef strndup +# define strndup(s, n) my_strndup(s, n) diff --git a/iwh.h b/iwh.h index c862273..b98e6ba 100644 --- a/iwh.h +++ b/iwh.h @@ -69,3 +69,5 @@ GLOBAL(const char *, me, "here"); #define AUTO_MONGOD_PORT 27018
int auto_start (int dbport); + +#include "gc-wrap.h" diff --git a/iwhd.spec.in b/iwhd.spec.in index 2b28b53..eae6086 100644 --- a/iwhd.spec.in +++ b/iwhd.spec.in @@ -17,6 +17,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: boost-devel BuildRequires: boost-filesystem +BuildRequires: gc-devel BuildRequires: glib2-devel BuildRequires: hail-devel BuildRequires: jansson-devel diff --git a/meta.cpp b/meta.cpp index b7ae903..59d4e53 100644 --- a/meta.cpp +++ b/meta.cpp @@ -440,9 +440,6 @@ RepoQuery::RepoQuery (const char *bucket, const char *key, const char *qstr, RepoQuery::~RepoQuery () { cout << "in " << __func__ << endl; - if (expr) { - free_value(expr); - }
delete curs; } diff --git a/mpipe.c b/mpipe.c index 46b3ad2..8272168 100644 --- a/mpipe.c +++ b/mpipe.c @@ -15,6 +15,7 @@
#include <config.h> #include <assert.h> +#include <unistd.h>
#include "iwh.h" #include "mpipe.h" diff --git a/mpipe.h b/mpipe.h index 9d0f795..cf0ec72 100644 --- a/mpipe.h +++ b/mpipe.h @@ -16,17 +16,11 @@ #if !defined(_MPIPE_H) #define _MPIPE_H
-#include <fcntl.h> #include <poll.h> #include <pthread.h> #include <semaphore.h> #include <stdint.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <unistd.h> -#include <sys/stat.h>
/* * This is an in-memory "pipe" construct with a twist: it lets you have diff --git a/qparser.y b/qparser.y index 64f025a..8ef7fe0 100644 --- a/qparser.y +++ b/qparser.y @@ -387,41 +387,6 @@ print_value (const value_t *v) _print_value(v,0); }
-void -free_value (value_t *v) -{ - if (v == NULL || v == &invalid) { - return; - } - - free((void *)v->resolved); - - switch (v->type) { - case T_STRING: - case T_OFIELD: - case T_SFIELD: - case T_ID: - free(v->as_str); - free(v); - break; - case T_LINK: - free_value(v->as_tree.left); - free(v->as_tree.right); - free(v); - break; - case T_COMP: - case T_AND: - case T_OR: - free_value(v->as_tree.right); - /* Fall through. */ - case T_NOT: - free_value(v->as_tree.left); - /* Fall through. */ - default: - free(v); - } -} - #include "qlexer.c"
value_t * @@ -433,8 +398,6 @@ parse (const char *text) YY_BUFFER_STATE buf = yy_scan_string (text, scanner); value_t *result = NULL; value_t *r = yyparse (scanner, &result) == 0 ? result : NULL; - if (r == NULL) - free_value (result); yy_delete_buffer (buf, scanner); yylex_destroy (scanner); return r; @@ -644,6 +607,7 @@ main (int argc, char **argv) { int fail = 0; unsigned int i; + GC_INIT (); for (i = 1; i < argc; ++i) { value_t *expr = parse (argv[i]); @@ -651,7 +615,7 @@ main (int argc, char **argv) { printf ("could not parse '%s'n", argv[i]); fail = 1; - goto next; + continue; }
print_value (expr); @@ -660,12 +624,9 @@ main (int argc, char **argv) if (str) { printf ("s= %sn", str); - goto next; + continue; } printf ("d= %dn", eval (expr, &unit_oget, &unit_sget)); - - next: - free_value (expr); }
return fail; diff --git a/query.h b/query.h index 523dd91..de42d80 100644 --- a/query.h +++ b/query.h @@ -69,9 +69,9 @@ typedef struct { #define CALL_GETTER(g,x) g->func(g->ctx,x)
/* - * In the normal case a caller would invoke parse once, eval multiple times, - * and free_value once. print_value is just for debugging/testing. - * TBD: make parse reentrant (eval already is, free_value doesn't need to be. + * In the normal case a caller would invoke parse once and eval multiple times. + * print_value is just for debugging/testing. + * TBD: make parse reentrant (eval already is). * Unfortunately, a quick scan of generated code and information on the web * seems to indicate that even a "reentrant" bison parser only encapsulates * user state and still relies quite a bit on internal globals. That might @@ -79,7 +79,6 @@ typedef struct { */ int eval (const value_t *expr, const getter_t *oget, const getter_t *sget); -void free_value (value_t *); void print_value (const value_t *);
value_t *parse (const char *text); diff --git a/replica.c b/replica.c index 301c8d3..1910747 100644 --- a/replica.c +++ b/replica.c @@ -354,9 +354,6 @@ replicate (const char *url, size_t size, const char *policy, my_state *ms) sem_post(&queue_sema); }
- if (expr) { - free_value(expr); - } free(url2); }
diff --git a/rest.c b/rest.c index 972c2fc..978ef89 100644 --- a/rest.c +++ b/rest.c @@ -2193,6 +2193,7 @@ main (int argc, char **argv)
set_program_name (argv[0]); atexit (close_stdout); + GC_INIT ();
for (;;) switch (getopt_long(argc,argv,"ac:d:m:p:v",my_options,NULL)) { case 'a': diff --git a/t/Makefile.am b/t/Makefile.am index 87fe3e4..0b3d100 100644 --- a/t/Makefile.am +++ b/t/Makefile.am @@ -15,9 +15,9 @@ # along with this program. If not, see http://www.gnu.org/licenses/.
TESTS = + parser-test basic replication - parser-test auto
EXTRA_DIST = @@ -31,7 +31,7 @@ BUILT_SOURCES = BUILT_SOURCES += parser.c MAINTAINERCLEANFILES = $(BUILT_SOURCES) parser_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -parser_LDADD = -L../lib -liwhd +parser_LDADD = -L../lib -liwhd -lgc -lpthread
parser.c: Makefile.am rm -f $@-t $@ diff --git a/template.c b/template.c index 2d49e2c..1b78bf4 100644 --- a/template.c +++ b/template.c @@ -19,6 +19,7 @@ #include <stdlib.h> #include <string.h> #include "template.h" +#include "gc-wrap.h"
static const char xml_root_header[] = " <api service="%s" version="%s"> http://repo.or.cz/w/iwhd.git/commit/2d99e43fee5f7af7f6ec6fd238ee900f9fb103aa
commit 2d99e43fee5f7af7f6ec6fd238ee900f9fb103aa Author: Jim Meyering meyering@redhat.com Date: Sat Dec 18 11:08:25 2010 +0100
maint: rename file-scoped global s/main_prov/g_main_prov/, and...
* setup.c (g_main_prov): Rename from main_prov, to avoid confusion between this file-scoped global and the locals of the same name in other compilation units. (g_master_prov): Rename from master_prov, for consistency. Though this one is truly global... * setup.h (g_master_prov): Update here,... * rest.c (g_master_prov): ...and here.
diff --git a/rest.c b/rest.c index b58f1bc..972c2fc 100644 --- a/rest.c +++ b/rest.c @@ -341,7 +341,7 @@ proxy_get_data (void *cctx, struct MHD_Connection *conn, const char *url, } provider_t *main_prov = get_main_provider(); ms->thunk.parent = ms; - ms->thunk.prov = ms->from_master ? master_prov : main_prov; + ms->thunk.prov = ms->from_master ? g_master_prov : main_prov; pthread_create(&ms->backend_th,NULL, ms->thunk.prov->func_tbl->get_child_func,&ms->thunk); /* TBD: check return value */ diff --git a/setup.c b/setup.c index 6ae5f01..d1daa19 100644 --- a/setup.c +++ b/setup.c @@ -69,19 +69,19 @@ extern backend_func_tbl fs_func_tbl; static json_t *config = NULL; static GHashTable *prov_hash = NULL;
-static provider_t *main_prov = NULL; -provider_t *master_prov = NULL; +static provider_t *g_main_prov = NULL; +provider_t *g_master_prov = NULL;
provider_t * get_main_provider (void) { - return main_prov; + return g_main_prov; }
void set_main_provider (provider_t *prov) { - main_prov = prov; + g_main_prov = prov; }
int @@ -482,7 +482,7 @@ parse_config_inner (void) } g_hash_table_insert(prov_hash,(char *)new_key,new_prov); if (!i) { - main_prov = new_prov; + g_main_prov = new_prov; primary = new_prov->name; } new_prov->func_tbl->init_func(new_prov); @@ -511,10 +511,10 @@ parse_config (char *cfg_file) * TBD: initialize this in a separate module-init function, passing * in master_host and master_port instead of using globals. */ - if (!master_prov) { - master_prov = malloc(sizeof(*master_prov)); - if (master_prov) { - master_prov->func_tbl = &curl_func_tbl; + if (!g_master_prov) { + g_master_prov = malloc(sizeof(*g_master_prov)); + if (g_master_prov) { + g_master_prov->func_tbl = &curl_func_tbl; } }
diff --git a/setup.h b/setup.h index 0bfbb81..54a4ca3 100644 --- a/setup.h +++ b/setup.h @@ -36,7 +36,7 @@ typedef struct _provider { char *token; } provider_t;
-provider_t *master_prov; +provider_t *g_master_prov;
const char *parse_config (char *); provider_t *get_provider (const char *name);
http://repo.or.cz/w/iwhd.git/commit/9bc8fc19e7d70de1fe8968bf2b844ee9c15b3574
commit 9bc8fc19e7d70de1fe8968bf2b844ee9c15b3574 Author: Jim Meyering meyering@redhat.com Date: Sat Dec 18 10:47:58 2010 +0100
rename a URL API component: s/_set_primary/_primary/
Suggested by Jeff Darcy.
diff --git a/rest.c b/rest.c index be4a888..b58f1bc 100644 --- a/rest.c +++ b/rest.c @@ -1762,7 +1762,7 @@ proxy_set_primary (void *cctx, struct MHD_Connection *conn, const char *url, char *name = NULL; unsigned int rc = MHD_HTTP_BAD_REQUEST;
- /* URL is guaranteed to be of the form "/_providers/NAME/_set_primary" + /* URL is guaranteed to be of the form "/_providers/NAME/_primary" Extract NAME: */ bool valid = memcmp (url, "/_providers/", strlen("/_providers/")) == 0; if (!valid) { @@ -2055,7 +2055,7 @@ parse_url (const char *url, my_state *ms) eindex = URL_PROVIDER; else if (eindex == URL_ATTR && !strcmp (parts[URL_BUCKET], "_providers") - && !strcmp (parts[URL_ATTR], "_set_primary")) + && !strcmp (parts[URL_ATTR], "_primary")) eindex = URL_PROVIDER_SET_PRIMARY;
DPRINTF("parse_url: %d: %s %s %s", eindex, parts[URL_BUCKET], diff --git a/t/basic b/t/basic index 436f123..a2f91ca 100644 --- a/t/basic +++ b/t/basic @@ -366,7 +366,7 @@ curl http://localhost:$port/_primary > p || fail=1 grep _primary p && { warn_ add-provider/reserved-name not rejected; fail=1; }
# Move the "primary" attribute to a different provider. -curl -X PUT $p1_url/_set_primary > p || fail=1 +curl -X PUT $p1_url/_primary > p || fail=1 test -s p && fail=1 new_primary=$(curl http://localhost:$port/_providers/_primary) || fail=1 test $new_primary = PROVIDER-1 || fail=1 @@ -375,7 +375,7 @@ test $new_primary = PROVIDER-1 || fail=1 # FIXME: if I don't restore, the following headless test makes iwhd segfault. # Investigate that. p1_url=http://localhost:$port/_providers/primary -curl -X PUT $p1_url/_set_primary > p || fail=1 +curl -X PUT $p1_url/_primary > p || fail=1
http://repo.or.cz/w/iwhd.git/commit/e8699f536bb5cd49f8e20db1615221263938de07
commit e8699f536bb5cd49f8e20db1615221263938de07 Author: Jim Meyering meyering@redhat.com Date: Fri Dec 17 17:07:47 2010 +0100
new interface: curl -X PUT http://_providers/PROVIDER/_set_primary
* rest.c: Include <errno.h>. (proxy_set_primary): New function. (parse_url): Handle new type: URL_PROVIDER_SET_PRIMARY. * setup.c (set_main_provider): New function. * setup.h (set_main_provider): Declare it. * t/basic: Exercise the new functionality.
diff --git a/rest.c b/rest.c index cc0a99b..be4a888 100644 --- a/rest.c +++ b/rest.c @@ -28,6 +28,7 @@ #include <unistd.h> #include <sys/stat.h> #include <assert.h> +#include <errno.h>
#include <microhttpd.h> #include <hstor.h> /* only for ARRAY_SIZE at this point */ @@ -58,7 +59,7 @@
typedef enum { URL_ROOT=0, URL_BUCKET, URL_OBJECT, URL_ATTR, URL_INVAL, - URL_QUERY, URL_PROVLIST, URL_PROVIDER + URL_QUERY, URL_PROVLIST, URL_PROVIDER, URL_PROVIDER_SET_PRIMARY } url_type;
typedef struct { @@ -1746,6 +1747,62 @@ proxy_primary_prov (void *cctx, struct MHD_Connection *conn, const char *url, }
static int +proxy_set_primary (void *cctx, struct MHD_Connection *conn, const char *url, + const char *method, const char *version, const char *data, + size_t *data_size, void **rctx) +{ + (void)cctx; + (void)method; + (void)version; + (void)data; + + DPRINTF("PROXY SET PRIMARY PROVIDER (%s)n", url); + + my_state *ms = *rctx; + char *name = NULL; + unsigned int rc = MHD_HTTP_BAD_REQUEST; + + /* URL is guaranteed to be of the form "/_providers/NAME/_set_primary" + Extract NAME: */ + bool valid = memcmp (url, "/_providers/", strlen("/_providers/")) == 0; + if (!valid) { + error (0, 0, "invalid request: %s", url); + goto bad_set; + } + const char *start = url + strlen("/_providers/"); + const char *slash = strchr (start, '/'); + if (slash == NULL) { + error (0, 0, "invalid request: %s", url); + goto bad_set; + } + name = strndup (start, slash - start); + if (name == NULL) { + error (0, errno, "failed to extract provider name: %s", url); + goto bad_set; + } + + /* If it's not a provider name, you lose. */ + provider_t *prov = find_provider (name); + if (prov) { + rc = MHD_HTTP_OK; + set_main_provider (prov); + } + + bad_set: + free (name); + + struct MHD_Response *resp; + resp = MHD_create_response_from_data(0, NULL, MHD_NO, MHD_NO); + if (!resp) { + return MHD_NO; + } + MHD_queue_response(conn,rc,resp); + MHD_destroy_response(resp); + + return MHD_YES; +} + +static int proxy_delete_prov (void *cctx, struct MHD_Connection *conn, const char *url, const char *method, const char *version, const char *data, size_t *data_size, void **rctx) @@ -1938,6 +1995,8 @@ static const rule my_rules[] = { "POST", URL_PROVIDER, proxy_add_prov }, { /* delete a provider */ "DELETE", URL_PROVIDER, proxy_delete_prov }, + { /* set the primary provider */ + "PUT", URL_PROVIDER_SET_PRIMARY, proxy_set_primary }, { NULL, 0, NULL } };
@@ -1994,6 +2053,10 @@ parse_url (const char *url, my_state *ms) if (eindex == URL_OBJECT && !strcmp (parts[URL_BUCKET], "_providers")) eindex = URL_PROVIDER; + else if (eindex == URL_ATTR + && !strcmp (parts[URL_BUCKET], "_providers") + && !strcmp (parts[URL_ATTR], "_set_primary")) + eindex = URL_PROVIDER_SET_PRIMARY;
DPRINTF("parse_url: %d: %s %s %s", eindex, parts[URL_BUCKET], parts[URL_OBJECT], parts[URL_ATTR]); diff --git a/setup.c b/setup.c index f613f24..6ae5f01 100644 --- a/setup.c +++ b/setup.c @@ -78,6 +78,12 @@ get_main_provider (void) return main_prov; }
+void +set_main_provider (provider_t *prov) +{ + main_prov = prov; +} + int validate_provider (GHashTable *h) { diff --git a/setup.h b/setup.h index ecdef5f..0bfbb81 100644 --- a/setup.h +++ b/setup.h @@ -53,5 +53,6 @@ provider_t *find_provider (const char *name); int add_provider (GHashTable *h); void delete_provider (provider_t *prov); provider_t *get_main_provider (void); +void set_main_provider (provider_t *prov);
#endif diff --git a/t/basic b/t/basic index 59e2608..436f123 100644 --- a/t/basic +++ b/t/basic @@ -365,6 +365,18 @@ curl -dtype=http -dhost=localhost -dport=9091 $p_reserved_url || fail=1 curl http://localhost:$port/_primary > p || fail=1 grep _primary p && { warn_ add-provider/reserved-name not rejected; fail=1; }
+# Move the "primary" attribute to a different provider. +curl -X PUT $p1_url/_set_primary > p || fail=1 +test -s p && fail=1 +new_primary=$(curl http://localhost:$port/_providers/_primary) || fail=1 +test $new_primary = PROVIDER-1 || fail=1 + +# Restore the primary attribute to the original. +# FIXME: if I don't restore, the following headless test makes iwhd segfault. +# Investigate that. +p1_url=http://localhost:$port/_providers/primary +curl -X PUT $p1_url/_set_primary > p || fail=1 +
# Test "headless" operation (no access to metadata DB).
http://repo.or.cz/w/iwhd.git/commit/55be76211cca12e07a644809272649176f336f0e
commit 55be76211cca12e07a644809272649176f336f0e Author: Jim Meyering meyering@redhat.com Date: Fri Dec 17 15:37:14 2010 +0100
get primary provider name via http://host:$port/_providers/_primary
Get a URL of the form http://.../_providers/_primary to obtain the name of the primary provider. * rest.c (proxy_primary_prov): Implement it. (proxy_add_prov): Prohibit addition of a provider with the reserved name, "_primary". * t/basic: Exercise the new functionality.
diff --git a/rest.c b/rest.c index a56f2d3..cc0a99b 100644 --- a/rest.c +++ b/rest.c @@ -1712,6 +1712,40 @@ url_to_provider_name (const char *url) }
static int +proxy_primary_prov (void *cctx, struct MHD_Connection *conn, const char *url, + const char *method, const char *version, const char *data, + size_t *data_size, void **rctx) +{ + (void)cctx; + (void)method; + (void)version; + (void)data; + + DPRINTF("PROXY GET PRIMARY PROVIDER (%s)n", url); + + my_state *ms = *rctx; + + // "/_providers/_primary" is the only one we accept for now. + bool valid = strcmp (url, "/_providers/_primary") == 0; + unsigned int rc = (valid ? MHD_HTTP_OK : MHD_HTTP_BAD_REQUEST); + if (!valid) + error (0, 0, "invalid request: %s", url); + + const char *name = get_main_provider()->name; + struct MHD_Response *resp; + resp = MHD_create_response_from_data(valid ? strlen (name) : 0, + valid ? (void *) name : NULL, + MHD_NO, MHD_NO); + if (!resp) { + return MHD_NO; + } + MHD_queue_response(conn,rc,resp); + MHD_destroy_response(resp); + + return MHD_YES; +} + +static int proxy_delete_prov (void *cctx, struct MHD_Connection *conn, const char *url, const char *method, const char *version, const char *data, size_t *data_size, void **rctx) @@ -1798,6 +1832,16 @@ proxy_add_prov (void *cctx, struct MHD_Connection *conn, const char *url, name); goto add_fail; } + + // another reserved word: provider name + // FIXME: don't hard-code it here + if (strcmp (prov_name, "_primary") == 0) { + fprintf(stderr, + "add_provider: %s is a reserved namen", + prov_name); + goto add_fail; + } + // FIXME: unchecked strdup g_hash_table_insert(ms->dict,strdup("name"),prov_name);
@@ -1888,6 +1932,8 @@ static const rule my_rules[] = { "GET", URL_PROVLIST, proxy_list_provs }, { /* update a provider */ "POST", URL_PROVLIST, proxy_update_prov }, + { /* get the primary provider */ + "GET", URL_PROVIDER, proxy_primary_prov }, { /* create a provider */ "POST", URL_PROVIDER, proxy_add_prov }, { /* delete a provider */ diff --git a/t/basic b/t/basic index 19eda9b..59e2608 100644 --- a/t/basic +++ b/t/basic @@ -350,6 +350,22 @@ curl -f -X DELETE http://localhost:$port/_providers/no-such 2> p test $? = 22 || fail=1 grep ' 404$' p || fail=1
+# Get the name of the current primary provider. +curl http://localhost:$port/_providers/_primary > p || fail=1 +test "$(cat p)" = primary || fail=1 + +# Trying to GET with anything other than "_primary" returns the empty string. +curl http://localhost:$port/_providers/anything > p 2>/dev/null || fail=1 +test -s p && fail=1 + +# Try to add a provider with the reserved name. It must fail. +p_reserved_url=http://localhost:$port/_providers/_primary +curl -dtype=http -dhost=localhost -dport=9091 $p_reserved_url || fail=1 +# Ensure it was not added. +curl http://localhost:$port/_primary > p || fail=1 +grep _primary p && { warn_ add-provider/reserved-name not rejected; fail=1; } + +
# Test "headless" operation (no access to metadata DB). kill -9 $mongo_pid
http://repo.or.cz/w/iwhd.git/commit/2143b86e49ed10a3f59b08bff562f1a804d8f4d4
commit 2143b86e49ed10a3f59b08bff562f1a804d8f4d4 Author: Jim Meyering meyering@redhat.com Date: Thu Dec 16 18:27:10 2010 +0100
tests: clean up provider-deletion test
diff --git a/t/basic b/t/basic index 0d394c7..19eda9b 100644 --- a/t/basic +++ b/t/basic @@ -345,13 +345,11 @@ curl http://localhost:$port/_providers > p || fail=1 grep PROVIDER-2 p && { warn_ $ME_: provider deletion failed; fail=1; }
# Delete a non-existent provider. -curl -f -X DELETE http://localhost:$port/_providers/no-such +curl -f -X DELETE http://localhost:$port/_providers/no-such 2> p +# ensure it fails; expect exit-22 and http: 404 test $? = 22 || fail=1 -# FIXME ensure it fails -cat p +grep ' 404$' p || fail=1
-curl http://localhost:$port/_providers > p || fail=1 -cat p
# Test "headless" operation (no access to metadata DB). kill -9 $mongo_pid
http://repo.or.cz/w/iwhd.git/commit/76d355f00798546cdc34079f3346547921c47185
commit 76d355f00798546cdc34079f3346547921c47185 Author: Jim Meyering meyering@redhat.com Date: Wed Dec 15 12:45:28 2010 +0100
use new function, get_main_provider, rather than global "main_prov"
* setup.c (get_main_provider): New function. (main_prov): Declare static. * setup.h (main_prov): Remove global decl. (get_main_provider): Declare. * rest.c, replica.c: Update all uses of "main_prov".
diff --git a/replica.c b/replica.c index f0b4b51..301c8d3 100644 --- a/replica.c +++ b/replica.c @@ -73,7 +73,7 @@ proxy_repl_prod (void *ctx) void *result;
thunk.parent = item->ms; - thunk.prov = main_prov; + thunk.prov = get_main_provider();
result = thunk.prov->func_tbl->get_child_func(&thunk); return result; diff --git a/rest.c b/rest.c index f7ece46..a56f2d3 100644 --- a/rest.c +++ b/rest.c @@ -338,6 +338,7 @@ proxy_get_data (void *cctx, struct MHD_Connection *conn, const char *url, if (!pp) { return MHD_NO; } + provider_t *main_prov = get_main_provider(); ms->thunk.parent = ms; ms->thunk.prov = ms->from_master ? master_prov : main_prov; pthread_create(&ms->backend_th,NULL, @@ -468,6 +469,7 @@ proxy_put_data (void *cctx, struct MHD_Connection *conn, const char *url, if (!pp) { return MHD_NO; } + provider_t *main_prov = get_main_provider(); pp->prov = main_prov; ms->be_flags = BACKEND_GET_SIZE; pthread_create(&ms->backend_th,NULL, @@ -913,6 +915,7 @@ proxy_delete (void *cctx, struct MHD_Connection *conn, const char *url,
DPRINTF("PROXY DELETE %sn",url);
+ provider_t *main_prov = get_main_provider(); ms->thunk.parent = ms; ms->thunk.prov = main_prov; rc = ms->thunk.prov->func_tbl->delete_func(main_prov, @@ -1145,6 +1148,7 @@ create_bucket (char *name, my_state *ms) return MHD_HTTP_BAD_REQUEST; }
+ provider_t *main_prov = get_main_provider(); rc = main_prov->func_tbl->bcreate_func(main_prov,name); if (rc == MHD_HTTP_OK) { if (meta_set_value(name,"_default", "_policy","0") != 0) { @@ -1730,8 +1734,8 @@ proxy_delete_prov (void *cctx, struct MHD_Connection *conn, const char *url, char *prov_name = url_to_provider_name (url); provider_t *prov = find_provider (prov_name);
- // don't allow removal of current main_prov. - if (prov == main_prov) + // don't allow removal of current main provider. + if (prov == get_main_provider()) prov = NULL;
int rc = prov ? MHD_HTTP_OK : MHD_HTTP_NOT_FOUND; @@ -2156,6 +2160,7 @@ args_done: sem_init(&the_sem,0,0);
if (verbose) { + provider_t *main_prov = get_main_provider(); printf("primary store type is %sn",main_prov->type); if (master_host) { printf("operating as slave to %s:%un", diff --git a/setup.c b/setup.c index dc494af..f613f24 100644 --- a/setup.c +++ b/setup.c @@ -69,9 +69,15 @@ extern backend_func_tbl fs_func_tbl; static json_t *config = NULL; static GHashTable *prov_hash = NULL;
-provider_t *main_prov = NULL; +static provider_t *main_prov = NULL; provider_t *master_prov = NULL;
+provider_t * +get_main_provider (void) +{ + return main_prov; +} + int validate_provider (GHashTable *h) { diff --git a/setup.h b/setup.h index dc89a74..ecdef5f 100644 --- a/setup.h +++ b/setup.h @@ -36,7 +36,6 @@ typedef struct _provider { char *token; } provider_t;
-provider_t *main_prov; provider_t *master_prov;
const char *parse_config (char *); @@ -53,5 +52,6 @@ int validate_provider (GHashTable *h); provider_t *find_provider (const char *name); int add_provider (GHashTable *h); void delete_provider (provider_t *prov); +provider_t *get_main_provider (void);
#endif
http://repo.or.cz/w/iwhd.git/commit/4f53c5ae1af0508fe90f2539772e247560836f73
commit 4f53c5ae1af0508fe90f2539772e247560836f73 Author: Jim Meyering meyering@redhat.com Date: Sat Dec 11 15:58:18 2010 +0100
reject an attempt to add a provider with "name" parameter
The "name" is specified as part of the URL, not via a parameter. * rest.c (proxy_add_prov): Handle undesired "name" parameter properly. * t/basic: Exercise the above.
diff --git a/rest.c b/rest.c index 4797438..f7ece46 100644 --- a/rest.c +++ b/rest.c @@ -1792,8 +1792,7 @@ proxy_add_prov (void *cctx, struct MHD_Connection *conn, const char *url, fprintf(stderr, "add_provider: do not specify name: name=%sn", name); - return MHD_NO; - // FIXME: be careful that this does not leak "ms" + goto add_fail; } // FIXME: unchecked strdup g_hash_table_insert(ms->dict,strdup("name"),prov_name); @@ -1808,6 +1807,8 @@ proxy_add_prov (void *cctx, struct MHD_Connection *conn, const char *url, else { DPRINTF("invalid providern"); } + + add_fail: resp = MHD_create_response_from_data(0,NULL,MHD_NO,MHD_NO); if (!resp) { fprintf(stderr,"MHD_crfd failedn"); diff --git a/t/basic b/t/basic index fc42ac4..0d394c7 100644 --- a/t/basic +++ b/t/basic @@ -331,6 +331,13 @@ curl -dtype=http -dhost=localhost -dport=9091 $p2_url || fail=1 curl http://localhost:$port/_providers > p || fail=1 grep PROVIDER-2 p || fail=1
+# Add provider using a "name" parameter (not permitted): +p3_url=http://localhost:$port/_providers/PROVIDER-3 +curl -dtype=http -dname=X -dhost=localhost -dport=9091 $p3_url || fail=1 +# Ensure it was not added. +curl http://localhost:$port/_providers > p || fail=1 +grep PROVIDER-3 p && { warn_ add-provider-w/name-param not rejected; fail=1; } + # Delete a provider. curl -f -X DELETE $p2_url 2> p || fail=1 # Ensure it was deleted.
http://repo.or.cz/w/iwhd.git/commit/042463398c4b70c98a4c4890addae0a21fdc97c4
commit 042463398c4b70c98a4c4890addae0a21fdc97c4 Author: Jim Meyering meyering@redhat.com Date: Fri Dec 10 21:11:27 2010 +0100
add provider ref-counting; FIXME: partial impl. (i.e., no incr)
delete_provider: New function.
diff --git a/rest.c b/rest.c index f156862..4797438 100644 --- a/rest.c +++ b/rest.c @@ -1728,7 +1728,6 @@ proxy_delete_prov (void *cctx, struct MHD_Connection *conn, const char *url, }
char *prov_name = url_to_provider_name (url); - DPRINTF("PROXY DELETE PROVIDER prov=%sn", prov_name); provider_t *prov = find_provider (prov_name);
// don't allow removal of current main_prov. @@ -1736,10 +1735,17 @@ proxy_delete_prov (void *cctx, struct MHD_Connection *conn, const char *url, prov = NULL;
int rc = prov ? MHD_HTTP_OK : MHD_HTTP_NOT_FOUND; - if (prov) - prov->deleted = 1;
- error (0, 0, "DELETE PROV: rc=%d", rc); + DPRINTF("PROXY DELETE PROVIDER prov=%s rc=%dn", prov_name, rc); + + if (prov) { + /* Delete for real if no one is using it. + Otherwise, just mark it as deleted. */ + if (g_atomic_int_get (&prov->refcnt) == 0) + delete_provider (prov); + else + prov->deleted = 1; + }
free (prov_name); MHD_queue_response(conn,rc,resp); diff --git a/setup.c b/setup.c index 86061d1..dc494af 100644 --- a/setup.c +++ b/setup.c @@ -319,6 +319,7 @@ convert_provider (int i, provider_t *out)
out->token = NULL; out->deleted = 0; + out->refcnt = 0;
return 1; } @@ -582,6 +583,19 @@ find_provider (const char *name) return p; }
+void +delete_provider (provider_t *prov) +{ + // Remove from prov_hash, then free + + g_hash_table_destroy(prov->attrs); + // FIXME: free other members, too? + + // FIXME: unchecked strdup + char *name = strdup (prov->name); + g_hash_table_remove(prov_hash, prov->name); +} + const char * get_provider_value (const provider_t *prov, const char *fname) { diff --git a/setup.h b/setup.h index 11d2207..dc89a74 100644 --- a/setup.h +++ b/setup.h @@ -26,7 +26,8 @@ typedef struct _provider { const char *type; const char *host; int port; - int deleted; + int deleted; + gint refcnt; const char *username; const char *password; const char *path; @@ -51,5 +52,6 @@ const char *auto_config (void); int validate_provider (GHashTable *h); provider_t *find_provider (const char *name); int add_provider (GHashTable *h); +void delete_provider (provider_t *prov);
#endif
http://repo.or.cz/w/iwhd.git/commit/e87a2a25917713f20e0543caac8ab9cef0435077
commit e87a2a25917713f20e0543caac8ab9cef0435077 Author: Jim Meyering meyering@redhat.com Date: Mon Nov 15 17:50:53 2010 +0100
allow dynamic addition/deletion of providers
* setup.h (struct _provider) [deleted]: New member. * setup.c (validate_provider): New function. (json_validate_server): Renamed from validate_server. (convert_provider): Initialize new "deleted" member. (add_provider, find_provider): New functions. Declare new functions. * rest.c (prov_list_generator): Don't list a provider that is marked as deleted. (url_to_provider_name): New function. (proxy_delete_prov, proxy_add_prov): New functions. (my_rules): Add corresponding entries in this table. * t/basic: Add minimal tests of new functionality.
diff --git a/rest.c b/rest.c index ea8b289..f156862 100644 --- a/rest.c +++ b/rest.c @@ -34,6 +34,7 @@ #include <curl/curl.h> #include <glib.h>
+#include "dirname.h" #include "iwh.h" #include "closeout.h" #include "progname.h" @@ -57,7 +58,7 @@
typedef enum { URL_ROOT=0, URL_BUCKET, URL_OBJECT, URL_ATTR, URL_INVAL, - URL_QUERY, URL_PROVLIST + URL_QUERY, URL_PROVLIST, URL_PROVIDER } url_type;
typedef struct { @@ -931,6 +932,7 @@ proxy_delete (void *cctx, struct MHD_Connection *conn, const char *url, free_ms(ms); return MHD_NO; } + error (0, 0, "DELETE BUCKET: rc=%d", rc); MHD_queue_response(conn,rc,resp); MHD_destroy_response(resp);
@@ -1458,7 +1460,7 @@ proxy_object_post (void *cctx, struct MHD_Connection *conn, const char *url, (void)method; (void)version;
- DPRINTF("PROXY POST (%s, %zu)n",url,*data_size); + DPRINTF("PROXY POST obj (%s, %zu)n",url,*data_size);
if (ms->state == MS_NEW) { ms->state = MS_NORMAL; @@ -1563,6 +1565,8 @@ prov_list_generator (void *ctx, uint64_t pos, char *buf, size_t max) }
if (g_hash_table_iter_next(&ms->prov_iter,&key,(gpointer *)&prov)) { + if (prov->deleted) + return 0; len = tmpl_prov_entry(ms->gen_ctx,prov->name,prov->type, prov->host, prov->port, prov->username, prov->password); if (!len) { @@ -1691,6 +1695,126 @@ proxy_update_prov (void *cctx, struct MHD_Connection *conn, const char *url, return MHD_YES; }
+static char * +url_to_provider_name (const char *url) +{ + char *prov_name = base_name (url); + if (prov_name) + strip_trailing_slashes (prov_name); + /* Ensure we handle trailing slashes (i.e., remove them). */ + assert (prov_name == NULL + || (*prov_name && prov_name[strlen(prov_name)-1] != '/')); + return prov_name; +} + +static int +proxy_delete_prov (void *cctx, struct MHD_Connection *conn, const char *url, + const char *method, const char *version, const char *data, + size_t *data_size, void **rctx) +{ + DPRINTF("PROXY DELETE PROVIDER %sn",url); + (void)cctx; + (void)method; + (void)version; + (void)data; + (void)data_size; + + my_state *ms = *rctx; + struct MHD_Response *resp + = MHD_create_response_from_data(0,NULL,MHD_NO,MHD_NO); + if (!resp) { + free_ms(ms); + return MHD_NO; + } + + char *prov_name = url_to_provider_name (url); + DPRINTF("PROXY DELETE PROVIDER prov=%sn", prov_name); + provider_t *prov = find_provider (prov_name); + + // don't allow removal of current main_prov. + if (prov == main_prov) + prov = NULL; + + int rc = prov ? MHD_HTTP_OK : MHD_HTTP_NOT_FOUND; + if (prov) + prov->deleted = 1; + + error (0, 0, "DELETE PROV: rc=%d", rc); + + free (prov_name); + MHD_queue_response(conn,rc,resp); + MHD_destroy_response(resp); + + free_ms(ms); + return MHD_YES; +} + +static int +proxy_add_prov (void *cctx, struct MHD_Connection *conn, const char *url, + const char *method, const char *version, const char *data, + size_t *data_size, void **rctx) +{ + DPRINTF("PROXY ADD PROVIDER %sn",url); + struct MHD_Response *resp; + my_state *ms = *rctx; + + (void)cctx; + (void)method; + (void)version; + + if (ms->state == MS_NEW) { + ms->state = MS_NORMAL; + ms->url = (char *)url; + ms->dict = g_hash_table_new_full( + g_str_hash,g_str_equal,free,free); + ms->cleanup |= CLEANUP_DICT; + ms->post = MHD_create_post_processor(conn,4096, + prov_iterator,ms->dict); + ms->cleanup |= CLEANUP_POST; + } + else if (*data_size) { + MHD_post_process(ms->post,data,*data_size); + *data_size = 0; + } + else { + int rc = MHD_HTTP_BAD_REQUEST; + char *prov_name = url_to_provider_name (url); + /* We're about to insert "name -> $prov_name". + Ensure there is no "name" key already there. */ + const char *name = g_hash_table_lookup (ms->dict, "name"); + if (name) { + fprintf(stderr, + "add_provider: do not specify name: name=%sn", + name); + return MHD_NO; + // FIXME: be careful that this does not leak "ms" + } + // FIXME: unchecked strdup + g_hash_table_insert(ms->dict,strdup("name"),prov_name); + + if (validate_provider (ms->dict)) { + if (!add_provider (ms->dict)) { + DPRINTF("add provider failedn"); + } else { + rc = MHD_HTTP_OK; + } + } + else { + DPRINTF("invalid providern"); + } + resp = MHD_create_response_from_data(0,NULL,MHD_NO,MHD_NO); + if (!resp) { + fprintf(stderr,"MHD_crfd failedn"); + return MHD_NO; + } + MHD_queue_response(conn,rc,resp); + MHD_destroy_response(resp); + free_ms(ms); + } + + return MHD_YES; +} + static int proxy_create_bucket (void *cctx, struct MHD_Connection *conn, const char *url, const char *method, const char *version, const char *data, @@ -1753,6 +1877,10 @@ static const rule my_rules[] = { "GET", URL_PROVLIST, proxy_list_provs }, { /* update a provider */ "POST", URL_PROVLIST, proxy_update_prov }, + { /* create a provider */ + "POST", URL_PROVIDER, proxy_add_prov }, + { /* delete a provider */ + "DELETE", URL_PROVIDER, proxy_delete_prov }, { NULL, 0, NULL } };
@@ -1806,6 +1934,12 @@ parse_url (const char *url, my_state *ms) } }
+ if (eindex == URL_OBJECT + && !strcmp (parts[URL_BUCKET], "_providers")) + eindex = URL_PROVIDER; + + DPRINTF("parse_url: %d: %s %s %s", eindex, parts[URL_BUCKET], + parts[URL_OBJECT], parts[URL_ATTR]); return eindex; }
diff --git a/setup.c b/setup.c index 2a03f40..86061d1 100644 --- a/setup.c +++ b/setup.c @@ -27,6 +27,7 @@ #include <string.h> #include <strings.h> #include <unistd.h> +#include <assert.h>
#include <jansson.h>
@@ -71,8 +72,74 @@ static GHashTable *prov_hash = NULL; provider_t *main_prov = NULL; provider_t *master_prov = NULL;
+int +validate_provider (GHashTable *h) +{ + const char *name = g_hash_table_lookup (h, "name"); + assert (name); + const char *type = g_hash_table_lookup (h, "type"); + if (type == NULL) { + error (0, 0, "provider %s has no type", name); + return 0; + } + + unsigned int needs; + if (!strcasecmp(type,"s3") || !strcasecmp(type,"cf")) { + needs = NEED_SERVER | NEED_CREDS; + } else if (!strcasecmp(type,"http")) { + needs = NEED_SERVER; + } else if (!strcasecmp(type,"fs")) { + needs = NEED_PATH; + } else { + error (0, 0, "provider %s has invalid type: %s", name, type); + return 0; + } + + int ok = 1; + if (needs & NEED_SERVER) { + const char *host = g_hash_table_lookup (h, "host"); + if (!host) { + error (0, 0, "%s: %s-provider requires a host", name, type); + ok = 0; + } + const char *port = g_hash_table_lookup (h, "port"); + if (!port) { + error (0, 0, "%s: %s-provider requires a port", name, type); + ok = 0; + } + // ensure port is a positive integer with 5 or fewer digits + if (5 < strlen (port) || strcspn (port, "0123456789")) { + error (0, 0, "%s: %s-provider: invalid port: %s", name, type, port); + ok = 0; + } + } + + if (needs & NEED_CREDS) { + const char *key = g_hash_table_lookup (h, "key"); + if (!key) { + error (0, 0, "%s: %s-provider requires a key", name, type); + ok = 0; + } + const char *secret = g_hash_table_lookup (h, "secret"); + if (!secret) { + error (0, 0, "%s: %s-provider requires a secret", name, type); + ok = 0; + } + } + + if (needs & NEED_PATH) { + const char *path = g_hash_table_lookup (h, "path"); + if (!path) { + error (0, 0, "%s: %s-provider requires a path", name, type); + ok = 0; + } + } + + return ok; +} + static int -validate_server (unsigned int i) +json_validate_server (unsigned int i) { json_t *server; json_t *elem; @@ -209,6 +276,7 @@ convert_provider (int i, provider_t *out) out->username = dup_json_string(server,"key"); out->password = dup_json_string(server,"secret"); out->path = dup_json_string(server,"path"); + /* FIXME: detect failed "dup_*" calls. */
/* TBD: do this a cleaner way. */ if (!strcasecmp(out->type,"s3")) { @@ -231,6 +299,7 @@ convert_provider (int i, provider_t *out) iter = json_object_iter(server); while (iter) { key = json_object_iter_key(iter); + error(0,0,"convert-provider: ITER key: %s",key); if (!is_reserved_attr(key)) { value = json_string_value(json_object_iter_value(iter)); if (value) { @@ -249,10 +318,100 @@ convert_provider (int i, provider_t *out) }
out->token = NULL; + out->deleted = 0;
return 1; }
+int +add_provider (GHashTable *h) +{ + char *name = g_hash_table_lookup (h, "name"); + assert (name); + + provider_t *prov = calloc (1, sizeof *prov); + if (prov == NULL) + return 0; + + prov->name = strdup (name); + if (prov->name == NULL) + goto fail; + + prov->type = g_hash_table_lookup(h,"type"); + if (prov->type == NULL) + goto fail; + prov->type = strdup (prov->type); + if (prov->type == NULL) + goto fail; + + prov->host = g_hash_table_lookup(h,"host"); + prov->port = atoi(g_hash_table_lookup(h,"port")); + /* TBD: change key/secret field names to username/password */ + prov->username = g_hash_table_lookup(h,"key"); + prov->password = g_hash_table_lookup(h,"secret"); + prov->path = g_hash_table_lookup(h,"path"); + + if (prov->host) + prov->host = strdup (prov->host); + if (prov->username) + prov->username = strdup (prov->username); + if (prov->password) + prov->password = strdup (prov->password); + if (prov->path) + prov->path = strdup (prov->path); + + /* TBD: do this a cleaner way. */ + if (!strcasecmp(prov->type,"s3")) + prov->func_tbl = &s3_func_tbl; + else if (!strcasecmp(prov->type,"http")) + prov->func_tbl = &curl_func_tbl; + else if (!strcasecmp(prov->type,"cf")) + prov->func_tbl = &cf_func_tbl; + else if (!strcasecmp(prov->type,"fs")) + prov->func_tbl = &fs_func_tbl; + else + prov->func_tbl = &bad_func_tbl; + + prov->attrs = g_hash_table_new_full(g_str_hash,g_str_equal,free,free); + // FIXME: can't the above fail? + + GHashTableIter iter; + g_hash_table_iter_init (&iter, h); + while (1) { + gpointer key; + gpointer val; + if (!g_hash_table_iter_next (&iter, &key, &val)) + break; + + if (!is_reserved_attr(key)) { + if (val) { + error(0,0,"no value for %s", (char *)key); + continue; + } + DPRINTF("%p.%s = %sn",prov, (char *)key, (char *)val); + g_hash_table_insert(prov->attrs, strdup(key), strdup(val)); + // FIXME: check strdup for failure + } + } + + /* Note that we must strdup "name", since here it's a key, but above it's a + value. Not using // strdup here would lead to a use-after-free bug. */ + // FIXME: check strdup for failure + g_hash_table_insert(prov_hash,strdup(name),prov); + + return 1; + + fail: + free ((char *) prov->name); + free ((char *) prov->type); + free ((char *) prov->host); + free ((char *) prov->username); + free ((char *) prov->password); + free ((char *) prov->path); + free (prov); + return 0; +} + static const char * parse_config_inner (void) { @@ -274,7 +433,7 @@ parse_config_inner (void) }
for (i = 0; i < nservers; ++i) { - if (!validate_server(i)) { + if (!json_validate_server(i)) { goto err; } } @@ -402,7 +561,7 @@ auto_config(void) return primary; }
-const provider_t * +provider_t * get_provider (const char *name) { if (!prov_hash || !name || (*name == '0')) { @@ -411,6 +570,18 @@ get_provider (const char *name) return g_hash_table_lookup(prov_hash,name); }
+provider_t * +find_provider (const char *name) +{ + if (!prov_hash || !name || (*name == '0')) { + return NULL; + } + + provider_t *p = g_hash_table_lookup(prov_hash, name); + + return p; +} + const char * get_provider_value (const provider_t *prov, const char *fname) { diff --git a/setup.h b/setup.h index e70cffa..11d2207 100644 --- a/setup.h +++ b/setup.h @@ -26,6 +26,7 @@ typedef struct _provider { const char *type; const char *host; int port; + int deleted; const char *username; const char *password; const char *path; @@ -38,14 +39,17 @@ provider_t *main_prov; provider_t *master_prov;
const char *parse_config (char *); -const provider_t *get_provider (const char *name); -void update_provider (const char *provname, +provider_t *get_provider (const char *name); +void update_provider (const char *provname, const char *username, const char *password); const char *get_provider_value (const provider_t *prov, const char *fname); void init_prov_iter (GHashTableIter *iter);
-const char *auto_config (void); +const char *auto_config (void); +int validate_provider (GHashTable *h); +provider_t *find_provider (const char *name); +int add_provider (GHashTable *h);
#endif diff --git a/t/basic b/t/basic index 6a30fcc..fc42ac4 100644 --- a/t/basic +++ b/t/basic @@ -311,14 +311,45 @@ echo bye | curl -f -T - $bucket/trunc_test || fail=1 cat FS/b1/trunc_test test "$(cat FS/b1/trunc_test)" = bye || fail=1
+# TBD: add attribute-delete tests when that functionality is implemented + +# TBD: add white-box tests for attributes in mongo + +# Add a provider: +p1_url=http://localhost:$port/_providers/PROVIDER-1 +curl -d type=s3 -dhost=localhost -dport=80 -dkey=u -dsecret=p + $p1_url || fail=1 + +# Ensure it was added +curl http://localhost:$port/_providers > p || fail=1 +grep PROVIDER-1 p || fail=1 + +# Add another provider: +p2_url=http://localhost:$port/_providers/PROVIDER-2 +curl -dtype=http -dhost=localhost -dport=9091 $p2_url || fail=1 +# Ensure it was added. +curl http://localhost:$port/_providers > p || fail=1 +grep PROVIDER-2 p || fail=1 + +# Delete a provider. +curl -f -X DELETE $p2_url 2> p || fail=1 +# Ensure it was deleted. +curl http://localhost:$port/_providers > p || fail=1 +grep PROVIDER-2 p && { warn_ $ME_: provider deletion failed; fail=1; } + +# Delete a non-existent provider. +curl -f -X DELETE http://localhost:$port/_providers/no-such +test $? = 22 || fail=1 +# FIXME ensure it fails +cat p + +curl http://localhost:$port/_providers > p || fail=1 +cat p + # Test "headless" operation (no access to metadata DB). kill -9 $mongo_pid cleanup_() { kill $iwhd_pid; } curl $bucket/attr_put > f3copy test "$(cat f3copy)" = "nothing" || fail=1
-# TBD: add attribute-delete tests when that functionality is implemented - -# TBD: add white-box tests for attributes in mongo - Exit $fail
-----------------------------------------------------------------------
repo.or.cz automatic notification. Contact project admin jim@meyering.net if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.
iwhd-commit@lists.fedorahosted.org