4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2014, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
31 * lustre/ptlrpc/sec_lproc.c
33 * Author: Eric Mei <ericm@clusterfs.com>
36 #define DEBUG_SUBSYSTEM S_SEC
38 #include <libcfs/libcfs.h>
39 #include <linux/crypto.h>
42 #include <obd_class.h>
43 #include <obd_support.h>
44 #include <lustre_net.h>
45 #include <lustre_import.h>
46 #include <lustre_dlm.h>
47 #include <lustre_sec.h>
49 #include "ptlrpc_internal.h"
51 static char *sec_flags2str(unsigned long flags, char *buf, int bufsize)
55 if (flags & PTLRPC_SEC_FL_REVERSE)
56 strlcat(buf, "reverse,", bufsize);
57 if (flags & PTLRPC_SEC_FL_ROOTONLY)
58 strlcat(buf, "rootonly,", bufsize);
59 if (flags & PTLRPC_SEC_FL_UDESC)
60 strlcat(buf, "udesc,", bufsize);
61 if (flags & PTLRPC_SEC_FL_BULK)
62 strlcat(buf, "bulk,", bufsize);
64 strlcat(buf, "-,", bufsize);
69 static int sptlrpc_info_lprocfs_seq_show(struct seq_file *seq, void *v)
71 struct obd_device *obd = seq->private;
72 struct client_obd *cli = &obd->u.cli;
73 struct ptlrpc_sec *sec = NULL;
76 LASSERT(strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) == 0 ||
77 strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) == 0 ||
78 strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME) == 0 ||
79 strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) == 0 ||
80 strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) == 0);
83 sec = sptlrpc_import_sec_ref(cli->cl_import);
87 sec_flags2str(sec->ps_flvr.sf_flags, str, sizeof(str));
89 seq_printf(seq, "rpc flavor: %s\n",
90 sptlrpc_flavor2name_base(sec->ps_flvr.sf_rpc));
91 seq_printf(seq, "bulk flavor: %s\n",
92 sptlrpc_flavor2name_bulk(&sec->ps_flvr, str, sizeof(str)));
93 seq_printf(seq, "flags: %s\n",
94 sec_flags2str(sec->ps_flvr.sf_flags, str, sizeof(str)));
95 seq_printf(seq, "id: %d\n", sec->ps_id);
96 seq_printf(seq, "refcount: %d\n",
97 atomic_read(&sec->ps_refcount));
98 seq_printf(seq, "nctx: %d\n", atomic_read(&sec->ps_nctx));
99 seq_printf(seq, "gc interval %lld\n", sec->ps_gc_interval);
100 seq_printf(seq, "gc next %lld\n",
101 sec->ps_gc_interval ?
102 (s64)(sec->ps_gc_next - ktime_get_real_seconds()) : 0ll);
104 sptlrpc_sec_put(sec);
109 LDEBUGFS_SEQ_FOPS_RO(sptlrpc_info_lprocfs);
111 static int sptlrpc_ctxs_lprocfs_seq_show(struct seq_file *seq, void *v)
113 struct obd_device *obd = seq->private;
114 struct client_obd *cli = &obd->u.cli;
115 struct ptlrpc_sec *sec = NULL;
117 LASSERT(strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) == 0 ||
118 strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) == 0 ||
119 strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME) == 0 ||
120 strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) == 0 ||
121 strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) == 0);
124 sec = sptlrpc_import_sec_ref(cli->cl_import);
128 if (sec->ps_policy->sp_cops->display)
129 sec->ps_policy->sp_cops->display(sec, seq);
131 sptlrpc_sec_put(sec);
136 LDEBUGFS_SEQ_FOPS_RO(sptlrpc_ctxs_lprocfs);
139 bool sptlrpc_sepol_update_needed(struct ptlrpc_sec *imp_sec,
140 ktime_t mtime, char *pol, size_t pol_len)
142 struct sptlrpc_sepol *old;
146 old = rcu_dereference(imp_sec->ps_sepol);
149 else if (!kref_read(&old->ssp_ref))
151 else if (ktime_compare(old->ssp_mtime, mtime) != 0)
159 static int sptlrpc_sepol_update(struct obd_import *imp,
160 ktime_t mtime, char *pol, size_t pol_len)
162 struct sptlrpc_sepol *old;
163 struct sptlrpc_sepol *new;
164 struct ptlrpc_sec *imp_sec;
167 imp_sec = sptlrpc_import_sec_ref(imp);
171 if (!sptlrpc_sepol_update_needed(imp_sec, mtime, pol, pol_len))
174 new = kmalloc(sizeof(typeof(*new)) + pol_len + 1, GFP_KERNEL);
176 GOTO(out, rc = -ENOMEM);
178 kref_init(&new->ssp_ref);
179 new->ssp_sepol_size = pol_len + 1;
180 new->ssp_mtime = mtime;
181 strscpy(new->ssp_sepol, pol, new->ssp_sepol_size);
183 spin_lock(&imp_sec->ps_lock);
184 old = rcu_dereference_protected(imp_sec->ps_sepol, 1);
185 rcu_assign_pointer(imp_sec->ps_sepol, new);
186 spin_unlock(&imp_sec->ps_lock);
187 sptlrpc_sepol_put(old);
189 sptlrpc_sec_put(imp_sec);
194 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 16, 53, 0)
195 static ssize_t sepol_seq_write_old(struct obd_device *obd,
196 const char __user *buffer, size_t count)
198 struct client_obd *cli = &obd->u.cli;
199 struct obd_import *imp = cli->cl_import;
200 struct sepol_downcall_data_old *param;
201 size_t maxlen = LUSTRE_NODEMAP_SEPOL_LENGTH + 1;
202 size_t size = sizeof(*param);
203 size_t maxparam = sizeof(*param) + maxlen;
209 CERROR("%s: invalid data count %zu <= size %zu: rc = %d\n",
210 obd->obd_name, count, size, rc);
214 OBD_ALLOC(param, maxparam);
218 if (copy_from_user(param, buffer, min(count, maxparam))) {
220 CERROR("%s: bad sepol data: rc = %d\n", obd->obd_name, rc);
224 if (param->sdd_magic != SEPOL_DOWNCALL_MAGIC_OLD) {
226 CERROR("%s: sepol downcall bad magic %#08x != %#08x: rc = %d\n",
227 obd->obd_name, param->sdd_magic,
228 SEPOL_DOWNCALL_MAGIC_OLD, rc);
232 len = param->sdd_sepol_len;
233 if (len == 0 || len >= maxlen) {
235 CERROR("%s: bad sepol len %u >= maxlen %zu: rc = %d\n",
236 obd->obd_name, len, maxlen, rc);
239 size = offsetof(typeof(*param), sdd_sepol[len]);
243 CERROR("%s: bad sepol count %zu < total size %zu: rc = %d\n",
244 obd->obd_name, count, size, rc);
248 rc = sptlrpc_sepol_update(imp, ktime_set(param->sdd_sepol_mtime, 0),
249 param->sdd_sepol, len);
251 OBD_FREE(param, maxparam);
258 ldebugfs_sptlrpc_sepol_seq_write(struct file *file, const char __user *buffer,
259 size_t count, void *data)
261 struct seq_file *seq = file->private_data;
262 struct obd_device *obd = seq->private;
263 struct client_obd *cli = &obd->u.cli;
264 struct obd_import *imp = cli->cl_import;
265 struct sepol_downcall_data *param;
266 size_t maxlen = LUSTRE_NODEMAP_SEPOL_LENGTH + 1;
267 size_t size = sizeof(*param);
268 size_t maxparam = size + maxlen;
274 CERROR("%s: invalid data count %zu <= size %zu: rc = %d\n",
275 obd->obd_name, count, size, rc);
279 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 16, 53, 0)
283 if (copy_from_user(&magic, buffer, sizeof(magic))) {
285 CERROR("%s: bad sepol magic data: rc = %d\n",
290 if (unlikely(magic == SEPOL_DOWNCALL_MAGIC_OLD))
291 return sepol_seq_write_old(obd, buffer, count);
295 OBD_ALLOC(param, maxparam);
299 if (copy_from_user(param, buffer, min(count, maxparam))) {
301 CERROR("%s: bad sepol data: rc = %d\n", obd->obd_name, rc);
305 if (param->sdd_magic != SEPOL_DOWNCALL_MAGIC) {
307 CERROR("%s: sepol downcall bad magic %#08x != %#08x: rc = %d\n",
308 obd->obd_name, param->sdd_magic,
309 SEPOL_DOWNCALL_MAGIC, rc);
313 len = param->sdd_sepol_len;
314 if (len == 0 || len >= maxlen) {
316 CERROR("%s: bad sepol len %u >= maxlen %zu: rc = %d\n",
317 obd->obd_name, len, maxlen, rc);
320 size = offsetof(typeof(*param), sdd_sepol[len]);
324 CERROR("%s: bad sepol count %zu < total size %zu: rc = %d\n",
325 obd->obd_name, count, size, rc);
329 rc = sptlrpc_sepol_update(imp, ktime_set(param->sdd_sepol_mtime, 0),
330 param->sdd_sepol, len);
332 OBD_FREE(param, maxparam);
337 static int lprocfs_sptlrpc_sepol_seq_show(struct seq_file *seq, void *v)
339 struct obd_device *obd = seq->private;
340 struct client_obd *cli = &obd->u.cli;
341 struct obd_import *imp = cli->cl_import;
342 struct ptlrpc_sec *imp_sec;
343 struct sptlrpc_sepol *sepol;
344 struct timespec64 ts;
347 imp_sec = sptlrpc_import_sec_ref(imp);
352 sepol = rcu_dereference(imp->imp_sec->ps_sepol);
354 ts = ktime_to_timespec64(sepol->ssp_mtime);
355 seq_printf(seq, "mtime: %lld\n", (long long int) ts.tv_sec);
356 seq_printf(seq, "sepol: %.*s\n",
357 sepol->ssp_sepol_size, sepol->ssp_sepol);
359 seq_puts(seq, "uninitialized\n");
362 sptlrpc_sec_put(imp_sec);
366 LDEBUGFS_SEQ_FOPS_RW_TYPE(srpc, sptlrpc_sepol);
368 int sptlrpc_lprocfs_cliobd_attach(struct obd_device *obd)
370 if (strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) != 0 &&
371 strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) != 0 &&
372 strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME) != 0 &&
373 strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) != 0 &&
374 strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) != 0) {
375 CERROR("can't register lproc for obd type %s\n",
376 obd->obd_type->typ_name);
380 debugfs_create_file("srpc_info", 0444, obd->obd_debugfs_entry, obd,
381 &sptlrpc_info_lprocfs_fops);
383 debugfs_create_file("srpc_contexts", 0444, obd->obd_debugfs_entry, obd,
384 &sptlrpc_ctxs_lprocfs_fops);
386 debugfs_create_file("srpc_sepol", 0200, obd->obd_debugfs_entry, obd,
387 &srpc_sptlrpc_sepol_fops);
391 EXPORT_SYMBOL(sptlrpc_lprocfs_cliobd_attach);
393 LDEBUGFS_SEQ_FOPS_RO(encrypt_page_pools);
394 LDEBUGFS_SEQ_FOPS_RO(page_pools);
396 static struct ldebugfs_vars sptlrpc_lprocfs_vars[] = {
397 { .name = "encrypt_page_pools",
398 .fops = &encrypt_page_pools_fops },
399 { .name = "page_pools",
400 .fops = &page_pools_fops },
405 struct dentry *sptlrpc_debugfs_dir;
406 EXPORT_SYMBOL(sptlrpc_debugfs_dir);
408 struct proc_dir_entry *sptlrpc_lprocfs_dir;
409 EXPORT_SYMBOL(sptlrpc_lprocfs_dir);
411 int sptlrpc_lproc_init(void)
415 LASSERT(sptlrpc_debugfs_dir == NULL);
417 sptlrpc_debugfs_dir = debugfs_create_dir("sptlrpc",
418 debugfs_lustre_root);
419 ldebugfs_add_vars(sptlrpc_debugfs_dir, sptlrpc_lprocfs_vars, NULL);
421 sptlrpc_lprocfs_dir = lprocfs_register("sptlrpc", proc_lustre_root,
423 if (IS_ERR_OR_NULL(sptlrpc_lprocfs_dir)) {
424 rc = PTR_ERR(sptlrpc_lprocfs_dir);
425 rc = sptlrpc_lprocfs_dir ? PTR_ERR(sptlrpc_lprocfs_dir)
427 sptlrpc_lprocfs_dir = NULL;
432 void sptlrpc_lproc_fini(void)
434 debugfs_remove_recursive(sptlrpc_debugfs_dir);
435 sptlrpc_debugfs_dir = NULL;
437 if (!IS_ERR_OR_NULL(sptlrpc_lprocfs_dir))
438 lprocfs_remove(&sptlrpc_lprocfs_dir);