summaryrefslogtreecommitdiffstats
path: root/source3/smbd/notifyd/notifyd.h
blob: 5ef8c4c8d09de5e23dc50e39784d1c0ed3ceb484 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 * Unix SMB/CIFS implementation.
 *
 * Copyright (C) Volker Lendecke 2014
 *
 * 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/>.
 */

#ifndef __NOTIFYD_NOTIFYD_H__
#define __NOTIFYD_NOTIFYD_H__

#include "includes.h"
#include "librpc/gen_ndr/notify.h"
#include "librpc/gen_ndr/messaging.h"
#include "lib/dbwrap/dbwrap.h"
#include "lib/dbwrap/dbwrap_rbt.h"
#include "messages.h"
#include "tdb.h"
#include "util_tdb.h"

/*
 * Filechangenotify based on asynchronous messages
 *
 * smbds talk to local notify daemons to inform them about paths they are
 * interested in. They also tell local notify daemons about changes they have
 * done to the file system. There's two message types from smbd to
 * notifyd. The first is used to inform notifyd about changes in notify
 * interest. These are only sent from smbd to notifyd if the SMB client issues
 * FileChangeNotify requests.
 */

/*
 * The notifyd implementation is designed to cope with multiple daemons taking
 * care of just a subset of smbds. The goal is to minimize the traffic between
 * the notify daemons. The idea behind this is a samba/ctdb cluster, but it
 * could also be used to spread the load of notifyd instances on a single
 * node, should this become a bottleneck. The following diagram illustrates
 * the setup. The numbers in the boxes are node:process ids.
 *
 *         +-----------+                  +-----------+
 *         |notifyd 0:5|------------------|notifyd 1:6|
 *         +-----------+                  +-----------+
 *            / |  \                         /    \
 *           /  |   \                       /      \
 *   +--------+ | +--------+        +--------+   +--------+
 *   |smbd 0:1| | |smbd 0:4|        |smbd 1:7|   |smbd 1:2|
 *   +--------+ | +--------+        +--------+   +--------+
 *              |
 *     	   +---------+
 *	   |smbd 0:20|
 *	   +---------+
 *
 * Suppose 0:1 and 0:4 are interested in changes for /foo and 0:20 creates the
 * file /foo/bar, if everything fully connected, 0:20 would have to send two
 * local messages, one to 0:1 and one to 0:4. With the notifyd design, 0:20
 * only has to send one message, it lets notifyd 0:5 do the hard work to
 * multicast the change to 0:1 and 0:4.
 *
 * Now lets assume 1:7 on the other node creates /foo/baz. It tells its
 * notifyd 1:6 about this change. All 1:6 will know about is that its peer
 * notifyd 0:5 is interested in the change. Thus it forwards the event to 0:5,
 * which sees it as if it came from just another local event creator. 0:5 will
 * multicast the change to 0:1 and 0:4. To prevent notify loops, the message
 * from 1:6 to 0:5 will carry a "proxied" flag, so that 0:5 will only forward
 * the event to local clients.
 */

/*
 * Data that notifyd maintains per smbd notify instance
 */
struct notify_instance {
	struct timespec creation_time;
	uint32_t filter;
	uint32_t subdir_filter;
	void *private_data;
};

/* MSG_SMB_NOTIFY_REC_CHANGE payload */
struct notify_rec_change_msg {
	struct notify_instance instance;
	char path[];
};

/*
 * The second message from smbd to notifyd is sent whenever an smbd makes a
 * file system change. It tells notifyd to inform all interested parties about
 * that change. This is the message that needs to be really fast in smbd
 * because it is called a lot.
 */

/* MSG_SMB_NOTIFY_TRIGGER payload */
struct notify_trigger_msg {
	struct timespec when;
	uint32_t action;
	uint32_t filter;
	char path[];
};

/*
 * In response to a MSG_SMB_NOTIFY_TRIGGER message notifyd walks its database
 * and sends out the following message to all interested clients
 */

/* MSG_PVFS_NOTIFY payload */
struct notify_event_msg {
	struct timespec when;
	void *private_data;
	uint32_t action;
	char path[];
};

struct sys_notify_context;
struct ctdbd_connection;

typedef int (*sys_notify_watch_fn)(TALLOC_CTX *mem_ctx,
				   struct sys_notify_context *ctx,
				   const char *path,
				   uint32_t *filter,
				   uint32_t *subdir_filter,
				   void (*callback)(struct sys_notify_context *ctx,
						    void *private_data,
						    struct notify_event *ev,
						    uint32_t filter),
				   void *private_data,
				   void *handle_p);

struct tevent_req *notifyd_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
				struct messaging_context *msg_ctx,
				struct ctdbd_connection *ctdbd_conn,
				sys_notify_watch_fn sys_notify_watch,
				struct sys_notify_context *sys_notify_ctx);
int notifyd_recv(struct tevent_req *req);

#endif