RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: j...@rpm5.org Module: rpm Date: 03-Apr-2011 23:18:45 Branch: rpm-5_4 Handle: 2011040321184401 Modified files: (Branch: rpm-5_4) rpm CHANGES rpm/rpmio bson.c bson.h mongo.c mongo.h Log: - mongo: update mongo-c-driver code, gridfs stil todo++ Summary: Revision Changes Path 1.3501.2.97 +1 -0 rpm/CHANGES 2.4.4.1 +44 -4 rpm/rpmio/bson.c 2.3.4.1 +11 -2 rpm/rpmio/bson.h 2.3.4.1 +102 -11 rpm/rpmio/mongo.c 2.2.4.1 +13 -0 rpm/rpmio/mongo.h ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/CHANGES ============================================================================ $ cvs diff -u -r1.3501.2.96 -r1.3501.2.97 CHANGES --- rpm/CHANGES 3 Apr 2011 20:02:18 -0000 1.3501.2.96 +++ rpm/CHANGES 3 Apr 2011 21:18:44 -0000 1.3501.2.97 @@ -1,4 +1,5 @@ 5.4.0 -> 5.4.1: + - jbj: mongo: update mongo-c-driver code, gridfs stil todo++ - jbj: mongo: stub-in a configurable mongodb:// %_mongodb URI. - jbj: autofu: fix: remove --with-js remnants. - jbj: autofu: drop --with-js=internal now that JS 1.8.5 is available. @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/bson.c ============================================================================ $ cvs diff -u -r2.4 -r2.4.4.1 bson.c --- rpm/rpmio/bson.c 18 Sep 2010 14:13:32 -0000 2.4 +++ rpm/rpmio/bson.c 3 Apr 2011 21:18:45 -0000 2.4.4.1 @@ -324,6 +324,7 @@ time_t out; bson_big_endian32(&out, &oid->ints[0]); return out; + } void bson_print( bson * b ){ @@ -334,6 +335,7 @@ bson_iterator i; const char * key; int temp; + bson_timestamp_t ts; char oidhex[25]; bson_iterator_init( &i , data ); @@ -353,6 +355,10 @@ case bson_string: printf( "%s" , bson_iterator_string( &i ) ); break; case bson_null: printf( "null" ); break; case bson_oid: bson_oid_to_string(bson_iterator_oid(&i), oidhex); printf( "%s" , oidhex ); break; + case bson_timestamp: + ts = bson_iterator_timestamp( &i ); + printf("i: %d, t: %d", ts.i, ts.t); + break; case bson_object: case bson_array: printf( "\n" ); @@ -501,6 +507,13 @@ } } +bson_timestamp_t bson_iterator_timestamp( const bson_iterator * i){ + bson_timestamp_t ts; + bson_little_endian32(&(ts.i), bson_iterator_value(i)); + bson_little_endian32(&(ts.t), bson_iterator_value(i) + 4); + return ts; +} + bson_bool_t bson_iterator_bool( const bson_iterator * i ){ switch (bson_iterator_type(i)){ case bson_bool: return bson_iterator_bool_raw(i); @@ -548,14 +561,18 @@ } int bson_iterator_bin_len( const bson_iterator * i ){ - return bson_iterator_int_raw( i ); + return (bson_iterator_bin_type(i) == 2) + ? bson_iterator_int_raw( i ) - 4 + : bson_iterator_int_raw( i ); } char bson_iterator_bin_type( const bson_iterator * i ){ return bson_iterator_value(i)[4]; } const char * bson_iterator_bin_data( const bson_iterator * i ){ - return bson_iterator_value( i ) + 5; + return (bson_iterator_bin_type( i ) == 2) + ? bson_iterator_value( i ) + 9 + : bson_iterator_value( i ) + 5; } const char * bson_iterator_regex( const bson_iterator * i ){ @@ -715,10 +732,19 @@ } bson_buffer * bson_append_binary( bson_buffer * b, const char * name, char type, const char * str, int len ){ + if ( type == 2 ){ + int subtwolen = len + 4; + if ( ! bson_append_estart( b , bson_bindata , name , 4+1+4+len ) ) return 0; + bson_append32(b, &subtwolen); + bson_append_byte(b, type); + bson_append32(b, &len); + bson_append(b, str, len); + }else{ if ( ! bson_append_estart( b , bson_bindata , name , 4+1+len ) ) return 0; bson_append32(b, &len); bson_append_byte(b, type); bson_append(b, str, len); + } return b; } bson_buffer * bson_append_oid( bson_buffer * b , const char * name , const bson_oid_t * oid ){ @@ -758,15 +784,23 @@ bson_ensure_space(b, size); bson_append(b, elem->cur, size); }else{ - int data_size = size - 1 - strlen(bson_iterator_key(elem)); + int data_size = size - 2 - strlen(bson_iterator_key(elem)); bson_append_estart(b, elem->cur[0], name_or_null, data_size); - bson_append(b, name_or_null, strlen(name_or_null)); bson_append(b, bson_iterator_value(elem), data_size); } return b; } +bson_buffer * bson_append_timestamp( bson_buffer * b, const char * name, bson_timestamp_t * ts ){ + if ( ! bson_append_estart( b , bson_timestamp , name , 8 ) ) return 0; + + bson_append32( b , &(ts->i) ); + bson_append32( b , &(ts->t) ); + + return b; +} + bson_buffer * bson_append_date( bson_buffer * b , const char * name , bson_date_t millis ){ if ( ! bson_append_estart( b , bson_date , name , 8 ) ) return 0; bson_append64( b , &millis ); @@ -810,6 +844,12 @@ return p; } +void* bson_realloc(void* ptr, int size){ + void* p = realloc(ptr, size); + bson_fatal_msg(!!p, "realloc() failed"); + return p; +} + static bson_err_handler err_handler = NULL; bson_err_handler set_bson_err_handler(bson_err_handler func){ @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/bson.h ============================================================================ $ cvs diff -u -r2.3 -r2.3.4.1 bson.h --- rpm/rpmio/bson.h 18 Sep 2010 14:02:49 -0000 2.3 +++ rpm/rpmio/bson.h 3 Apr 2011 21:18:45 -0000 2.3.4.1 @@ -72,6 +72,11 @@ typedef int64_t bson_date_t; /* milliseconds since epoch UTC */ +typedef struct { + int i; /* increment */ + int t; /* time in seconds */ +} bson_timestamp_t; + #ifdef __cplusplus extern "C" { #endif @@ -121,6 +126,9 @@ int bson_iterator_int( const bson_iterator * i ); int64_t bson_iterator_long( const bson_iterator * i ); +/* return the bson timestamp as a whole or in parts */ +bson_timestamp_t bson_iterator_timestamp( const bson_iterator * i ); + /* false: boolean false, 0 in any type, or null */ /* true: anything else (even empty strings and objects) */ bson_bool_t bson_iterator_bool( const bson_iterator * i ); @@ -194,6 +202,7 @@ bson_buffer * bson_append_regex( bson_buffer * b , const char * name , const char * pattern, const char * opts ); bson_buffer * bson_append_bson( bson_buffer * b , const char * name , const bson* bson); bson_buffer * bson_append_element( bson_buffer * b, const char * name_or_null, const bson_iterator* elem); +bson_buffer * bson_append_timestamp( bson_buffer * b, const char * name, bson_timestamp_t * ts ); /* these both append a bson_date */ bson_buffer * bson_append_date(bson_buffer * b, const char * name, bson_date_t millis); @@ -212,6 +221,7 @@ ------------------------------ */ void * bson_malloc(int size); /* checks return value */ +void * bson_realloc(void * ptr, int size); /* checks return value */ /* bson_err_handlers shouldn't return!!! */ typedef void(*bson_err_handler)(const char* errmsg); @@ -220,8 +230,6 @@ /* default handler prints error then exits with failure*/ bson_err_handler set_bson_err_handler(bson_err_handler func); - - /* does nothing is ok != 0 */ void bson_fatal( int ok ); void bson_fatal_msg( int ok, const char* msg ); @@ -230,4 +238,5 @@ } #endif + #endif /* H_BSON */ @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/mongo.c ============================================================================ $ cvs diff -u -r2.3 -r2.3.4.1 mongo.c --- rpm/rpmio/mongo.c 18 Sep 2010 14:02:49 -0000 2.3 +++ rpm/rpmio/mongo.c 3 Apr 2011 21:18:45 -0000 2.3.4.1 @@ -239,10 +239,12 @@ /* connect */ conn->sock = socket( AF_INET, SOCK_STREAM, 0 ); if ( conn->sock <= 0 ){ + mongo_close_socket( conn->sock ); return mongo_conn_no_socket; } if ( connect( conn->sock , (struct sockaddr*)&conn->sa , conn->addressSize ) ){ + mongo_close_socket( conn->sock ); return mongo_conn_fail; } @@ -271,6 +273,94 @@ return mongo_connect_helper(conn); } + +void mongo_replset_init_conn(mongo_connection* conn) { + conn->seeds = NULL; +} + +int mongo_replset_add_seed(mongo_connection* conn, const char* host, int port) { + mongo_host_port* host_port = bson_malloc(sizeof(mongo_host_port)); + host_port->port = port; + host_port->next = NULL; + strncpy( host_port->host, host, strlen(host) ); + + if( conn->seeds == NULL ) + conn->seeds = host_port; + else { + mongo_host_port* p = conn->seeds; + while( p->next != NULL ) + p = p->next; + p->next = host_port; + } + + return 0; +} + +mongo_conn_return mongo_replset_connect(mongo_connection* conn) { + + bson* out; + bson_bool_t ismaster; + + mongo_host_port* node = conn->seeds; + + conn->sock = 0; + conn->connected = 0; + + while( node != NULL ) { + + memset( conn->sa.sin_zero , 0 , sizeof(conn->sa.sin_zero) ); + conn->sa.sin_family = AF_INET; + conn->sa.sin_port = htons(node->port); + conn->sa.sin_addr.s_addr = inet_addr(node->host); + + conn->addressSize = sizeof(conn->sa); + + conn->sock = socket( AF_INET, SOCK_STREAM, 0 ); + if ( conn->sock <= 0 ){ + mongo_close_socket( conn->sock ); + return mongo_conn_no_socket; + } + + if ( connect( conn->sock , (struct sockaddr*)&conn->sa , conn->addressSize ) ){ + mongo_close_socket( conn->sock ); + } + + setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one) ); + + /* Check whether this is the primary node */ + ismaster = 0; + + out = bson_malloc(sizeof(bson)); + out->data = NULL; + out->owned = 0; + + if (mongo_simple_int_command(conn, "admin", "ismaster", 1, out)) { + bson_iterator it; + bson_find(&it, out, "ismaster"); + ismaster = bson_iterator_bool(&it); + free(out); + } + + if(ismaster) { + conn->connected = 1; + } + else { + mongo_close_socket( conn->sock ); + } + + node = node->next; + } + + /* TODO signals */ + + /* Might be nice to know which node is primary */ + /* con->primary = NULL; */ + if( conn->connected == 1 ) + return 0; + else + return -1; +} + static void swap_repl_pair(mongo_connection * conn){ mongo_connection_options * tmp = conn->left_opts; conn->left_opts = conn->right_opts; @@ -405,12 +495,16 @@ mongo_header head; /* header from network */ mongo_reply_fields fields; /* header from network */ mongo_reply * out; /* native endian */ - int len; + size_t len; looping_read(conn, &head, sizeof(head)); looping_read(conn, &fields, sizeof(fields)); bson_little_endian32(&len, &head.len); + + if (len < sizeof(head)+sizeof(fields) || len > 64*1024*1024) + MONGO_THROW(MONGO_EXCEPT_NETWORK); /* most likely corruption */ + out = (mongo_reply*)bson_malloc(len); out->head.len = len; @@ -435,7 +529,7 @@ mongo_cursor* mongo_find(mongo_connection* conn, const char* ns, bson* query, bson* fields, int nToReturn, int nToSkip, int options){ int sl; - mongo_cursor * cursor; + volatile mongo_cursor * cursor; /* volatile due to longjmp in mongo exception handler */ char * data; mongo_message * mm = mongo_message_create( 16 + /* header */ 4 + /* options */ @@ -464,7 +558,7 @@ MONGO_TRY{ cursor->mm = mongo_read_response(conn); }MONGO_CATCH{ - free(cursor); + free((mongo_cursor*)cursor); /* cast away volatile, not changing type */ MONGO_RETHROW(); } @@ -472,13 +566,13 @@ cursor->ns = bson_malloc(sl); if (!cursor->ns){ free(cursor->mm); - free(cursor); + free((mongo_cursor*)cursor); /* cast away volatile, not changing type */ return 0; } memcpy((void*)cursor->ns, ns, sl); /* cast needed to silence GCC warning */ cursor->conn = conn; cursor->current.data = NULL; - return cursor; + return (mongo_cursor*)cursor; } bson_bool_t mongo_find_one(mongo_connection* conn, const char* ns, bson* query, bson* fields, bson* out){ @@ -526,11 +620,7 @@ if ( ! conn->connected ) return 1; -#ifdef _WIN32 - closesocket( conn->sock ); -#else - close( conn->sock ); -#endif + mongo_close_socket( conn->sock ); conn->sock = 0; conn->connected = 0; @@ -697,6 +787,7 @@ free(ns); return success; } + bson_bool_t mongo_simple_int_command(mongo_connection * conn, const char * db, const char* cmdstr, int arg, bson * realout){ bson out; bson cmd; @@ -822,7 +913,7 @@ bson user_obj; bson pass_obj; char hex_digest[32+1]; - char* ns = malloc(strlen(db) + strlen(".system.users") + 1); + char* ns = bson_malloc(strlen(db) + strlen(".system.users") + 1); strcpy(ns, db); strcpy(ns+strlen(db), ".system.users"); @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/mongo.h ============================================================================ $ cvs diff -u -r2.2 -r2.2.4.1 mongo.h --- rpm/rpmio/mongo.h 18 Sep 2010 03:41:08 -0000 2.2 +++ rpm/rpmio/mongo.h 3 Apr 2011 21:18:45 -0000 2.2.4.1 @@ -56,15 +56,23 @@ } mongo_exception_context; /* --- mongo.h */ +#define mongo_close_socket(sock) ( close(sock) ) typedef struct mongo_connection_options { char host[255]; int port; } mongo_connection_options; +typedef struct mongo_host_port { + char host[255]; + int port; + struct mongo_host_port* next; +} mongo_host_port; + typedef struct { mongo_connection_options* left_opts; /* always current server */ mongo_connection_options* right_opts; /* unused with single server */ + mongo_host_port* seeds; struct sockaddr_in sa; socklen_t addressSize; int sock; @@ -146,6 +154,11 @@ mongo_conn_return mongo_connect( mongo_connection * conn , mongo_connection_options * options ); mongo_conn_return mongo_connect_pair( mongo_connection * conn , mongo_connection_options * left, mongo_connection_options * right ); mongo_conn_return mongo_reconnect( mongo_connection * conn ); /* you will need to reauthenticate after calling */ + +void mongo_replset_init_conn(mongo_connection* conn); +int mongo_replset_add_seed(mongo_connection* conn, const char* host, int port); +mongo_conn_return mongo_replset_connect(mongo_connection* conn); + bson_bool_t mongo_disconnect( mongo_connection * conn ); /* use this if you want to be able to reconnect */ bson_bool_t mongo_destroy( mongo_connection * conn ); /* you must call this even if connection failed */ @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org