From edd05ae9d671c9209d630c68a1aff5c5cca8ee32 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 20 Nov 2008 08:16:52 -0500 Subject: Start conversion from a fork() and live to a fork()/exec() model. To start the dameon now you need to pass the option -s monitor Still have some problems communicating with children. --- server/monitor.c | 60 ++++++++++++++++++----- server/monitor.h | 6 +-- server/nss/nsssrv.c | 42 ++++++++--------- server/nss/nsssrv.h | 3 +- server/providers/data_provider.c | 40 +++++++--------- server/providers/data_provider.h | 1 - server/providers/providers.h | 4 +- server/sbus/sssd_dbus_common.c | 2 +- server/sbus/sssd_dbus_connection.c | 33 ++++++------- server/sbus/sssd_dbus_server.c | 18 +++---- server/server.c | 97 ++++++++++++++++++++++++++++---------- server/server.mk | 2 - server/util/become_daemon.c | 65 ++++++++++++++++++++++++- server/util/debug.c | 1 + server/util/util.h | 6 ++- 15 files changed, 258 insertions(+), 122 deletions(-) (limited to 'server') diff --git a/server/monitor.c b/server/monitor.c index 40f25c339..1d0e3dcfe 100644 --- a/server/monitor.c +++ b/server/monitor.c @@ -1,4 +1,4 @@ -/* +/* SSSD Service monitor @@ -19,19 +19,23 @@ along with this program. If not, see . */ +#define _GNU_SOURCE +#include +#include #include #include #include #include #include "../events/events.h" #include "util/util.h" -#include "service.h" #include "confdb/confdb.h" #include "monitor.h" #include "dbus/dbus.h" #include "sbus/sssd_dbus.h" #include "sbus_interfaces.h" +static int start_service(const char *name, pid_t *retpid); + /* ping time cannot be less then once every few seconds or the * monitor will get crazy hammering children with messages */ #define MONITOR_MIN_PING_TIME 2 @@ -138,7 +142,7 @@ static int monitor_dbus_init(struct mt_ctx *ctx) return ENOMEM; } sd_ctx->methods = monitor_methods; - sd_ctx->message_handler = sbus_message_handler; /* Use the default message_handler */ + sd_ctx->message_handler = sbus_message_handler; ret = sbus_new_server(ctx->ev, sd_ctx, sbus_address, dbus_service_init, ctx); @@ -161,13 +165,14 @@ static void tasks_check_handler(struct event_context *ev, break; case ECHILD: - DEBUG(1,("Process is stopped!\n")); + DEBUG(1,("Process (%s) is stopped!\n", svc->name)); process_alive = false; break; default: /* TODO: should we tear down it ? */ - DEBUG(1,("Checking for service process failed!!\n")); + DEBUG(1,("Checking for service %s(%d) failed!!\n", + svc->name, svc->pid)); break; } @@ -179,12 +184,12 @@ static void tasks_check_handler(struct event_context *ev, break; case ENXIO: - DEBUG(1,("Connection with child not available! (yet)\n")); + DEBUG(1,("Child (%s) not responding! (yet)\n", svc->name)); break; default: /* TODO: should we tear it down ? */ - DEBUG(1,("Sending a message to the service failed!!\n")); + DEBUG(1,("Sending a message to service (%s) failed!!\n", svc->name)); break; } @@ -193,7 +198,9 @@ static void tasks_check_handler(struct event_context *ev, /* too long since we last heard of this process */ ret = kill(svc->pid, SIGUSR1); if (ret != EOK) { - DEBUG(0,("Sending signal to child failed! Ignore and pretend child is dead.\n")); + DEBUG(0,("Sending signal to child (%s:%d) failed! " + "Ignore and pretend child is dead.\n", + svc->name, svc->pid)); } process_alive = false; } @@ -216,7 +223,7 @@ static void tasks_check_handler(struct event_context *ev, return; } - ret = server_service_init(svc->name, svc->mt_ctx->ev, &svc->pid); + ret = start_service(svc->name, &svc->pid); if (ret != EOK) { DEBUG(0,("Failed to restart service '%s'\n", svc->name)); talloc_free(svc); @@ -280,9 +287,9 @@ int get_monitor_config(struct mt_ctx *ctx) return EOK; } -int start_monitor(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx, - struct confdb_ctx *cdb) +int monitor_process_init(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx, + struct confdb_ctx *cdb) { struct mt_ctx *ctx; struct mt_svc *svc; @@ -318,7 +325,7 @@ int start_monitor(TALLOC_CTX *mem_ctx, svc->name = ctx->services[i]; svc->mt_ctx = ctx; - ret = server_service_init(svc->name, event_ctx, &svc->pid); + ret = start_service(svc->name, &svc->pid); if (ret != EOK) { DEBUG(0,("Failed to start service '%s'\n", svc->name)); talloc_free(svc); @@ -659,3 +666,30 @@ static int service_check_alive(struct mt_svc *svc) return ECHILD; } + +static int start_service(const char *name, pid_t *retpid) +{ + char **args; + pid_t pid; + + pid = fork(); + if (pid != 0) { + if (pid == -1) { + return ECHILD; + } + + *retpid = pid; + + return EOK; + } + + /* child */ + + args = calloc(4, sizeof(char *)); + asprintf(&args[0], "sssd[%s]", name); + args[1] = strdup("-s"); + args[2] = strdup(name); + if (!args[0] || !args[1] || !args[2]) exit(2); + execvp("./sbin/sssd", args); + exit(1); +} diff --git a/server/monitor.h b/server/monitor.h index cb53916f6..8899c51a4 100644 --- a/server/monitor.h +++ b/server/monitor.h @@ -22,8 +22,8 @@ #ifndef _MONITOR_H_ #define _MONITOR_H_ -int start_monitor(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx, - struct confdb_ctx *cdb); +int monitor_process_init(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx, + struct confdb_ctx *cdb); #endif /* _MONITOR_H */ diff --git a/server/nss/nsssrv.c b/server/nss/nsssrv.c index 0181644d4..764de8460 100644 --- a/server/nss/nsssrv.c +++ b/server/nss/nsssrv.c @@ -413,49 +413,45 @@ done: return retval; } -void nss_task_init(struct task_server *task) +int nss_process_init(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct confdb_ctx *cdb) { struct nss_ctx *nctx; int ret; - task_server_set_title(task, "sssd[nsssrv]"); - - nctx = talloc_zero(task, struct nss_ctx); + nctx = talloc_zero(mem_ctx, struct nss_ctx); if (!nctx) { - task_server_terminate(task, "fatal error initializing nss_ctx\n"); - return; - } - nctx->ev = task->event_ctx; - nctx->task = task; - - ret = confdb_init(task, task->event_ctx, &nctx->cdb); - if (ret != EOK) { - task_server_terminate(task, "fatal error initializing confdb\n"); - return; + DEBUG(0, ("fatal error initializing nss_ctx\n")); + return ENOMEM; } + nctx->ev = ev; + nctx->cdb = cdb; ret = nss_init_domains(nctx); if (ret != EOK) { - task_server_terminate(task, "fatal error setting up domain map\n"); - return; + DEBUG(0, ("fatal error setting up domain map\n")); + return ret; } ret = nss_sbus_init(nctx); if (ret != EOK) { - task_server_terminate(task, "fatal error setting up message bus\n"); - return; + DEBUG(0, ("fatal error setting up message bus\n")); + return ret; } - ret = nss_ldb_init(nctx, nctx->ev, nctx->cdb, &nctx->lctx); + ret = nss_ldb_init(nctx, ev, cdb, &nctx->lctx); if (ret != EOK) { - task_server_terminate(task, "fatal error initializing nss_ctx\n"); - return; + DEBUG(0, ("fatal error initializing nss_ctx\n")); + return ret; } /* after all initializations we are ready to listen on our socket */ ret = set_unix_socket(nctx); if (ret != EOK) { - task_server_terminate(task, "fatal error initializing socket\n"); - return; + DEBUG(0, ("fatal error initializing socket\n")); + return ret; } + + return EOK; } diff --git a/server/nss/nsssrv.h b/server/nss/nsssrv.h index 5d49e79fe..cf07ad490 100644 --- a/server/nss/nsssrv.h +++ b/server/nss/nsssrv.h @@ -43,7 +43,6 @@ struct nss_sbus_ctx { struct nss_ctx { struct event_context *ev; - struct task_server *task; struct fd_event *lfde; int lfd; struct nss_ldb_ctx *lctx; @@ -76,7 +75,7 @@ struct cli_request { /* from nsssrv_packet.c */ int nss_packet_new(TALLOC_CTX *mem_ctx, size_t size, - enum sss_nss_command cmd, + enum sss_nss_command cmd, struct nss_packet **rpacket); int nss_packet_grow(struct nss_packet *packet, size_t size); int nss_packet_recv(struct nss_packet *packet, int fd); diff --git a/server/providers/data_provider.c b/server/providers/data_provider.c index 43c80128d..df9cfdf6f 100644 --- a/server/providers/data_provider.c +++ b/server/providers/data_provider.c @@ -367,48 +367,44 @@ done: return ret; } -void dp_task_init(struct task_server *task) +int dp_process_init(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct confdb_ctx *cdb) { struct dp_ctx *dpctx; int ret; - task_server_set_title(task, "sssd[datap]"); - - dpctx = talloc_zero(task, struct dp_ctx); + dpctx = talloc_zero(mem_ctx, struct dp_ctx); if (!dpctx) { - task_server_terminate(task, "fatal error initializing dp_ctx\n"); - return; - } - dpctx->ev = task->event_ctx; - dpctx->task = task; - - ret = confdb_init(task, task->event_ctx, &dpctx->cdb); - if (ret != EOK) { - task_server_terminate(task, "fatal error initializing confdb\n"); - return; + DEBUG(0, ("fatal error initializing dp_ctx\n")); + return ENOMEM; } + dpctx->ev = ev; + dpctx->cdb = cdb; ret = dp_db_init(dpctx); if (ret != EOK) { - task_server_terminate(task, "fatal error opening database\n"); - return; + DEBUG(0, ("fatal error opening database\n")); + return ret; } ret = dp_monitor_init(dpctx); if (ret != EOK) { - task_server_terminate(task, "fatal error setting up monitor bus\n"); - return; + DEBUG(0, ("fatal error setting up monitor bus\n")); + return ret; } ret = dp_srv_init(dpctx); if (ret != EOK) { - task_server_terminate(task, "fatal error setting up server bus\n"); - return; + DEBUG(0, ("fatal error setting up server bus\n")); + return ret; } ret = init_data_providers(dpctx); if (ret != EOK) { - task_server_terminate(task, "fatal error initializing data providers\n"); - return; + DEBUG(0, ("fatal error initializing data providers\n")); + return ret; } + + return EOK; } diff --git a/server/providers/data_provider.h b/server/providers/data_provider.h index a5c0a4177..36f921896 100644 --- a/server/providers/data_provider.h +++ b/server/providers/data_provider.h @@ -58,7 +58,6 @@ struct dp_sbus_ctx { struct dp_ctx { struct event_context *ev; - struct task_server *task; struct confdb_ctx *cdb; struct ldb_context *ldb; struct dp_sbus_ctx *sbus_ctx; diff --git a/server/providers/providers.h b/server/providers/providers.h index a1cc1fc42..19eab827c 100644 --- a/server/providers/providers.h +++ b/server/providers/providers.h @@ -19,4 +19,6 @@ along with this program. If not, see . */ -void dp_task_init(struct task_server *task); +int dp_process_init(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct confdb_ctx *cdb); diff --git a/server/sbus/sssd_dbus_common.c b/server/sbus/sssd_dbus_common.c index 0ea66ccb3..5e724a3ac 100644 --- a/server/sbus/sssd_dbus_common.c +++ b/server/sbus/sssd_dbus_common.c @@ -22,7 +22,7 @@ struct timeval _dbus_timeout_get_interval_tv(int interval) { void sbus_remove_watch(DBusWatch *watch, void *data) { struct fd_event *fde; - DEBUG(2, ("%lX\n", watch)); + DEBUG(5, ("%lX\n", watch)); fde = talloc_get_type(dbus_watch_get_data(watch), struct fd_event); /* Freeing the event object will remove it from the event loop */ diff --git a/server/sbus/sssd_dbus_connection.c b/server/sbus/sssd_dbus_connection.c index 996c0e85e..e587bd9b6 100644 --- a/server/sbus/sssd_dbus_connection.c +++ b/server/sbus/sssd_dbus_connection.c @@ -49,10 +49,10 @@ static void sbus_dispatch(struct event_context *ev, dct_ctx = talloc_get_type(data, struct sbus_conn_ctx); conn = dct_ctx->conn; - DEBUG(3, ("conn: %lX\n", conn)); + DEBUG(4, ("conn: %lX\n", conn)); if((dct_ctx->disconnect) || (!dbus_connection_get_is_connected(conn))) { - DEBUG(0,("Connection is not open for dispatching.\n")); + DEBUG(4,("Connection is not open for dispatching.\n")); /* * Free the connection object. * This will invoke the destructor for the connection @@ -67,7 +67,7 @@ static void sbus_dispatch(struct event_context *ev, */ ret = dbus_connection_get_dispatch_status(conn); if (ret != DBUS_DISPATCH_COMPLETE) { - DEBUG(2,("Dispatching.\n")); + DEBUG(4,("Dispatching.\n")); dbus_connection_dispatch(conn); } @@ -78,7 +78,7 @@ static void sbus_dispatch(struct event_context *ev, if (ret != DBUS_DISPATCH_COMPLETE) { new_event = event_add_timed(ev, dct_ctx, tv, sbus_dispatch, dct_ctx); if (new_event == NULL) { - DEBUG(0,("Could not add dispatch event!\n")); + DEBUG(2,("Could not add dispatch event!\n")); /* TODO: Calling exit here is bad */ exit(1); @@ -97,7 +97,7 @@ static void sbus_conn_read_write_handler(struct event_context *ev, struct sbus_conn_watch_ctx *conn_w_ctx; conn_w_ctx = talloc_get_type(data, struct sbus_conn_watch_ctx); - DEBUG(0,("Connection is open for read/write.\n")); + DEBUG(4,("Connection is open for read/write.\n")); dbus_connection_ref(conn_w_ctx->top->conn); if (flags & EVENT_FD_READ) { dbus_watch_handle(conn_w_ctx->watch, DBUS_WATCH_READABLE); @@ -144,7 +144,7 @@ static dbus_bool_t sbus_add_conn_watch(DBusWatch *watch, void *data) if (event_flags == 0) return FALSE; - DEBUG(2,("%lX: %d, %d=%s\n", + DEBUG(5,("%lX: %d, %d=%s\n", watch, conn_w_ctx->fd, event_flags, event_flags==EVENT_FD_READ?"READ":"WRITE")); @@ -256,7 +256,8 @@ static void sbus_conn_wakeup_main(void *data) te = event_add_timed(dct_ctx->ev, dct_ctx, tv, sbus_dispatch, dct_ctx); if (te == NULL) { - DEBUG(0,("Could not add dispatch event!\n")); + DEBUG(2,("Could not add dispatch event!\n")); + /* TODO: Calling exit here is bad */ exit(1); } } @@ -275,7 +276,7 @@ int sbus_add_connection(TALLOC_CTX *ctx, dbus_bool_t dbret; struct sbus_conn_ctx *dt_ctx; - DEBUG(0,("Adding connection %lX\n", dbus_conn)); + DEBUG(5,("Adding connection %lX\n", dbus_conn)); dt_ctx = talloc_zero(ctx, struct sbus_conn_ctx); dt_ctx->ev = ev; dt_ctx->conn = dbus_conn; @@ -298,7 +299,7 @@ int sbus_add_connection(TALLOC_CTX *ctx, sbus_toggle_conn_watch, dt_ctx, NULL); if (!dbret) { - DEBUG(0,("Error setting up D-BUS connection watch functions\n")); + DEBUG(2,("Error setting up D-BUS connection watch functions\n")); return EIO; } @@ -309,7 +310,7 @@ int sbus_add_connection(TALLOC_CTX *ctx, sbus_toggle_conn_timeout, dt_ctx, NULL); if (!dbret) { - DEBUG(0,("Error setting up D-BUS server timeout functions\n")); + DEBUG(2,("Error setting up D-BUS server timeout functions\n")); /* FIXME: free resources ? */ return EIO; } @@ -351,7 +352,7 @@ int sbus_new_connection(TALLOC_CTX *ctx, struct event_context *ev, /* Open a shared D-BUS connection to the address */ dbus_conn = dbus_connection_open(address, &dbus_error); if (!dbus_conn) { - DEBUG(0, ("Failed to open connection: name=%s, message=%s\n", + DEBUG(1, ("Failed to open connection: name=%s, message=%s\n", dbus_error.name, dbus_error.message)); return EIO; } @@ -394,7 +395,7 @@ int sbus_default_connection_destructor(void *ctx) struct sbus_conn_ctx *dct_ctx; dct_ctx = talloc_get_type(ctx, struct sbus_conn_ctx); - DEBUG(3, ("Invoking default destructor on connection %lX\n", dct_ctx->conn)); + DEBUG(5, ("Invoking default destructor on connection %lX\n", dct_ctx->conn)); if (dct_ctx->connection_type == SBUS_CONN_TYPE_PRIVATE) { /* Private connections must be closed explicitly */ dbus_connection_close(dct_ctx->conn); @@ -403,7 +404,7 @@ int sbus_default_connection_destructor(void *ctx) } else { /* Critical Error! */ - DEBUG(0,("Critical Error, connection_type is neither shared nor private!\n")); + DEBUG(1,("Critical Error, connection_type is neither shared nor private!\n")); return -1; } @@ -430,7 +431,7 @@ void sbus_disconnect (struct sbus_conn_ctx *dct_ctx) return; } - DEBUG(2,("Disconnecting %lX\n", dct_ctx->conn)); + DEBUG(5,("Disconnecting %lX\n", dct_ctx->conn)); dbus_connection_ref(dct_ctx->conn); dct_ctx->disconnect = 1; @@ -460,7 +461,7 @@ void sbus_disconnect (struct sbus_conn_ctx *dct_ctx) /* Finalize the connection */ sbus_default_connection_destructor(dct_ctx); dbus_connection_unref(dct_ctx->conn); - DEBUG(2,("Disconnected %lX\n", dct_ctx->conn)); + DEBUG(5,("Disconnected %lX\n", dct_ctx->conn)); } /* messsage_handler @@ -505,7 +506,7 @@ DBusHandlerResult sbus_message_handler(DBusConnection *conn, /* FIXME: check if we didn't find any matching method */ } - DEBUG(2, ("Method %s complete. Reply was %srequested.\n", method, reply?"":"not ")); + DEBUG(5, ("Method %s complete. Reply was %srequested.\n", method, reply?"":"not ")); if (reply) { dbus_connection_send(conn, reply, NULL); diff --git a/server/sbus/sssd_dbus_server.c b/server/sbus/sssd_dbus_server.c index 3b3f9f1ad..abc9c8635 100644 --- a/server/sbus/sssd_dbus_server.c +++ b/server/sbus/sssd_dbus_server.c @@ -113,7 +113,7 @@ static dbus_bool_t sbus_add_srv_watch(DBusWatch *watch, void *data) if (flags & DBUS_WATCH_WRITABLE) { event_flags |= EVENT_FD_WRITE; } - DEBUG(2,("%lX: %d, %d=%s\n", watch, svw_ctx->fd, event_flags, event_flags==EVENT_FD_READ?"READ":"WRITE")); + DEBUG(5,("%lX: %d, %d=%s\n", watch, svw_ctx->fd, event_flags, event_flags==EVENT_FD_READ?"READ":"WRITE")); svw_ctx->fde = event_add_fd(dt_ctx->ev, svw_ctx, svw_ctx->fd, event_flags, sbus_srv_read_write_handler, @@ -208,24 +208,24 @@ static void sbus_server_init_new_connection(DBusServer *server, struct sbus_method_ctx *iter; int ret; - DEBUG(3,("Entering.\n")); + DEBUG(5,("Entering.\n")); srv_ctx = talloc_get_type(data, struct sbus_srv_ctx); if (srv_ctx == NULL) { return; } - DEBUG(3,("Adding connection %lX.\n", conn)); + DEBUG(5,("Adding connection %lX.\n", conn)); ret = sbus_add_connection(srv_ctx, srv_ctx->ev, conn, &conn_ctx, SBUS_CONN_TYPE_PRIVATE); if (ret != 0) { dbus_connection_close(conn); - DEBUG(3,("Closing connection (failed setup)")); + DEBUG(5,("Closing connection (failed setup)")); return; } dbus_connection_ref(conn); - DEBUG(2,("Got a connection\n")); + DEBUG(5,("Got a connection\n")); /* Set up global methods */ iter = srv_ctx->sd_ctx; @@ -266,12 +266,12 @@ int sbus_new_server(struct event_context *ev, struct sbus_method_ctx *ctx, dbus_error_init(&dbus_error); dbus_server = dbus_server_listen(address, &dbus_error); if (!dbus_server) { - DEBUG(0,("dbus_server_listen failed! (name=%s, message=%s)\n", + DEBUG(1,("dbus_server_listen failed! (name=%s, message=%s)\n", dbus_error.name, dbus_error.message)); return EIO; } - DEBUG(2, ("D-BUS Server listening on %s\n", + DEBUG(3, ("D-BUS Server listening on %s\n", dbus_server_get_address(dbus_server))); srv_ctx = talloc_zero(ev, struct sbus_srv_ctx); @@ -299,7 +299,7 @@ int sbus_new_server(struct event_context *ev, struct sbus_method_ctx *ctx, sbus_toggle_srv_watch, srv_ctx, NULL); if (!dbret) { - DEBUG(0, ("Error setting up D-BUS server watch functions")); + DEBUG(4, ("Error setting up D-BUS server watch functions")); talloc_free(srv_ctx); return EIO; } @@ -311,7 +311,7 @@ int sbus_new_server(struct event_context *ev, struct sbus_method_ctx *ctx, sbus_toggle_srv_timeout, srv_ctx, NULL); if (!dbret) { - DEBUG(0,("Error setting up D-BUS server timeout functions")); + DEBUG(4,("Error setting up D-BUS server timeout functions")); dbus_server_set_watch_functions(srv_ctx->server, NULL, NULL, NULL, NULL, NULL); talloc_free(srv_ctx); diff --git a/server/server.c b/server/server.c index 01bcf29c3..15dbb8d9c 100644 --- a/server/server.c +++ b/server/server.c @@ -36,8 +36,9 @@ #include "providers/providers.h" #include "monitor.h" -extern void monitor_task_init(struct task_server *task); -extern void nss_task_init(struct task_server *task); +extern int nss_process_init(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct confdb_ctx *cdb); static void sig_hup(int sig) { @@ -107,11 +108,14 @@ static void server_stdin_handler(struct event_context *event_ctx, struct fd_even } } +#define PID_PATH "/var/run/" + /* main server. */ int main(int argc, const char *argv[]) { + char *service = NULL; bool opt_daemon = false; bool opt_interactive = false; int opt; @@ -120,7 +124,10 @@ int main(int argc, const char *argv[]) struct confdb_ctx *confdb_ctx; TALLOC_CTX *mem_ctx; uint16_t stdin_event_flags; - int status; + int ret = EOK; + bool is_monitor = false; + + debug_prg_name = argv[0]; enum { OPT_DAEMON = 1000, @@ -132,6 +139,10 @@ int main(int argc, const char *argv[]) "Become a daemon (default)", NULL }, {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)", NULL}, + {"service", 's', POPT_ARG_STRING, &service, 0, + "Executes a specific service instead of the monitor", NULL}, + {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, + "Executes a specific service instead of the monitor", NULL}, { NULL } }; @@ -148,19 +159,36 @@ int main(int argc, const char *argv[]) fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); - exit(1); + return 1; } } - if (opt_daemon && opt_interactive) { - fprintf(stderr,"\nERROR: " - "Option -i|--interactive is not allowed together with -D|--daemon\n\n"); - poptPrintUsage(pc, stderr, 0); - exit(1); - } else if (!opt_interactive) { - /* default is --daemon */ - opt_daemon = true; - } + if (!service) { + fprintf(stderr,"\nERROR: No service specified\n\n"); + return 5; + } + + if (strcmp(service, "monitor") == 0) is_monitor = true; + + if (is_monitor) { + if (opt_daemon && opt_interactive) { + fprintf(stderr,"\nERROR: " + "Option -i|--interactive is not allowed together with -D|--daemon\n\n"); + poptPrintUsage(pc, stderr, 0); + return 1; + } else if (!opt_interactive) { + /* default is --daemon */ + opt_daemon = true; + } + } else { + if (opt_daemon || opt_interactive) { + fprintf(stderr,"\nERROR: " + "Options -i or -D not allowed with -s (service)\n\n"); + poptPrintUsage(pc, stderr, 0); + return 1; + } + + } poptFreeContext(pc); @@ -173,12 +201,16 @@ int main(int argc, const char *argv[]) if (opt_daemon) { DEBUG(3,("Becoming a daemon.\n")); become_daemon(true); - } -/* pidfile_create(PID_DIR, argv[0]); */ + ret = pidfile(PID_PATH, "sssd"); + if (ret != EOK) { + fprintf(stderr, "\nERROR: PID File reports daemon already running!\n"); + return 1; + } + } - /* the event context is the top level structure in smbd. Everything else - should hang off that */ + /* the event context is the top level structure. + * Everything else should hang off that */ event_ctx = event_context_init(talloc_autofree_context()); if (event_ctx == NULL) { DEBUG(0,("The event context initialiaziton failed\n")); @@ -191,8 +223,8 @@ int main(int argc, const char *argv[]) return 1; } - status = confdb_init(mem_ctx, event_ctx, &confdb_ctx); - if (status != EOK) { + ret = confdb_init(mem_ctx, event_ctx, &confdb_ctx); + if (ret != EOK) { DEBUG(0,("The confdb initialization failed\n")); return 1; } @@ -213,16 +245,29 @@ int main(int argc, const char *argv[]) server_stdin_handler, discard_const(argv[0])); - /* Services */ - register_server_service("nss", nss_task_init); - register_server_service("dp", dp_task_init); + /* What are we asked to run ? */ + if (is_monitor) { + /* the monitor */ + ret = monitor_process_init(mem_ctx, event_ctx, confdb_ctx); - /* the monitor starts the services */ - status = start_monitor(mem_ctx, event_ctx, confdb_ctx); - if (status != EOK) { - return 1; + } else { + + if (strcmp(service, "nss") == 0) { + ret = nss_process_init(mem_ctx, event_ctx, confdb_ctx); + + } else if (strcmp(service, "dp") == 0) { + ret = dp_process_init(mem_ctx, event_ctx, confdb_ctx); + + } else { + fprintf(stderr, + "\nERROR: Unknown Service specified [%s]\n", + service); + ret = EINVAL; + } } + if (ret != EOK) return 3; + /* wait for events - this is where smbd sits for most of its life */ event_loop_wait(event_ctx); diff --git a/server/server.mk b/server/server.mk index ee5f036a3..1196cc564 100644 --- a/server/server.mk +++ b/server/server.mk @@ -2,8 +2,6 @@ SERVER_OBJ = \ server.o \ monitor.o \ process.o \ - service.o \ - service_task.o \ util/debug.o \ util/signal.o \ util/become_daemon.o \ diff --git a/server/util/become_daemon.c b/server/util/become_daemon.c index c753d08c0..4a940eaa1 100644 --- a/server/util/become_daemon.c +++ b/server/util/become_daemon.c @@ -21,7 +21,8 @@ along with this program. If not, see . */ - +#define _GNU_SOURCE +#include #include #include #include @@ -96,3 +97,65 @@ void become_daemon(bool Fork) attach it to the logfile */ } +int pidfile(const char *path, const char *name) +{ + char pid_str[32]; + pid_t pid; + char *file; + int fd; + int ret; + + asprintf(&file, "%s/%s.pid", path, name); + + fd = open(file, O_RDONLY, 0644); + if (fd != -1) { + + pid_str[sizeof(pid_str) -1] = '\0'; + ret = read(fd, pid_str, sizeof(pid_str) -1); + if (ret > 0) { + /* let's check the pid */ + + pid = (pid_t)atoi(pid_str); + if (pid != 0) { + errno = 0; + ret = kill(pid, 0); + if (ret != 0 && errno != ESRCH) { + close(fd); + free(file); + return EEXIST; + } + } + } + + /* notihng in the file or no process */ + close(fd); + unlink(file); + + } else { + if (errno != ENOENT) { + free(file); + return EIO; + } + } + + fd = open(file, O_CREAT | O_WRONLY | O_EXCL, 0644); + if (fd == -1) { + free(file); + return EIO; + } + free(file); + + memset(pid_str, 0, sizeof(pid_str)); + snprintf(pid_str, sizeof(pid_str) -1, "%u\n", (unsigned int) getpid()); + + ret = write(fd, pid_str, strlen(pid_str)); + if (ret != strlen(pid_str)) { + close(fd); + return EIO; + } + + close(fd); + + return 0; +} + diff --git a/server/util/debug.c b/server/util/debug.c index 403ec8d2d..6fd6ccc3d 100644 --- a/server/util/debug.c +++ b/server/util/debug.c @@ -3,6 +3,7 @@ #include #include +const char *debug_prg_name = "sssd"; int debug_level = 3; void debug_fn(const char *format, ...) diff --git a/server/util/util.h b/server/util/util.h index bb5526e48..897e35419 100644 --- a/server/util/util.h +++ b/server/util/util.h @@ -6,16 +6,17 @@ #include "replace.h" #include "talloc.h" +extern const char *debug_prg_name; extern int debug_level; void debug_fn(const char *format, ...); #define DEBUG(level, body) do { \ if (level <= debug_level) { \ - debug_fn("%s[%s]: ", __location__, __FUNCTION__); \ + debug_fn("[%s] [%s] (%d): ", \ + debug_prg_name, __FUNCTION__, level); \ debug_fn body; \ } \ } while(0); -#define DEBUGADD(level, body) #ifndef discard_const #define discard_const(ptr) ((void *)((uintptr_t)(ptr))) @@ -35,6 +36,7 @@ void debug_fn(const char *format, ...); /* from become_daemon.c */ void become_daemon(bool Fork); +int pidfile(const char *path, const char *name); /* from signal.c */ #include -- cgit