Commit 39d432fc authored by Chuck Lever's avatar Chuck Lever

NFSD: trace nfsctl operations

Add trace log eye-catchers that record the arguments used to
configure NFSD. This helps when troubleshooting the NFSD
administrative interfaces.

These tracepoints can capture NFSD start-up and shutdown times and
parameters, changes in lease time and thread count, and a request
to end the namespace's NFSv4 grace period, in addition to the set
of NFS versions that are enabled.
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 3434d7aa
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "netns.h" #include "netns.h"
#include "pnfs.h" #include "pnfs.h"
#include "filecache.h" #include "filecache.h"
#include "trace.h"
/* /*
* We have a single directory with several nodes in it. * We have a single directory with several nodes in it.
...@@ -230,6 +231,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size) ...@@ -230,6 +231,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
if (rpc_pton(net, fo_path, size, sap, salen) == 0) if (rpc_pton(net, fo_path, size, sap, salen) == 0)
return -EINVAL; return -EINVAL;
trace_nfsd_ctl_unlock_ip(net, buf);
return nlmsvc_unlock_all_by_ip(sap); return nlmsvc_unlock_all_by_ip(sap);
} }
...@@ -263,7 +265,7 @@ static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size) ...@@ -263,7 +265,7 @@ static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size)
fo_path = buf; fo_path = buf;
if (qword_get(&buf, fo_path, size) < 0) if (qword_get(&buf, fo_path, size) < 0)
return -EINVAL; return -EINVAL;
trace_nfsd_ctl_unlock_fs(netns(file), fo_path);
error = kern_path(fo_path, 0, &path); error = kern_path(fo_path, 0, &path);
if (error) if (error)
return error; return error;
...@@ -341,6 +343,8 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size) ...@@ -341,6 +343,8 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
if (qword_get(&mesg, mesg, size) > 0) if (qword_get(&mesg, mesg, size) > 0)
return -EINVAL; return -EINVAL;
trace_nfsd_ctl_filehandle(netns(file), dname, path, maxsize);
/* we have all the words, they are in buf.. */ /* we have all the words, they are in buf.. */
dom = unix_domain_find(dname); dom = unix_domain_find(dname);
if (!dom) if (!dom)
...@@ -399,6 +403,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size) ...@@ -399,6 +403,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
return rv; return rv;
if (newthreads < 0) if (newthreads < 0)
return -EINVAL; return -EINVAL;
trace_nfsd_ctl_threads(net, newthreads);
rv = nfsd_svc(newthreads, net, file->f_cred); rv = nfsd_svc(newthreads, net, file->f_cred);
if (rv < 0) if (rv < 0)
return rv; return rv;
...@@ -471,6 +476,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size) ...@@ -471,6 +476,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
rv = -EINVAL; rv = -EINVAL;
if (nthreads[i] < 0) if (nthreads[i] < 0)
goto out_free; goto out_free;
trace_nfsd_ctl_pool_threads(net, i, nthreads[i]);
} }
rv = nfsd_set_nrthreads(i, nthreads, net); rv = nfsd_set_nrthreads(i, nthreads, net);
if (rv) if (rv)
...@@ -536,6 +542,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) ...@@ -536,6 +542,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
if (buf[size-1] != '\n') if (buf[size-1] != '\n')
return -EINVAL; return -EINVAL;
buf[size-1] = 0; buf[size-1] = 0;
trace_nfsd_ctl_version(netns(file), buf);
vers = mesg; vers = mesg;
len = qword_get(&mesg, vers, size); len = qword_get(&mesg, vers, size);
...@@ -689,6 +696,7 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred ...@@ -689,6 +696,7 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred
err = get_int(&mesg, &fd); err = get_int(&mesg, &fd);
if (err != 0 || fd < 0) if (err != 0 || fd < 0)
return -EINVAL; return -EINVAL;
trace_nfsd_ctl_ports_addfd(net, fd);
err = nfsd_create_serv(net); err = nfsd_create_serv(net);
if (err != 0) if (err != 0)
...@@ -720,6 +728,7 @@ static ssize_t __write_ports_addxprt(char *buf, struct net *net, const struct cr ...@@ -720,6 +728,7 @@ static ssize_t __write_ports_addxprt(char *buf, struct net *net, const struct cr
if (port < 1 || port > USHRT_MAX) if (port < 1 || port > USHRT_MAX)
return -EINVAL; return -EINVAL;
trace_nfsd_ctl_ports_addxprt(net, transport, port);
err = nfsd_create_serv(net); err = nfsd_create_serv(net);
if (err != 0) if (err != 0)
...@@ -853,6 +862,8 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) ...@@ -853,6 +862,8 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
int rv = get_int(&mesg, &bsize); int rv = get_int(&mesg, &bsize);
if (rv) if (rv)
return rv; return rv;
trace_nfsd_ctl_maxblksize(netns(file), bsize);
/* force bsize into allowed range and /* force bsize into allowed range and
* required alignment. * required alignment.
*/ */
...@@ -903,6 +914,7 @@ static ssize_t write_maxconn(struct file *file, char *buf, size_t size) ...@@ -903,6 +914,7 @@ static ssize_t write_maxconn(struct file *file, char *buf, size_t size)
if (rv) if (rv)
return rv; return rv;
trace_nfsd_ctl_maxconn(netns(file), maxconn);
nn->max_connections = maxconn; nn->max_connections = maxconn;
} }
...@@ -913,6 +925,7 @@ static ssize_t write_maxconn(struct file *file, char *buf, size_t size) ...@@ -913,6 +925,7 @@ static ssize_t write_maxconn(struct file *file, char *buf, size_t size)
static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size, static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
time64_t *time, struct nfsd_net *nn) time64_t *time, struct nfsd_net *nn)
{ {
struct dentry *dentry = file_dentry(file);
char *mesg = buf; char *mesg = buf;
int rv, i; int rv, i;
...@@ -922,6 +935,9 @@ static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size, ...@@ -922,6 +935,9 @@ static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
rv = get_int(&mesg, &i); rv = get_int(&mesg, &i);
if (rv) if (rv)
return rv; return rv;
trace_nfsd_ctl_time(netns(file), dentry->d_name.name,
dentry->d_name.len, i);
/* /*
* Some sanity checking. We don't have a reason for * Some sanity checking. We don't have a reason for
* these particular numbers, but problems with the * these particular numbers, but problems with the
...@@ -1014,6 +1030,7 @@ static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size, ...@@ -1014,6 +1030,7 @@ static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
len = qword_get(&mesg, recdir, size); len = qword_get(&mesg, recdir, size);
if (len <= 0) if (len <= 0)
return -EINVAL; return -EINVAL;
trace_nfsd_ctl_recoverydir(netns(file), recdir);
status = nfs4_reset_recoverydir(recdir); status = nfs4_reset_recoverydir(recdir);
if (status) if (status)
...@@ -1087,7 +1104,7 @@ static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size) ...@@ -1087,7 +1104,7 @@ static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size)
case '1': case '1':
if (!nn->nfsd_serv) if (!nn->nfsd_serv)
return -EBUSY; return -EBUSY;
nfsd4_end_grace(nn); trace_nfsd_end_grace(netns(file));
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -1192,8 +1209,8 @@ static int __nfsd_symlink(struct inode *dir, struct dentry *dentry, ...@@ -1192,8 +1209,8 @@ static int __nfsd_symlink(struct inode *dir, struct dentry *dentry,
* @content is assumed to be a NUL-terminated string that lives * @content is assumed to be a NUL-terminated string that lives
* longer than the symlink itself. * longer than the symlink itself.
*/ */
static void nfsd_symlink(struct dentry *parent, const char *name, static void _nfsd_symlink(struct dentry *parent, const char *name,
const char *content) const char *content)
{ {
struct inode *dir = parent->d_inode; struct inode *dir = parent->d_inode;
struct dentry *dentry; struct dentry *dentry;
...@@ -1210,8 +1227,8 @@ static void nfsd_symlink(struct dentry *parent, const char *name, ...@@ -1210,8 +1227,8 @@ static void nfsd_symlink(struct dentry *parent, const char *name,
inode_unlock(dir); inode_unlock(dir);
} }
#else #else
static inline void nfsd_symlink(struct dentry *parent, const char *name, static inline void _nfsd_symlink(struct dentry *parent, const char *name,
const char *content) const char *content)
{ {
} }
...@@ -1389,8 +1406,8 @@ static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc) ...@@ -1389,8 +1406,8 @@ static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc)
ret = simple_fill_super(sb, 0x6e667364, nfsd_files); ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
if (ret) if (ret)
return ret; return ret;
nfsd_symlink(sb->s_root, "supported_krb5_enctypes", _nfsd_symlink(sb->s_root, "supported_krb5_enctypes",
"/proc/net/rpc/gss_krb5_enctypes"); "/proc/net/rpc/gss_krb5_enctypes");
dentry = nfsd_mkdir(sb->s_root, NULL, "clients"); dentry = nfsd_mkdir(sb->s_root, NULL, "clients");
if (IS_ERR(dentry)) if (IS_ERR(dentry))
return PTR_ERR(dentry); return PTR_ERR(dentry);
......
...@@ -1581,6 +1581,265 @@ TRACE_EVENT(nfsd_cb_recall_any_done, ...@@ -1581,6 +1581,265 @@ TRACE_EVENT(nfsd_cb_recall_any_done,
) )
); );
TRACE_EVENT(nfsd_ctl_unlock_ip,
TP_PROTO(
const struct net *net,
const char *address
),
TP_ARGS(net, address),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
__string(address, address)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
__assign_str(address, address);
),
TP_printk("address=%s",
__get_str(address)
)
);
TRACE_EVENT(nfsd_ctl_unlock_fs,
TP_PROTO(
const struct net *net,
const char *path
),
TP_ARGS(net, path),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
__string(path, path)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
__assign_str(path, path);
),
TP_printk("path=%s",
__get_str(path)
)
);
TRACE_EVENT(nfsd_ctl_filehandle,
TP_PROTO(
const struct net *net,
const char *domain,
const char *path,
int maxsize
),
TP_ARGS(net, domain, path, maxsize),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
__field(int, maxsize)
__string(domain, domain)
__string(path, path)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
__entry->maxsize = maxsize;
__assign_str(domain, domain);
__assign_str(path, path);
),
TP_printk("domain=%s path=%s maxsize=%d",
__get_str(domain), __get_str(path), __entry->maxsize
)
);
TRACE_EVENT(nfsd_ctl_threads,
TP_PROTO(
const struct net *net,
int newthreads
),
TP_ARGS(net, newthreads),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
__field(int, newthreads)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
__entry->newthreads = newthreads;
),
TP_printk("newthreads=%d",
__entry->newthreads
)
);
TRACE_EVENT(nfsd_ctl_pool_threads,
TP_PROTO(
const struct net *net,
int pool,
int nrthreads
),
TP_ARGS(net, pool, nrthreads),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
__field(int, pool)
__field(int, nrthreads)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
__entry->pool = pool;
__entry->nrthreads = nrthreads;
),
TP_printk("pool=%d nrthreads=%d",
__entry->pool, __entry->nrthreads
)
);
TRACE_EVENT(nfsd_ctl_version,
TP_PROTO(
const struct net *net,
const char *mesg
),
TP_ARGS(net, mesg),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
__string(mesg, mesg)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
__assign_str(mesg, mesg);
),
TP_printk("%s",
__get_str(mesg)
)
);
TRACE_EVENT(nfsd_ctl_ports_addfd,
TP_PROTO(
const struct net *net,
int fd
),
TP_ARGS(net, fd),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
__field(int, fd)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
__entry->fd = fd;
),
TP_printk("fd=%d",
__entry->fd
)
);
TRACE_EVENT(nfsd_ctl_ports_addxprt,
TP_PROTO(
const struct net *net,
const char *transport,
int port
),
TP_ARGS(net, transport, port),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
__field(int, port)
__string(transport, transport)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
__entry->port = port;
__assign_str(transport, transport);
),
TP_printk("transport=%s port=%d",
__get_str(transport), __entry->port
)
);
TRACE_EVENT(nfsd_ctl_maxblksize,
TP_PROTO(
const struct net *net,
int bsize
),
TP_ARGS(net, bsize),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
__field(int, bsize)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
__entry->bsize = bsize;
),
TP_printk("bsize=%d",
__entry->bsize
)
);
TRACE_EVENT(nfsd_ctl_maxconn,
TP_PROTO(
const struct net *net,
int maxconn
),
TP_ARGS(net, maxconn),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
__field(int, maxconn)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
__entry->maxconn = maxconn;
),
TP_printk("maxconn=%d",
__entry->maxconn
)
);
TRACE_EVENT(nfsd_ctl_time,
TP_PROTO(
const struct net *net,
const char *name,
size_t namelen,
int time
),
TP_ARGS(net, name, namelen, time),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
__field(int, time)
__string_len(name, name, namelen)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
__entry->time = time;
__assign_str_len(name, name, namelen);
),
TP_printk("file=%s time=%d\n",
__get_str(name), __entry->time
)
);
TRACE_EVENT(nfsd_ctl_recoverydir,
TP_PROTO(
const struct net *net,
const char *recdir
),
TP_ARGS(net, recdir),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
__string(recdir, recdir)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
__assign_str(recdir, recdir);
),
TP_printk("recdir=%s",
__get_str(recdir)
)
);
TRACE_EVENT(nfsd_end_grace,
TP_PROTO(
const struct net *net
),
TP_ARGS(net),
TP_STRUCT__entry(
__field(unsigned int, netns_ino)
),
TP_fast_assign(
__entry->netns_ino = net->ns.inum;
),
TP_printk("nn=%d", __entry->netns_ino
)
);
#endif /* _NFSD_TRACE_H */ #endif /* _NFSD_TRACE_H */
#undef TRACE_INCLUDE_PATH #undef TRACE_INCLUDE_PATH
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment