smbd: Implement a cleanup daemon
[samba.git] / source3 / smbd / smbd_cleanupd.c
1 /*
2  * Unix SMB/CIFS implementation.
3  *
4  * Copyright (C) Volker Lendecke 2015
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "replace.h"
21 #include "smbd_cleanupd.h"
22 #include "lib/util/tevent_ntstatus.h"
23 #include "lib/util/debug.h"
24
25 struct smbd_cleanupd_state {
26         pid_t parent_pid;
27 };
28
29 static void smbd_cleanupd_shutdown(struct messaging_context *msg,
30                                    void *private_data, uint32_t msg_type,
31                                    struct server_id server_id,
32                                    DATA_BLOB *data);
33 static void smbd_cleanupd_process_exited(struct messaging_context *msg,
34                                          void *private_data, uint32_t msg_type,
35                                          struct server_id server_id,
36                                          DATA_BLOB *data);
37
38 struct tevent_req *smbd_cleanupd_send(TALLOC_CTX *mem_ctx,
39                                       struct tevent_context *ev,
40                                       struct messaging_context *msg,
41                                       pid_t parent_pid)
42 {
43         struct tevent_req *req;
44         struct smbd_cleanupd_state *state;
45         NTSTATUS status;
46
47         req = tevent_req_create(mem_ctx, &state, struct smbd_cleanupd_state);
48         if (req == NULL) {
49                 return NULL;
50         }
51         state->parent_pid = parent_pid;
52
53         status = messaging_register(msg, req, MSG_SHUTDOWN,
54                                     smbd_cleanupd_shutdown);
55         if (tevent_req_nterror(req, status)) {
56                 return tevent_req_post(req, ev);
57         }
58
59         status = messaging_register(msg, req, MSG_SMB_NOTIFY_CLEANUP,
60                                     smbd_cleanupd_process_exited);
61         if (tevent_req_nterror(req, status)) {
62                 return tevent_req_post(req, ev);
63         }
64
65         return req;
66 }
67
68 static void smbd_cleanupd_shutdown(struct messaging_context *msg,
69                                    void *private_data, uint32_t msg_type,
70                                    struct server_id server_id,
71                                    DATA_BLOB *data)
72 {
73         struct tevent_req *req = talloc_get_type_abort(
74                 private_data, struct tevent_req);
75         tevent_req_done(req);
76 }
77
78 static void smbd_cleanupd_process_exited(struct messaging_context *msg,
79                                          void *private_data, uint32_t msg_type,
80                                          struct server_id server_id,
81                                          DATA_BLOB *data)
82 {
83         struct tevent_req *req = talloc_get_type_abort(
84                 private_data, struct tevent_req);
85         struct smbd_cleanupd_state *state = tevent_req_data(
86                 req, struct smbd_cleanupd_state);
87         pid_t pid;
88         bool unclean_shutdown;
89
90         if (data->length != (sizeof(pid) + sizeof(unclean_shutdown))) {
91                 DBG_WARNING("Got invalid length: %zu\n", data->length);
92                 return;
93         }
94
95         memcpy(&pid, data->data, sizeof(pid));
96         memcpy(&unclean_shutdown, data->data + sizeof(pid),
97                sizeof(unclean_shutdown));
98
99         DBG_DEBUG("%d exited %sclean\n", (int)pid,
100                   unclean_shutdown ? "un" : "");
101 }
102
103 NTSTATUS smbd_cleanupd_recv(struct tevent_req *req)
104 {
105         return tevent_req_simple_recv_ntstatus(req);
106 }