xref: /titanic_44/usr/src/uts/common/fs/zev/zev_callbacks.c (revision dde42681594ce662371ce2d747b012dd0cdfa1b0)
1 #include <sys/zfs_znode.h>
2 #include <sys/fs/zfs.h>
3 #include <sys/fs/zev.h>
4 #include <sys/zfs_events.h>
5 
6 #define ZEV_MAXSTRLEN		4096
7 
8 #define ZEV_ESCAPE(op, varname)						\
9 	char escaped_##varname[ZEV_MAXSTRLEN];				\
10 	if ((zev_escape(varname, escaped_##varname)) != 0) {		\
11 		zev_mq_printf(op, 1, "ERROR: ZEV_ESCAPE failed\n");	\
12 		return;							\
13 	}
14 
15 
16 static int
17 zev_escape(char *from, char *to)
18 {
19 	char *f = from;
20 	char *t = to;
21 	while (*f) {
22 		switch (*f) {
23 		case '\\':
24 			*t = '\\';  t++;
25 			*t = '\\';  t++;
26 			break;
27 		case '\'':
28 			*t = '\\';  t++;
29 			*t = '\'';  t++;
30 			break;
31 		case '\n':
32 			*t = '\\';  t++;
33 			*t = 'n';  t++;
34 			break;
35 		default:
36 			*t = *f;
37 			t++;
38 		}
39 		f++;
40 		if (*f && (t >= (to + ZEV_MAXSTRLEN - 2))) {
41 			*t = '\0';
42 			return (ENAMETOOLONG);
43 		}
44 	}
45 	*t = '\0';
46 	return (0);
47 }
48 
49 void
50 zev_zfs_mount_cb(vfs_t *vfs, vnode_t *mpt, char *dataset, boolean_t remount)
51 {
52 	zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data;
53 	if (zev_skip_pool(zfsvfs->z_os))
54 		return;
55 	/* we're watching this pool */
56 	ZEV_ESCAPE(ZEV_OP_ZFS_MOUNT, dataset);
57 	char mountpoint[MAXPATHLEN+1];
58 	/* expensive, but we don't have many mount ops. */
59 	if ((vnodetopath(NULL, mpt, mountpoint, sizeof(mountpoint),
60 	    kcred)) != 0) {
61 		zev_mq_printf(ZEV_OP_ZFS_MOUNT, 1,
62 		    "ERROR: ZEV_MOUNT: unresolvable mountpoint\n");
63 		return;
64 	}
65 	ZEV_ESCAPE(ZEV_OP_ZFS_MOUNT, mountpoint);
66 	zev_mq_printf(ZEV_OP_ZFS_MOUNT, 0,
67 	    "ZFS_MOUNT guid=%llu dataset='%s' root_inode=?:%d remount=%s "
68 	    "mountpoint='%s'\n",
69 	    zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid,
70 	    escaped_dataset,
71 	    zfsvfs->z_root,
72 	    remount == B_TRUE ? "true" : "false",
73 	    escaped_mountpoint);
74 }
75 
76 void
77 zev_zfs_umount_cb(vfs_t *vfs)
78 {
79 	zfsvfs_t *zfsvfs = (zfsvfs_t *)vfs->vfs_data;
80 	if (zev_skip_pool(zfsvfs->z_os))
81 		return;
82 	zev_mq_printf(ZEV_OP_ZFS_UMOUNT, 0, "ZFS_UMOUNT guid=%llu\n",
83 	    zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid);
84 }
85 
86 void
87 zev_zvol_truncate_cb(char *dataset, objset_t *os, uint64_t off, uint64_t len)
88 {
89 	if (zev_skip_pool(os))
90 		return;
91 	ZEV_ESCAPE(ZEV_OP_ZVOL_TRUNCATE, dataset);
92 	zev_mq_printf(ZEV_OP_ZVOL_TRUNCATE, 0,
93 	    "ZVOL_TRUNCATE dataset='%s' offset=%d len=%d\n",
94 	    escaped_dataset,
95 	    off,
96 	    len);
97 }
98 
99 void
100 zev_zvol_write_cb(char *dataset, objset_t *os, uint64_t off, uint64_t len)
101 {
102 	if (zev_skip_pool(os))
103 		return;
104 	ZEV_ESCAPE(ZEV_OP_ZVOL_WRITE, dataset);
105 	zev_mq_printf(ZEV_OP_ZVOL_WRITE, 0,
106 	    "ZVOL_WRITE dataset='%s' offset=%d len=%d\n",
107 	    escaped_dataset,
108 	    off,
109 	    len);
110 }
111 
112 void
113 zev_znode_close_after_update_cb(znode_t *zp)
114 {
115 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
116 		return;
117 	zev_mq_printf(ZEV_OP_ZNODE_CLOSE_AFTER_UPDATE, 0,
118 	    "ZNODE_CLOSE_AFTER_UPDATE guid=%llu inode=%d:%d\n",
119 	    zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid,
120 	    zp->z_gen,
121 	    zp->z_id);
122 }
123 
124 void
125 zev_znode_create_cb(znode_t *dzp, znode_t *zp, char *name, uint64_t txtype)
126 {
127 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
128 		return;
129 	ZEV_ESCAPE(ZEV_OP_ZNODE_CREATE, name);
130 	char *op = NULL;
131 	int type = (int)txtype;
132 	switch(type) {
133 	case TX_CREATE:
134 	case TX_CREATE_ACL:
135 	case TX_CREATE_ATTR:
136 	case TX_CREATE_ACL_ATTR:
137 		op = "ZNODE_CREATE";
138 		break;
139 	case TX_MKDIR:
140 	case TX_MKDIR_ACL:
141 	case TX_MKDIR_ATTR:
142 	case TX_MKDIR_ACL_ATTR:
143 		op = "ZNODE_MKDIR";
144 		break;
145 	case TX_MKXATTR:
146 		op = "ZNODE_MAKE_XATTR_DIR";
147 		break;
148 	default:
149 		zev_mq_printf(ZEV_OP_ZNODE_CREATE, 1,
150 		    "ERROR: ZNODE_CREATE: unknown txtype %d "
151 		    "(dir_inode=%d:%d inode=%d:%d name='%s')\n",
152 		    type,
153 		    dzp->z_gen,
154 		    dzp->z_id,
155 		    zp->z_gen,
156 		    zp->z_id,
157 		    escaped_name);
158 		return;
159 	}
160 	zev_mq_printf(ZEV_OP_ZNODE_CREATE, 0,
161 	    "%s guid=%llu dir_inode=%d:%d inode=%d:%d name='%s'\n",
162 	    op,
163 	    zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid,
164 	    dzp->z_gen,
165 	    dzp->z_id,
166 	    zp->z_gen,
167 	    zp->z_id,
168 	    escaped_name);
169 }
170 
171 void
172 zev_znode_remove_cb(znode_t *dzp, char *name, uint64_t txtype)
173 {
174 	if (zev_skip_pool(dzp->z_zfsvfs->z_os))
175 		return;
176 	ZEV_ESCAPE(ZEV_OP_ZNODE_REMOVE, name);
177 	char *op = NULL;
178 	int type = (int)txtype;
179 	switch(type) {
180 	case TX_REMOVE:
181 		op = "ZNODE_REMOVE";
182 		break;
183 	case TX_RMDIR:
184 		op = "ZNODE_RMDIR";
185 		break;
186 	default:
187 		zev_mq_printf(ZEV_OP_ZNODE_REMOVE, 1,
188 		    "ERROR: ZNODE_REMOVE: unknown txtype %d "
189 		    "(dir_inode=%d:%d name='%s')\n",
190 		    type,
191 		    dzp->z_gen,
192 		    dzp->z_id,
193 		    escaped_name);
194 		return;
195 	}
196 	zev_mq_printf(ZEV_OP_ZNODE_REMOVE, 0,
197 	    "%s guid=%llu dir_inode=%d:%d name='%s'\n",
198 	    op,
199 	    dzp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid,
200 	    dzp->z_gen,
201 	    dzp->z_id,
202 	    escaped_name);
203 }
204 
205 void
206 zev_znode_link_cb(znode_t *dzp, znode_t *zp, char *name)
207 {
208 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
209 		return;
210 	ZEV_ESCAPE(ZEV_OP_ZNODE_LINK, name);
211 	zev_mq_printf(ZEV_OP_ZNODE_LINK, 0,
212 	    "ZNODE_LINK guid=%llu dir_inode=%d:%d inode=%d:%d name='%s'\n",
213 	    zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid,
214 	    dzp->z_gen,
215 	    dzp->z_id,
216 	    zp->z_gen,
217 	    zp->z_id,
218 	    escaped_name);
219 }
220 
221 void
222 zev_znode_symlink_cb(znode_t *dzp, znode_t *zp, char *name, char *link)
223 {
224 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
225 		return;
226 	ZEV_ESCAPE(ZEV_OP_ZNODE_SYMLINK, name);
227 	ZEV_ESCAPE(ZEV_OP_ZNODE_SYMLINK, link);
228 	zev_mq_printf(ZEV_OP_ZNODE_SYMLINK, 0,
229 	    "ZNODE_SYMLINK guid=%llu dir_inode=%d:%d inode=%d:%d "
230 	    "name='%s' link='%s'\n",
231 	    zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid,
232 	    dzp->z_gen,
233 	    dzp->z_id,
234 	    zp->z_gen,
235 	    zp->z_id,
236 	    escaped_name,
237 	    escaped_link);
238 }
239 
240 void
241 zev_znode_rename_cb(znode_t *sdzp, char *sname, znode_t *tdzp,
242     char *tname, znode_t *szp)
243 {
244 	if (zev_skip_pool(szp->z_zfsvfs->z_os))
245 		return;
246 	ZEV_ESCAPE(ZEV_OP_ZNODE_RENAME, sname);
247 	ZEV_ESCAPE(ZEV_OP_ZNODE_RENAME, tname);
248 	zev_mq_printf(ZEV_OP_ZNODE_RENAME, 0,
249 	    "ZNODE_RENAME guid=%llu src_dir_inode=%d:%d src_name='%s' "
250 	    "target_dir_inode=%d:%d target_name='%s' inode=%d:%d\n",
251 	    szp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid,
252 	    sdzp->z_gen,
253 	    sdzp->z_id,
254 	    escaped_sname,
255 	    tdzp->z_gen,
256 	    tdzp->z_id,
257 	    escaped_tname,
258 	    szp->z_gen,
259 	    szp->z_id);
260 }
261 
262 void
263 zev_znode_write_cb(znode_t *zp, uint64_t off, uint64_t len)
264 {
265 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
266 		return;
267 	zev_mq_printf(ZEV_OP_ZNODE_WRITE, 0,
268 	    "ZNODE_WRITE guid=%llu inode=%d:%d offset=%d len=%d\n",
269 	    zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid,
270 	    zp->z_gen,
271 	    zp->z_id,
272 	    off,
273 	    len);
274 }
275 
276 void
277 zev_znode_truncate_cb(znode_t *zp, uint64_t off, uint64_t len)
278 {
279 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
280 		return;
281 	zev_mq_printf(ZEV_OP_ZNODE_TRUNCATE, 0,
282 	    "ZNODE_TRUNCATE guid=%llu inode=%d:%d offset=%d len=%d\n",
283 	    zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid,
284 	    zp->z_gen,
285 	    zp->z_id,
286 	    off,
287 	    len);
288 }
289 
290 void
291 zev_znode_setattr_cb(znode_t *zp)
292 {
293 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
294 		return;
295 	zev_mq_printf(ZEV_OP_ZNODE_SETATTR, 0,
296 	    "ZNODE_SETATTR guid=%llu inode=%d:%d\n",
297 	    zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid,
298 	    zp->z_gen,
299 	    zp->z_id);
300 }
301 
302 void
303 zev_znode_acl_cb(znode_t *zp)
304 {
305 	if (zev_skip_pool(zp->z_zfsvfs->z_os))
306 		return;
307 	zev_mq_printf(ZEV_OP_ZNODE_ACL, 0,
308 	    "ZNODE_ACL guid=%llu inode=%d:%d\n",
309 	    zp->z_zfsvfs->z_os->os_dsl_dataset->ds_phys->ds_guid,
310 	    zp->z_gen,
311 	    zp->z_id);
312 }
313 
314 rz_zev_callbacks_t zev_callbacks = {
315 	/* zfsvfs events */
316 	.rz_zev_zfs_mount                = zev_zfs_mount_cb,
317 	.rz_zev_zfs_umount               = zev_zfs_umount_cb,
318 
319 	/* zvol zil events */
320 	.rz_zev_zvol_truncate            = zev_zvol_truncate_cb,
321 	.rz_zev_zvol_write               = zev_zvol_write_cb,
322 
323 	/* znode zil events */
324 	.rz_zev_znode_close_after_update = zev_znode_close_after_update_cb,
325 	.rz_zev_znode_create             = zev_znode_create_cb,
326 	.rz_zev_znode_remove             = zev_znode_remove_cb,
327 	.rz_zev_znode_link               = zev_znode_link_cb,
328 	.rz_zev_znode_symlink            = zev_znode_symlink_cb,
329 	.rz_zev_znode_rename             = zev_znode_rename_cb,
330 	.rz_zev_znode_write              = zev_znode_write_cb,
331 	.rz_zev_znode_truncate           = zev_znode_truncate_cb,
332 	.rz_zev_znode_setattr            = zev_znode_setattr_cb,
333 	.rz_zev_znode_acl                = zev_znode_acl_cb,
334 };
335 
336