diff options
author | Simo Sorce <idra@samba.org> | 2008-10-03 13:01:57 -0400 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2008-10-04 11:14:49 -0400 |
commit | 4458162a943a432b5f8517182e2ee7aab2590f85 (patch) | |
tree | 7b29a7ed33632565e216509f6f010be2dbbbb19c /server/monitor.c | |
parent | 9bd63b97c9c3132a0b3c8c6bd1c67f8c31a54c3c (diff) | |
download | sssd-4458162a943a432b5f8517182e2ee7aab2590f85.tar.gz sssd-4458162a943a432b5f8517182e2ee7aab2590f85.tar.bz2 sssd-4458162a943a432b5f8517182e2ee7aab2590f85.zip |
Initital server code.
Includes test monitor task.
Diffstat (limited to 'server/monitor.c')
-rw-r--r-- | server/monitor.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/server/monitor.c b/server/monitor.c new file mode 100644 index 00000000..93ebeddc --- /dev/null +++ b/server/monitor.c @@ -0,0 +1,168 @@ +/* + SSSD + + Service monitor + + Copyright (C) Simo Sorce 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <string.h> +#include <sys/time.h> +#include "../events/events.h" +#include "util/util.h" +#include "service.h" + +struct mt_ctx { + struct task_server *task; + struct fd_event *test_fde; + int test_fd; +}; + +static void set_nonblocking(int fd) +{ + unsigned v; + v = fcntl(fd, F_GETFL, 0); + fcntl(fd, F_SETFL, v | O_NONBLOCK); +} + +static void set_close_on_exec(int fd) +{ + unsigned v; + v = fcntl(fd, F_GETFD, 0); + fcntl(fd, F_SETFD, v | FD_CLOEXEC); +} + +static void set_test_timed_event(struct event_context *ev, + struct mt_ctx *ctx); + +static void test_timed_handler(struct event_context *ev, + struct timed_event *te, + struct timeval t, void *ptr) +{ + struct mt_ctx *ctx = talloc_get_type(ptr, struct mt_ctx); + + fprintf(stdout, "."); + fflush(stdout); + + set_test_timed_event(ev, ctx); +} + +static void set_test_timed_event(struct event_context *ev, + struct mt_ctx *ctx) +{ + struct timed_event *te = NULL; + struct timeval tv; + + gettimeofday(&tv, NULL); + tv.tv_sec += 2; + tv.tv_usec = 0; + te = event_add_timed(ev, ctx, tv, test_timed_handler, ctx); + if (te == NULL) { + DEBUG(0, ("failed to add event!\n")); + task_server_terminate(ctx->task, "fatal error initializing service\n"); + } +} + +static void test_fd_handler(struct event_context *ev, + struct fd_event *fde, + uint16_t flags, void *ptr) +{ + /* accept and close */ + struct mt_ctx *ctx = talloc_get_type(ptr, struct mt_ctx); + struct sockaddr_un addr; + socklen_t len; + int fd; + + memset(&addr, 0, sizeof(addr)); + len = sizeof(addr); + fd = accept(ctx->test_fd, (struct sockaddr *)&addr, &len); + if (fd == -1) { + return; + } + + close(fd); + return; +} + +/* create a unix socket and listen to it */ +static void set_test_fd_event(struct event_context *ev, + struct mt_ctx *ctx) +{ + struct sockaddr_un addr; + const char *sock_name = "/tmp/foo/test_sock"; + + /* make sure we have no old sockets around */ + unlink(sock_name); + + ctx->test_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (ctx->test_fd == -1) { + return; + } + + set_nonblocking(ctx->test_fd); + set_close_on_exec(ctx->test_fd); + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, sock_name, sizeof(addr.sun_path)); + + if (bind(ctx->test_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { + DEBUG(0,("Unable to bind on socket '%s'\n", sock_name)); + goto failed; + } + if (listen(ctx->test_fd, 10) != 0) { + DEBUG(0,("Unable to listen on socket '%s'\n", sock_name)); + goto failed; + } + + ctx->test_fde = event_add_fd(ev, ctx, ctx->test_fd, + EVENT_FD_READ, test_fd_handler, ctx); + + return; + +failed: + close(ctx->test_fd); +} + +void monitor_task_init(struct task_server *task) +{ + struct mt_ctx *ctx; + + task_server_set_title(task, "sssd[monitor]"); + + ctx = talloc_zero(task, struct mt_ctx); + if (!ctx) { + task_server_terminate(task, "fatal error initializing mt_ctx\n"); + return; + } + ctx->task = task; + + /* without an fd event the event system just exits. + * We must always have at least one file base event around + */ + set_test_fd_event(task->event_ctx, ctx); + + /* our test timed event */ + set_test_timed_event(task->event_ctx, ctx); + + fprintf(stdout, "test monitor process started!\n"); +} |