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

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
Loading
Loading
Loading
Loading
+25 −8
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include "netns.h"
#include "pnfs.h"
#include "filecache.h"
#include "trace.h"

/*
 *	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)
	if (rpc_pton(net, fo_path, size, sap, salen) == 0)
		return -EINVAL;

	trace_nfsd_ctl_unlock_ip(net, buf);
	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)
	fo_path = buf;
	if (qword_get(&buf, fo_path, size) < 0)
		return -EINVAL;

	trace_nfsd_ctl_unlock_fs(netns(file), fo_path);
	error = kern_path(fo_path, 0, &path);
	if (error)
		return error;
@@ -341,6 +343,8 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
	if (qword_get(&mesg, mesg, size) > 0)
		return -EINVAL;

	trace_nfsd_ctl_filehandle(netns(file), dname, path, maxsize);

	/* we have all the words, they are in buf.. */
	dom = unix_domain_find(dname);
	if (!dom)
@@ -399,6 +403,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
			return rv;
		if (newthreads < 0)
			return -EINVAL;
		trace_nfsd_ctl_threads(net, newthreads);
		rv = nfsd_svc(newthreads, net, file->f_cred);
		if (rv < 0)
			return rv;
@@ -471,6 +476,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
			rv = -EINVAL;
			if (nthreads[i] < 0)
				goto out_free;
			trace_nfsd_ctl_pool_threads(net, i, nthreads[i]);
		}
		rv = nfsd_set_nrthreads(i, nthreads, net);
		if (rv)
@@ -536,6 +542,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
		if (buf[size-1] != '\n')
			return -EINVAL;
		buf[size-1] = 0;
		trace_nfsd_ctl_version(netns(file), buf);

		vers = mesg;
		len = qword_get(&mesg, vers, size);
@@ -689,6 +696,7 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred
	err = get_int(&mesg, &fd);
	if (err != 0 || fd < 0)
		return -EINVAL;
	trace_nfsd_ctl_ports_addfd(net, fd);

	err = nfsd_create_serv(net);
	if (err != 0)
@@ -720,6 +728,7 @@ static ssize_t __write_ports_addxprt(char *buf, struct net *net, const struct cr

	if (port < 1 || port > USHRT_MAX)
		return -EINVAL;
	trace_nfsd_ctl_ports_addxprt(net, transport, port);

	err = nfsd_create_serv(net);
	if (err != 0)
@@ -853,6 +862,8 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
		int rv = get_int(&mesg, &bsize);
		if (rv)
			return rv;
		trace_nfsd_ctl_maxblksize(netns(file), bsize);

		/* force bsize into allowed range and
		 * required alignment.
		 */
@@ -903,6 +914,7 @@ static ssize_t write_maxconn(struct file *file, char *buf, size_t size)

		if (rv)
			return rv;
		trace_nfsd_ctl_maxconn(netns(file), maxconn);
		nn->max_connections = maxconn;
	}

@@ -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,
				  time64_t *time, struct nfsd_net *nn)
{
	struct dentry *dentry = file_dentry(file);
	char *mesg = buf;
	int rv, i;

@@ -922,6 +935,9 @@ static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
		rv = get_int(&mesg, &i);
		if (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
		 * these particular numbers, but problems with the
@@ -1014,6 +1030,7 @@ static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
		len = qword_get(&mesg, recdir, size);
		if (len <= 0)
			return -EINVAL;
		trace_nfsd_ctl_recoverydir(netns(file), recdir);

		status = nfs4_reset_recoverydir(recdir);
		if (status)
@@ -1087,7 +1104,7 @@ static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size)
		case '1':
			if (!nn->nfsd_serv)
				return -EBUSY;
			nfsd4_end_grace(nn);
			trace_nfsd_end_grace(netns(file));
			break;
		default:
			return -EINVAL;
@@ -1192,7 +1209,7 @@ static int __nfsd_symlink(struct inode *dir, struct dentry *dentry,
 * @content is assumed to be a NUL-terminated string that lives
 * 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)
{
	struct inode *dir = parent->d_inode;
@@ -1210,7 +1227,7 @@ static void nfsd_symlink(struct dentry *parent, const char *name,
	inode_unlock(dir);
}
#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)
{
}
@@ -1389,7 +1406,7 @@ static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc)
	ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
	if (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");
	dentry = nfsd_mkdir(sb->s_root, NULL, "clients");
	if (IS_ERR(dentry))
+259 −0
Original line number Diff line number Diff line
@@ -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 */

#undef TRACE_INCLUDE_PATH