diff --git a/daemon/main.c b/daemon/main.c index c7a655990..c04bca378 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -71,6 +71,7 @@ static int port_max = 40000; static int max_sessions = -1; static int redis_db = -1; static int redis_write_db = -1; +static int no_redis_required; static char *redis_auth; static char *redis_write_auth; static char *b2b_url; @@ -289,6 +290,7 @@ static void options(int *argc, char ***argv) { { "port-max", 'M', 0, G_OPTION_ARG_INT, &port_max, "Highest port to use for RTP", "INT" }, { "redis", 'r', 0, G_OPTION_ARG_STRING, &redisps, "Connect to Redis database", "[PW@]IP:PORT/INT" }, { "redis-write",'w', 0, G_OPTION_ARG_STRING, &redisps_write, "Connect to Redis write database", "[PW@]IP:PORT/INT" }, + { "no-redis-required", 'Q', 0, G_OPTION_ARG_NONE, &no_redis_required, "Start no matter of redis connection state", NULL }, { "b2b-url", 'b', 0, G_OPTION_ARG_STRING, &b2b_url, "XMLRPC URL of B2B UA" , "STRING" }, { "log-level", 'L', 0, G_OPTION_ARG_INT, (void *)&log_level,"Mask log priorities above this level","INT" }, { "log-facility",0, 0, G_OPTION_ARG_STRING, &log_facility_s, "Syslog facility to use for logging", "daemon|local0|...|local7"}, @@ -571,15 +573,17 @@ no_kernel: } if (!is_addr_unspecified(&redis_write_ep.address)) { - mc.redis_write = redis_new(&redis_write_ep, redis_write_db, redis_write_auth, ANY_REDIS_ROLE); + mc.redis_write = redis_new(&redis_write_ep, redis_write_db, redis_write_auth, ANY_REDIS_ROLE, no_redis_required); if (!mc.redis_write) - die("Cannot start up without Redis write database"); + die("Cannot start up without running Redis %s write database! See also NO_REDIS_REQUIRED paramter.", + endpoint_print_buf(&redis_write_ep)); } if (!is_addr_unspecified(&redis_ep.address)) { - mc.redis = redis_new(&redis_ep, redis_db, redis_auth, mc.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE); + mc.redis = redis_new(&redis_ep, redis_db, redis_auth, mc.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, no_redis_required); if (!mc.redis) - die("Cannot start up without Redis database"); + die("Cannot start up without running Redis %s database! See also NO_REDIS_REQUIRED paramter.", + endpoint_print_buf(&redis_ep)); if (!mc.redis_write) mc.redis_write = mc.redis; diff --git a/daemon/redis.c b/daemon/redis.c index 17aeaa175..027b5d71e 100644 --- a/daemon/redis.c +++ b/daemon/redis.c @@ -225,7 +225,7 @@ err: -struct redis *redis_new(const endpoint_t *ep, int db, const char *auth, enum redis_role role) { +struct redis *redis_new(const endpoint_t *ep, int db, const char *auth, enum redis_role role, int no_redis_required) { struct redis *r; r = g_slice_alloc0(sizeof(*r)); @@ -236,20 +236,28 @@ struct redis *redis_new(const endpoint_t *ep, int db, const char *auth, enum red r->auth = auth; r->role = role; r->state = REDIS_STATE_DISCONNECTED; + r->no_redis_required = no_redis_required; mutex_init(&r->lock); if (redis_connect(r, 10)) { - rlog(LOG_WARN, "Starting with no initial connection to Redis %s !", - endpoint_print_buf(&r->endpoint)); - return r; + if (r->no_redis_required) { + rlog(LOG_WARN, "Starting with no initial connection to Redis %s !", + endpoint_print_buf(&r->endpoint)); + return r; + } + goto err; } // redis is connected rlog(LOG_INFO, "Established initial connection to Redis %s", endpoint_print_buf(&r->endpoint)); r->state = REDIS_STATE_CONNECTED; - return r; + +err: + mutex_destroy(&r->lock); + g_slice_free1(sizeof(*r), r); + return NULL; } @@ -1131,7 +1139,7 @@ int redis_restore(struct callmaster *m, struct redis *r) { mutex_init(&ctx.r_m); g_queue_init(&ctx.r_q); for (i = 0; i < RESTORE_NUM_THREADS; i++) - g_queue_push_tail(&ctx.r_q, redis_new(&r->endpoint, r->db, r->auth, r->role)); + g_queue_push_tail(&ctx.r_q, redis_new(&r->endpoint, r->db, r->auth, r->role, r->no_redis_required)); gtp = g_thread_pool_new(restore_thread, &ctx, RESTORE_NUM_THREADS, TRUE, NULL); for (i = 0; i < calls->elements; i++) { diff --git a/daemon/redis.h b/daemon/redis.h index 8c0e15348..037fab041 100644 --- a/daemon/redis.h +++ b/daemon/redis.h @@ -42,6 +42,7 @@ struct redis { unsigned int pipeline; int state; + int no_redis_required; }; struct redis_hash { redisReply *rr; @@ -86,7 +87,7 @@ INLINE gboolean g_hash_table_insert_check(GHashTable *h, gpointer k, gpointer v) -struct redis *redis_new(const endpoint_t *, int, const char *, enum redis_role); +struct redis *redis_new(const endpoint_t *, int, const char *, enum redis_role, int no_redis_required); int redis_restore(struct callmaster *, struct redis *); void redis_update(struct call *, struct redis *); void redis_delete(struct call *, struct redis *); diff --git a/debian/ngcp-rtpengine-daemon.default b/debian/ngcp-rtpengine-daemon.default index f9b56f89c..ed69e24bb 100644 --- a/debian/ngcp-rtpengine-daemon.default +++ b/debian/ngcp-rtpengine-daemon.default @@ -21,6 +21,7 @@ TABLE=0 # REDIS_WRITE=127.0.0.1:6379 # REDIS_WRITE_DB=1 # REDIS_WRITE_AUTH_PW=foobar +# NO_REDIS_REQUIRED=yes # B2B_URL=http://127.0.0.1:8090/ # LOG_LEVEL=6 # LOG_FACILITY=daemon diff --git a/debian/ngcp-rtpengine-daemon.init b/debian/ngcp-rtpengine-daemon.init index f1bbfd885..bbba8aa0d 100755 --- a/debian/ngcp-rtpengine-daemon.init +++ b/debian/ngcp-rtpengine-daemon.init @@ -66,6 +66,7 @@ fi [ -z "$REDIS_AUTH_PW" ] || export RTPENGINE_REDIS_AUTH_PW="$REDIS_AUTH_PW" [ -z "$REDIS_WRITE" -o -z "$REDIS_WRITE_DB" ] || OPTIONS="$OPTIONS --redis-write=$REDIS_WRITE/$REDIS_WRITE_DB" [ -z "$REDIS_WRITE_AUTH_PW" ] || export RTPENGINE_REDIS_WRITE_AUTH_PW="$REDIS_WRITE_AUTH_PW" +[ -z "$NO_REDIS_REQUIRED" -o \( "$NO_REDIS_REQUIRED" != "1" -a "$NO_REDIS_REQUIRED" != "yes" \) ] || OPTIONS="$OPTIONS --no-redis-required" [ -z "$B2B_URL" ] || OPTIONS="$OPTIONS --b2b-url=$B2B_URL" [ -z "$NO_FALLBACK" -o \( "$NO_FALLBACK" != "1" -a "$NO_FALLBACK" != "yes" \) ] || OPTIONS="$OPTIONS --no-fallback" OPTIONS="$OPTIONS --table=$TABLE"