Skip to contentSkip to conversation

convert write_threads, write_version and write_ports to netlink commands

PATCH Superseded Lorenzo Bianconi 5 participants 14 messages Nov 4, 2023 – Nov 27, 2023

Subsystems (5)

v4 of 9 Superseded Latest is v9 →

lore
Share & tools
lore
#0 lore raw

v4 cover convert write_threads, write_version and write_ports to netlink commands

Introduce write_threads, write_version and write_ports netlink commands similar to the ones available through the procfs.

Changes since v3:
- drop write_maxconn and write_maxblksize for the moment
- add write_version and write_ports commands Changes since v2:
- use u32 to store nthreads in nfsd_nl_threads_set_doit
- rename server-attr in control-plane in nfsd.yaml specs Changes since v1:
- remove write_v4_end_grace command
- add write_maxblksize and write_maxconn netlink commands

This patch can be tested with user-space tool reported below:
https://github.com/LorenzoBianconi/nfsd-netlink.git
This series is based on the commit below available in net-next tree

commit e0fadcffdd172d3a762cb3d0e2e185b8198532d9

Author: Jakub Kicinski <[email protected]>
Date:   Fri Oct 6 06:50:32 2023 -0700

tools: ynl-gen: handle do ops with no input attrs

The code supports dumps with no input attributes currently thru a combination of special-casing and luck. Clean up the handling of ops with no inputs. Create empty Structs, and skip printing of empty types.
This makes dos with no inputs work.

Lorenzo Bianconi (3):
NFSD: convert write_threads to netlink commands
NFSD: convert write_version to netlink commands
NFSD: convert write_ports to netlink commands

 Documentation/netlink/specs/nfsd.yaml |  83 ++++++++
 fs/nfsd/netlink.c                     |  54 ++++++
 fs/nfsd/netlink.h                     |   8 +
 fs/nfsd/nfsctl.c                      | 267 +++++++++++++++++++++++++-
 include/uapi/linux/nfsd_netlink.h     |  30 +++
 tools/net/ynl/generated/nfsd-user.c   | 254 ++++++++++++++++++++++++
 tools/net/ynl/generated/nfsd-user.h   | 156 +++++++++++++++
 7 files changed, 845 insertions(+), 7 deletions(-)
Signature · 1 line
2.41.0
#1 lore raw

PATCH v4 1/3 NFSD: convert write_threads to netlink command

Introduce write_threads netlink command similar to the ones available through the procfs.

---
 Documentation/netlink/specs/nfsd.yaml | 23 +++++++
 fs/nfsd/netlink.c                     | 17 +++++
 fs/nfsd/netlink.h                     |  2 +
 fs/nfsd/nfsctl.c                      | 58 +++++++++++++++++
 include/uapi/linux/nfsd_netlink.h     |  9 +++
 tools/net/ynl/generated/nfsd-user.c   | 92 +++++++++++++++++++++++++++
 tools/net/ynl/generated/nfsd-user.h   | 47 ++++++++++++++
 7 files changed, 248 insertions(+)
Documentation/netlink/specs/nfsd.yaml +23 -0
index 05acc73e2e33..c92e1425d316 100644
@@ -62,6 +62,12 @@ attribute-sets:
         name: compound-ops
         type: u32
         multi-attr: true
+  -
+    name: server-worker
+    attributes:
+      -
+        name: threads
+        type: u32
 
 operations:
   list:
@@ -87,3 +93,20 @@ operations:
             - sport
             - dport
             - compound-ops
+    -
+      name: threads-set
+      doc: set the number of running threads
+      attribute-set: server-worker
+      flags: [ admin-perm ]
+      do:
+        request:
+          attributes:
+            - threads
+    -
+      name: threads-get
+      doc: get the number of running threads
+      attribute-set: server-worker
+      do:
+        reply:
+          attributes:
+            - threads
fs/nfsd/netlink.c +17 -0
index 0e1d635ec5f9..1a59a8e6c7e2 100644
@@ -10,6 +10,11 @@
 
 #include <uapi/linux/nfsd_netlink.h>
 
+/* NFSD_CMD_THREADS_SET - do */
+static const struct nla_policy nfsd_threads_set_nl_policy[NFSD_A_SERVER_WORKER_THREADS + 1] = {
+	[NFSD_A_SERVER_WORKER_THREADS] = { .type = NLA_U32, },
+};
+
 /* Ops table for nfsd */
 static const struct genl_split_ops nfsd_nl_ops[] = {
 	{
@@ -19,6 +24,18 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
 		.done	= nfsd_nl_rpc_status_get_done,
 		.flags	= GENL_CMD_CAP_DUMP,
 	},
+	{
+		.cmd		= NFSD_CMD_THREADS_SET,
+		.doit		= nfsd_nl_threads_set_doit,
+		.policy		= nfsd_threads_set_nl_policy,
+		.maxattr	= NFSD_A_SERVER_WORKER_THREADS,
+		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
+	},
+	{
+		.cmd	= NFSD_CMD_THREADS_GET,
+		.doit	= nfsd_nl_threads_get_doit,
+		.flags	= GENL_CMD_CAP_DO,
+	},
 };
 
 struct genl_family nfsd_nl_family __ro_after_init = {
fs/nfsd/netlink.h +2 -0
index d83dd6bdee92..4137fac477e4 100644
@@ -16,6 +16,8 @@ int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb);
 
 int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,
 				  struct netlink_callback *cb);
+int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info);
+int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info);
 
 extern struct genl_family nfsd_nl_family;
 
fs/nfsd/nfsctl.c +58 -0

64 lines not on this page · raw message

include/uapi/linux/nfsd_netlink.h +9 -0
index c8ae72466ee6..99f7855852a1 100644
@@ -29,8 +29,17 @@ enum {
 	NFSD_A_RPC_STATUS_MAX = (__NFSD_A_RPC_STATUS_MAX - 1)
 };
 
+enum {
+	NFSD_A_SERVER_WORKER_THREADS = 1,
+
+	__NFSD_A_SERVER_WORKER_MAX,
+	NFSD_A_SERVER_WORKER_MAX = (__NFSD_A_SERVER_WORKER_MAX - 1)
+};
+
 enum {
 	NFSD_CMD_RPC_STATUS_GET = 1,
+	NFSD_CMD_THREADS_SET,
+	NFSD_CMD_THREADS_GET,
 
 	__NFSD_CMD_MAX,
 	NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)
tools/net/ynl/generated/nfsd-user.c +92 -0

110 lines not on this page · raw message

tools/net/ynl/generated/nfsd-user.h +47 -0

51 lines not on this page · raw message

Signature · 1 line
2.41.0
#2 lore raw

Re: [PATCH v4 1/3] NFSD: convert write_threads to netlink command

Quoted 4 lines · Lorenzo Bianconi

Introduce write_threads netlink command similar to the ones available through the procfs.

Quoted 9 lines
---
 Documentation/netlink/specs/nfsd.yaml | 23 +++++++
 fs/nfsd/netlink.c                     | 17 +++++
 fs/nfsd/netlink.h                     |  2 +
 fs/nfsd/nfsctl.c                      | 58 +++++++++++++++++
 include/uapi/linux/nfsd_netlink.h     |  9 +++
 tools/net/ynl/generated/nfsd-user.c   | 92 +++++++++++++++++++++++++++
 tools/net/ynl/generated/nfsd-user.h   | 47 ++++++++++++++
 7 files changed, 248 insertions(+)

Hi Lorenzo -

This doesn't apply to my private nfsd-next branch. I don't believe that's your fault... We've got some things in flight here that conflict with what is in net-next.

Jakub tells me there is some ynl churn coming in v6.7-rc1 that might resolve the conflicts.

I plan to rebase my private nfsd-next on v6.7-rc1 and push the first set of patches on Monday or Tuesday. Please rebase this series on top of that, regen the ynl code, and then send a v5. I will then apply that to nfsd-next for more testing and review.

Quoted 353 lines
Documentation/netlink/specs/nfsd.yaml +23 -0
index 05acc73e2e33..c92e1425d316 100644
@@ -62,6 +62,12 @@ attribute-sets:
         name: compound-ops
         type: u32
         multi-attr: true
+  -
+    name: server-worker
+    attributes:
+      -
+        name: threads
+        type: u32
 
 operations:
   list:
@@ -87,3 +93,20 @@ operations:
             - sport
             - dport
             - compound-ops
+    -
+      name: threads-set
+      doc: set the number of running threads
+      attribute-set: server-worker
+      flags: [ admin-perm ]
+      do:
+        request:
+          attributes:
+            - threads
+    -
+      name: threads-get
+      doc: get the number of running threads
+      attribute-set: server-worker
+      do:
+        reply:
+          attributes:
+            - threads
fs/nfsd/netlink.c +17 -0
index 0e1d635ec5f9..1a59a8e6c7e2 100644
@@ -10,6 +10,11 @@
 
 #include <uapi/linux/nfsd_netlink.h>
 
+/* NFSD_CMD_THREADS_SET - do */
+static const struct nla_policy nfsd_threads_set_nl_policy[NFSD_A_SERVER_WORKER_THREADS + 1] = {
+	[NFSD_A_SERVER_WORKER_THREADS] = { .type = NLA_U32, },
+};
+
 /* Ops table for nfsd */
 static const struct genl_split_ops nfsd_nl_ops[] = {
 	{
@@ -19,6 +24,18 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
 		.done	= nfsd_nl_rpc_status_get_done,
 		.flags	= GENL_CMD_CAP_DUMP,
 	},
+	{
+		.cmd		= NFSD_CMD_THREADS_SET,
+		.doit		= nfsd_nl_threads_set_doit,
+		.policy		= nfsd_threads_set_nl_policy,
+		.maxattr	= NFSD_A_SERVER_WORKER_THREADS,
+		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
+	},
+	{
+		.cmd	= NFSD_CMD_THREADS_GET,
+		.doit	= nfsd_nl_threads_get_doit,
+		.flags	= GENL_CMD_CAP_DO,
+	},
 };
 
 struct genl_family nfsd_nl_family __ro_after_init = {
fs/nfsd/netlink.h +2 -0
index d83dd6bdee92..4137fac477e4 100644
@@ -16,6 +16,8 @@ int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb);
 
 int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,
 				  struct netlink_callback *cb);
+int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info);
+int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info);
 
 extern struct genl_family nfsd_nl_family;
 
fs/nfsd/nfsctl.c +58 -0
index 739ed5bf71cd..0d0394887506 100644
@@ -1693,6 +1693,64 @@ int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb)
 	return 0;
 }
 
+/**
+ * nfsd_nl_threads_set_doit - set the number of running threads
+ * @skb: reply buffer
+ * @info: netlink metadata and command arguments
+ *
+ * Return 0 on success or a negative errno.
+ */
+int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	u32 nthreads;
+	int ret;
+
+	if (GENL_REQ_ATTR_CHECK(info, NFSD_A_SERVER_WORKER_THREADS))
+		return -EINVAL;
+
+	nthreads = nla_get_u32(info->attrs[NFSD_A_SERVER_WORKER_THREADS]);
+	ret = nfsd_svc(nthreads, genl_info_net(info), get_current_cred());
+
+	return ret == nthreads ? 0 : ret;
+}
+
+/**
+ * nfsd_nl_threads_get_doit - get the number of running threads
+ * @skb: reply buffer
+ * @info: netlink metadata and command arguments
+ *
+ * Return 0 on success or a negative errno.
+ */
+int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	void *hdr;
+	int err;
+
+	skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!skb)
+		return -ENOMEM;
+
+	hdr = genlmsg_iput(skb, info);
+	if (!hdr) {
+		err = -EMSGSIZE;
+		goto err_free_msg;
+	}
+
+	if (nla_put_u32(skb, NFSD_A_SERVER_WORKER_THREADS,
+			nfsd_nrthreads(genl_info_net(info)))) {
+		err = -EINVAL;
+		goto err_free_msg;
+	}
+
+	genlmsg_end(skb, hdr);
+
+	return genlmsg_reply(skb, info);
+
+err_free_msg:
+	nlmsg_free(skb);
+	return err;
+}
+
 /**
  * nfsd_net_init - Prepare the nfsd_net portion of a new net namespace
  * @net: a freshly-created network namespace
include/uapi/linux/nfsd_netlink.h +9 -0
index c8ae72466ee6..99f7855852a1 100644
@@ -29,8 +29,17 @@ enum {
 	NFSD_A_RPC_STATUS_MAX = (__NFSD_A_RPC_STATUS_MAX - 1)
 };
 
+enum {
+	NFSD_A_SERVER_WORKER_THREADS = 1,
+
+	__NFSD_A_SERVER_WORKER_MAX,
+	NFSD_A_SERVER_WORKER_MAX = (__NFSD_A_SERVER_WORKER_MAX - 1)
+};
+
 enum {
 	NFSD_CMD_RPC_STATUS_GET = 1,
+	NFSD_CMD_THREADS_SET,
+	NFSD_CMD_THREADS_GET,
 
 	__NFSD_CMD_MAX,
 	NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)
tools/net/ynl/generated/nfsd-user.c +92 -0
index fec6828680ce..342a00b0474a 100644
@@ -15,6 +15,8 @@
 /* Enums */
 static const char * const nfsd_op_strmap[] = {
 	[NFSD_CMD_RPC_STATUS_GET] = "rpc-status-get",
+	[NFSD_CMD_THREADS_SET] = "threads-set",
+	[NFSD_CMD_THREADS_GET] = "threads-get",
 };
 
 const char *nfsd_op_str(int op)
@@ -47,6 +49,15 @@ struct ynl_policy_nest nfsd_rpc_status_nest = {
 	.table = nfsd_rpc_status_policy,
 };
 
+struct ynl_policy_attr nfsd_server_worker_policy[NFSD_A_SERVER_WORKER_MAX + 1] = {
+	[NFSD_A_SERVER_WORKER_THREADS] = { .name = "threads", .type = YNL_PT_U32, },
+};
+
+struct ynl_policy_nest nfsd_server_worker_nest = {
+	.max_attr = NFSD_A_SERVER_WORKER_MAX,
+	.table = nfsd_server_worker_policy,
+};
+
 /* Common nested types */
 /* ============== NFSD_CMD_RPC_STATUS_GET ============== */
 /* NFSD_CMD_RPC_STATUS_GET - dump */
@@ -90,6 +101,87 @@ struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys)
 	return NULL;
 }
 
+/* ============== NFSD_CMD_THREADS_SET ============== */
+/* NFSD_CMD_THREADS_SET - do */
+void nfsd_threads_set_req_free(struct nfsd_threads_set_req *req)
+{
+	free(req);
+}
+
+int nfsd_threads_set(struct ynl_sock *ys, struct nfsd_threads_set_req *req)
+{
+	struct nlmsghdr *nlh;
+	int err;
+
+	nlh = ynl_gemsg_start_req(ys, ys->family_id, NFSD_CMD_THREADS_SET, 1);
+	ys->req_policy = &nfsd_server_worker_nest;
+
+	if (req->_present.threads)
+		mnl_attr_put_u32(nlh, NFSD_A_SERVER_WORKER_THREADS, req->threads);
+
+	err = ynl_exec(ys, nlh, NULL);
+	if (err < 0)
+		return -1;
+
+	return 0;
+}
+
+/* ============== NFSD_CMD_THREADS_GET ============== */
+/* NFSD_CMD_THREADS_GET - do */
+void nfsd_threads_get_rsp_free(struct nfsd_threads_get_rsp *rsp)
+{
+	free(rsp);
+}
+
+int nfsd_threads_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
+{
+	struct ynl_parse_arg *yarg = data;
+	struct nfsd_threads_get_rsp *dst;
+	const struct nlattr *attr;
+
+	dst = yarg->data;
+
+	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+		unsigned int type = mnl_attr_get_type(attr);
+
+		if (type == NFSD_A_SERVER_WORKER_THREADS) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.threads = 1;
+			dst->threads = mnl_attr_get_u32(attr);
+		}
+	}
+
+	return MNL_CB_OK;
+}
+
+struct nfsd_threads_get_rsp *nfsd_threads_get(struct ynl_sock *ys)
+{
+	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
+	struct nfsd_threads_get_rsp *rsp;
+	struct nlmsghdr *nlh;
+	int err;
+
+	nlh = ynl_gemsg_start_req(ys, ys->family_id, NFSD_CMD_THREADS_GET, 1);
+	ys->req_policy = &nfsd_server_worker_nest;
+	yrs.yarg.rsp_policy = &nfsd_server_worker_nest;
+
+	rsp = calloc(1, sizeof(*rsp));
+	yrs.yarg.data = rsp;
+	yrs.cb = nfsd_threads_get_rsp_parse;
+	yrs.rsp_cmd = NFSD_CMD_THREADS_GET;
+
+	err = ynl_exec(ys, nlh, &yrs);
+	if (err < 0)
+		goto err_free;
+
+	return rsp;
+
+err_free:
+	nfsd_threads_get_rsp_free(rsp);
+	return NULL;
+}
+
 const struct ynl_family ynl_nfsd_family =  {
 	.name		= "nfsd",
 };
tools/net/ynl/generated/nfsd-user.h +47 -0
index b6b69501031a..4c11119217f1 100644
@@ -30,4 +30,51 @@ void nfsd_rpc_status_get_list_free(struct nfsd_rpc_status_get_list *rsp);
 
 struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys);
 
+/* ============== NFSD_CMD_THREADS_SET ============== */
+/* NFSD_CMD_THREADS_SET - do */
+struct nfsd_threads_set_req {
+	struct {
+		__u32 threads:1;
+	} _present;
+
+	__u32 threads;
+};
+
+static inline struct nfsd_threads_set_req *nfsd_threads_set_req_alloc(void)
+{
+	return calloc(1, sizeof(struct nfsd_threads_set_req));
+}
+void nfsd_threads_set_req_free(struct nfsd_threads_set_req *req);
+
+static inline void
+nfsd_threads_set_req_set_threads(struct nfsd_threads_set_req *req,
+				 __u32 threads)
+{
+	req->_present.threads = 1;
+	req->threads = threads;
+}
+
+/*
+ * set the number of running threads
+ */
+int nfsd_threads_set(struct ynl_sock *ys, struct nfsd_threads_set_req *req);
+
+/* ============== NFSD_CMD_THREADS_GET ============== */
+/* NFSD_CMD_THREADS_GET - do */
+
+struct nfsd_threads_get_rsp {
+	struct {
+		__u32 threads:1;
+	} _present;
+
+	__u32 threads;
+};
+
+void nfsd_threads_get_rsp_free(struct nfsd_threads_get_rsp *rsp);
+
+/*
+ * get the number of running threads
+ */
+struct nfsd_threads_get_rsp *nfsd_threads_get(struct ynl_sock *ys);
+
 #endif /* _LINUX_NFSD_GEN_H */
Signature · 1 line
2.41.0
Signature · 1 line
Chuck Lever
#3 lore raw

Re: [PATCH v4 1/3] NFSD: convert write_threads to netlink command

Quoted 21 lines · Lorenzo Bianconi
Quoted 4 lines

Introduce write_threads netlink command similar to the ones available through the procfs.

Quoted 9 lines
---
 Documentation/netlink/specs/nfsd.yaml | 23 +++++++
 fs/nfsd/netlink.c                     | 17 +++++
 fs/nfsd/netlink.h                     |  2 +
 fs/nfsd/nfsctl.c                      | 58 +++++++++++++++++
 include/uapi/linux/nfsd_netlink.h     |  9 +++
 tools/net/ynl/generated/nfsd-user.c   | 92 +++++++++++++++++++++++++++
 tools/net/ynl/generated/nfsd-user.h   | 47 ++++++++++++++
 7 files changed, 248 insertions(+)

Hi Lorenzo -

This doesn't apply to my private nfsd-next branch. I don't believe that's your fault... We've got some things in flight here that conflict with what is in net-next.

Quoted 7 lines

Jakub tells me there is some ynl churn coming in v6.7-rc1 that might resolve the conflicts.

I plan to rebase my private nfsd-next on v6.7-rc1 and push the first set of patches on Monday or Tuesday. Please rebase this series on top of that, regen the ynl code, and then send a v5. I will then apply that to nfsd-next for more testing and review.

ack, will do.

Regards,
Lorenzo

Quoted 358 lines
Quoted 355 lines
Documentation/netlink/specs/nfsd.yaml +23 -0
index 05acc73e2e33..c92e1425d316 100644
@@ -62,6 +62,12 @@ attribute-sets:
         name: compound-ops
         type: u32
         multi-attr: true
+  -
+    name: server-worker
+    attributes:
+      -
+        name: threads
+        type: u32
 
 operations:
   list:
@@ -87,3 +93,20 @@ operations:
             - sport
             - dport
             - compound-ops
+    -
+      name: threads-set
+      doc: set the number of running threads
+      attribute-set: server-worker
+      flags: [ admin-perm ]
+      do:
+        request:
+          attributes:
+            - threads
+    -
+      name: threads-get
+      doc: get the number of running threads
+      attribute-set: server-worker
+      do:
+        reply:
+          attributes:
+            - threads
fs/nfsd/netlink.c +17 -0
index 0e1d635ec5f9..1a59a8e6c7e2 100644
@@ -10,6 +10,11 @@
 
 #include <uapi/linux/nfsd_netlink.h>
 
+/* NFSD_CMD_THREADS_SET - do */
+static const struct nla_policy nfsd_threads_set_nl_policy[NFSD_A_SERVER_WORKER_THREADS + 1] = {
+	[NFSD_A_SERVER_WORKER_THREADS] = { .type = NLA_U32, },
+};
+
 /* Ops table for nfsd */
 static const struct genl_split_ops nfsd_nl_ops[] = {
 	{
@@ -19,6 +24,18 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
 		.done	= nfsd_nl_rpc_status_get_done,
 		.flags	= GENL_CMD_CAP_DUMP,
 	},
+	{
+		.cmd		= NFSD_CMD_THREADS_SET,
+		.doit		= nfsd_nl_threads_set_doit,
+		.policy		= nfsd_threads_set_nl_policy,
+		.maxattr	= NFSD_A_SERVER_WORKER_THREADS,
+		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
+	},
+	{
+		.cmd	= NFSD_CMD_THREADS_GET,
+		.doit	= nfsd_nl_threads_get_doit,
+		.flags	= GENL_CMD_CAP_DO,
+	},
 };
 
 struct genl_family nfsd_nl_family __ro_after_init = {
fs/nfsd/netlink.h +2 -0
index d83dd6bdee92..4137fac477e4 100644
@@ -16,6 +16,8 @@ int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb);
 
 int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,
 				  struct netlink_callback *cb);
+int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info);
+int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info);
 
 extern struct genl_family nfsd_nl_family;
 
fs/nfsd/nfsctl.c +58 -0
index 739ed5bf71cd..0d0394887506 100644
@@ -1693,6 +1693,64 @@ int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb)
 	return 0;
 }
 
+/**
+ * nfsd_nl_threads_set_doit - set the number of running threads
+ * @skb: reply buffer
+ * @info: netlink metadata and command arguments
+ *
+ * Return 0 on success or a negative errno.
+ */
+int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	u32 nthreads;
+	int ret;
+
+	if (GENL_REQ_ATTR_CHECK(info, NFSD_A_SERVER_WORKER_THREADS))
+		return -EINVAL;
+
+	nthreads = nla_get_u32(info->attrs[NFSD_A_SERVER_WORKER_THREADS]);
+	ret = nfsd_svc(nthreads, genl_info_net(info), get_current_cred());
+
+	return ret == nthreads ? 0 : ret;
+}
+
+/**
+ * nfsd_nl_threads_get_doit - get the number of running threads
+ * @skb: reply buffer
+ * @info: netlink metadata and command arguments
+ *
+ * Return 0 on success or a negative errno.
+ */
+int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	void *hdr;
+	int err;
+
+	skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!skb)
+		return -ENOMEM;
+
+	hdr = genlmsg_iput(skb, info);
+	if (!hdr) {
+		err = -EMSGSIZE;
+		goto err_free_msg;
+	}
+
+	if (nla_put_u32(skb, NFSD_A_SERVER_WORKER_THREADS,
+			nfsd_nrthreads(genl_info_net(info)))) {
+		err = -EINVAL;
+		goto err_free_msg;
+	}
+
+	genlmsg_end(skb, hdr);
+
+	return genlmsg_reply(skb, info);
+
+err_free_msg:
+	nlmsg_free(skb);
+	return err;
+}
+
 /**
  * nfsd_net_init - Prepare the nfsd_net portion of a new net namespace
  * @net: a freshly-created network namespace
include/uapi/linux/nfsd_netlink.h +9 -0
index c8ae72466ee6..99f7855852a1 100644
@@ -29,8 +29,17 @@ enum {
 	NFSD_A_RPC_STATUS_MAX = (__NFSD_A_RPC_STATUS_MAX - 1)
 };
 
+enum {
+	NFSD_A_SERVER_WORKER_THREADS = 1,
+
+	__NFSD_A_SERVER_WORKER_MAX,
+	NFSD_A_SERVER_WORKER_MAX = (__NFSD_A_SERVER_WORKER_MAX - 1)
+};
+
 enum {
 	NFSD_CMD_RPC_STATUS_GET = 1,
+	NFSD_CMD_THREADS_SET,
+	NFSD_CMD_THREADS_GET,
 
 	__NFSD_CMD_MAX,
 	NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)
tools/net/ynl/generated/nfsd-user.c +92 -0
index fec6828680ce..342a00b0474a 100644
@@ -15,6 +15,8 @@
 /* Enums */
 static const char * const nfsd_op_strmap[] = {
 	[NFSD_CMD_RPC_STATUS_GET] = "rpc-status-get",
+	[NFSD_CMD_THREADS_SET] = "threads-set",
+	[NFSD_CMD_THREADS_GET] = "threads-get",
 };
 
 const char *nfsd_op_str(int op)
@@ -47,6 +49,15 @@ struct ynl_policy_nest nfsd_rpc_status_nest = {
 	.table = nfsd_rpc_status_policy,
 };
 
+struct ynl_policy_attr nfsd_server_worker_policy[NFSD_A_SERVER_WORKER_MAX + 1] = {
+	[NFSD_A_SERVER_WORKER_THREADS] = { .name = "threads", .type = YNL_PT_U32, },
+};
+
+struct ynl_policy_nest nfsd_server_worker_nest = {
+	.max_attr = NFSD_A_SERVER_WORKER_MAX,
+	.table = nfsd_server_worker_policy,
+};
+
 /* Common nested types */
 /* ============== NFSD_CMD_RPC_STATUS_GET ============== */
 /* NFSD_CMD_RPC_STATUS_GET - dump */
@@ -90,6 +101,87 @@ struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys)
 	return NULL;
 }
 
+/* ============== NFSD_CMD_THREADS_SET ============== */
+/* NFSD_CMD_THREADS_SET - do */
+void nfsd_threads_set_req_free(struct nfsd_threads_set_req *req)
+{
+	free(req);
+}
+
+int nfsd_threads_set(struct ynl_sock *ys, struct nfsd_threads_set_req *req)
+{
+	struct nlmsghdr *nlh;
+	int err;
+
+	nlh = ynl_gemsg_start_req(ys, ys->family_id, NFSD_CMD_THREADS_SET, 1);
+	ys->req_policy = &nfsd_server_worker_nest;
+
+	if (req->_present.threads)
+		mnl_attr_put_u32(nlh, NFSD_A_SERVER_WORKER_THREADS, req->threads);
+
+	err = ynl_exec(ys, nlh, NULL);
+	if (err < 0)
+		return -1;
+
+	return 0;
+}
+
+/* ============== NFSD_CMD_THREADS_GET ============== */
+/* NFSD_CMD_THREADS_GET - do */
+void nfsd_threads_get_rsp_free(struct nfsd_threads_get_rsp *rsp)
+{
+	free(rsp);
+}
+
+int nfsd_threads_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
+{
+	struct ynl_parse_arg *yarg = data;
+	struct nfsd_threads_get_rsp *dst;
+	const struct nlattr *attr;
+
+	dst = yarg->data;
+
+	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+		unsigned int type = mnl_attr_get_type(attr);
+
+		if (type == NFSD_A_SERVER_WORKER_THREADS) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.threads = 1;
+			dst->threads = mnl_attr_get_u32(attr);
+		}
+	}
+
+	return MNL_CB_OK;
+}
+
+struct nfsd_threads_get_rsp *nfsd_threads_get(struct ynl_sock *ys)
+{
+	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
+	struct nfsd_threads_get_rsp *rsp;
+	struct nlmsghdr *nlh;
+	int err;
+
+	nlh = ynl_gemsg_start_req(ys, ys->family_id, NFSD_CMD_THREADS_GET, 1);
+	ys->req_policy = &nfsd_server_worker_nest;
+	yrs.yarg.rsp_policy = &nfsd_server_worker_nest;
+
+	rsp = calloc(1, sizeof(*rsp));
+	yrs.yarg.data = rsp;
+	yrs.cb = nfsd_threads_get_rsp_parse;
+	yrs.rsp_cmd = NFSD_CMD_THREADS_GET;
+
+	err = ynl_exec(ys, nlh, &yrs);
+	if (err < 0)
+		goto err_free;
+
+	return rsp;
+
+err_free:
+	nfsd_threads_get_rsp_free(rsp);
+	return NULL;
+}
+
 const struct ynl_family ynl_nfsd_family =  {
 	.name		= "nfsd",
 };
tools/net/ynl/generated/nfsd-user.h +47 -0
index b6b69501031a..4c11119217f1 100644
@@ -30,4 +30,51 @@ void nfsd_rpc_status_get_list_free(struct nfsd_rpc_status_get_list *rsp);
 
 struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys);
 
+/* ============== NFSD_CMD_THREADS_SET ============== */
+/* NFSD_CMD_THREADS_SET - do */
+struct nfsd_threads_set_req {
+	struct {
+		__u32 threads:1;
+	} _present;
+
+	__u32 threads;
+};
+
+static inline struct nfsd_threads_set_req *nfsd_threads_set_req_alloc(void)
+{
+	return calloc(1, sizeof(struct nfsd_threads_set_req));
+}
+void nfsd_threads_set_req_free(struct nfsd_threads_set_req *req);
+
+static inline void
+nfsd_threads_set_req_set_threads(struct nfsd_threads_set_req *req,
+				 __u32 threads)
+{
+	req->_present.threads = 1;
+	req->threads = threads;
+}
+
+/*
+ * set the number of running threads
+ */
+int nfsd_threads_set(struct ynl_sock *ys, struct nfsd_threads_set_req *req);
+
+/* ============== NFSD_CMD_THREADS_GET ============== */
+/* NFSD_CMD_THREADS_GET - do */
+
+struct nfsd_threads_get_rsp {
+	struct {
+		__u32 threads:1;
+	} _present;
+
+	__u32 threads;
+};
+
+void nfsd_threads_get_rsp_free(struct nfsd_threads_get_rsp *rsp);
+
+/*
+ * get the number of running threads
+ */
+struct nfsd_threads_get_rsp *nfsd_threads_get(struct ynl_sock *ys);
+
 #endif /* _LINUX_NFSD_GEN_H */
Signature · 1 line
2.41.0
Signature · 1 line
Chuck Lever
#4 lore raw

PATCH v4 2/3 NFSD: convert write_version to netlink command

In reply to Lorenzo Bianconi

Introduce write_version netlink command similar to the ones available through the procfs.

---
 Documentation/netlink/specs/nfsd.yaml |  32 ++++++++
 fs/nfsd/netlink.c                     |  19 +++++
 fs/nfsd/netlink.h                     |   3 +
 fs/nfsd/nfsctl.c                      | 105 ++++++++++++++++++++++++++
 include/uapi/linux/nfsd_netlink.h     |  11 +++
 tools/net/ynl/generated/nfsd-user.c   |  81 ++++++++++++++++++++
 tools/net/ynl/generated/nfsd-user.h   |  55 ++++++++++++++
 7 files changed, 306 insertions(+)
Documentation/netlink/specs/nfsd.yaml +32 -0
index c92e1425d316..6c5e42bb20f6 100644
@@ -68,6 +68,18 @@ attribute-sets:
       -
         name: threads
         type: u32
+  -
+    name: server-version
+    attributes:
+      -
+        name: major
+        type: u32
+      -
+        name: minor
+        type: u32
+      -
+        name: status
+        type: u8
 
 operations:
   list:
@@ -110,3 +122,23 @@ operations:
         reply:
           attributes:
             - threads
+    -
+      name: version-set
+      doc: enable/disable server version
+      attribute-set: server-version
+      flags: [ admin-perm ]
+      do:
+        request:
+          attributes:
+            - major
+            - minor
+            - status
+    -
+      name: version-get
+      doc: dump server versions
+      attribute-set: server-version
+      dump:
+        reply:
+          attributes:
+            - major
+            - minor
fs/nfsd/netlink.c +19 -0
index 1a59a8e6c7e2..0608a7bd193b 100644
@@ -15,6 +15,13 @@ static const struct nla_policy nfsd_threads_set_nl_policy[NFSD_A_SERVER_WORKER_T
 	[NFSD_A_SERVER_WORKER_THREADS] = { .type = NLA_U32, },
 };
 
+/* NFSD_CMD_VERSION_SET - do */
+static const struct nla_policy nfsd_version_set_nl_policy[NFSD_A_SERVER_VERSION_STATUS + 1] = {
+	[NFSD_A_SERVER_VERSION_MAJOR] = { .type = NLA_U32, },
+	[NFSD_A_SERVER_VERSION_MINOR] = { .type = NLA_U32, },
+	[NFSD_A_SERVER_VERSION_STATUS] = { .type = NLA_U8, },
+};
+
 /* Ops table for nfsd */
 static const struct genl_split_ops nfsd_nl_ops[] = {
 	{
@@ -36,6 +43,18 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
 		.doit	= nfsd_nl_threads_get_doit,
 		.flags	= GENL_CMD_CAP_DO,
 	},
+	{
+		.cmd		= NFSD_CMD_VERSION_SET,
+		.doit		= nfsd_nl_version_set_doit,
+		.policy		= nfsd_version_set_nl_policy,
+		.maxattr	= NFSD_A_SERVER_VERSION_STATUS,
+		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
+	},
+	{
+		.cmd	= NFSD_CMD_VERSION_GET,
+		.dumpit	= nfsd_nl_version_get_dumpit,
+		.flags	= GENL_CMD_CAP_DUMP,
+	},
 };
 
 struct genl_family nfsd_nl_family __ro_after_init = {
fs/nfsd/netlink.h +3 -0
index 4137fac477e4..7d203cec08e4 100644
@@ -18,6 +18,9 @@ int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,
 				  struct netlink_callback *cb);
 int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info);
 int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info);
+int nfsd_nl_version_set_doit(struct sk_buff *skb, struct genl_info *info);
+int nfsd_nl_version_get_dumpit(struct sk_buff *skb,
+			       struct netlink_callback *cb);
 
 extern struct genl_family nfsd_nl_family;
 
fs/nfsd/nfsctl.c +105 -0

111 lines not on this page · raw message

include/uapi/linux/nfsd_netlink.h +11 -0
index 99f7855852a1..51f078b26af4 100644
@@ -36,10 +36,21 @@ enum {
 	NFSD_A_SERVER_WORKER_MAX = (__NFSD_A_SERVER_WORKER_MAX - 1)
 };
 
+enum {
+	NFSD_A_SERVER_VERSION_MAJOR = 1,
+	NFSD_A_SERVER_VERSION_MINOR,
+	NFSD_A_SERVER_VERSION_STATUS,
+
+	__NFSD_A_SERVER_VERSION_MAX,
+	NFSD_A_SERVER_VERSION_MAX = (__NFSD_A_SERVER_VERSION_MAX - 1)
+};
+
 enum {
 	NFSD_CMD_RPC_STATUS_GET = 1,
 	NFSD_CMD_THREADS_SET,
 	NFSD_CMD_THREADS_GET,
+	NFSD_CMD_VERSION_SET,
+	NFSD_CMD_VERSION_GET,
 
 	__NFSD_CMD_MAX,
 	NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)
tools/net/ynl/generated/nfsd-user.c +81 -0

99 lines not on this page · raw message

tools/net/ynl/generated/nfsd-user.h +55 -0

59 lines not on this page · raw message

Signature · 1 line
2.41.0
#5 lore raw

Re: [PATCH v4 2/3] NFSD: convert write_version to netlink command

kernel test robot noticed the following build warnings:

Hi Lorenzo,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on next-20231103]
[cannot apply to trondmy-nfs/linux-next v6.6]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Lorenzo-Bianconi/NFSD-convert-write_threads-to-netlink-command/20231104-202515
base:   linus/master
patch link:    https://lore.kernel.org/r/3785da26e14c13e194510eaad9c6bd846d691d5f.1699095665.git.lorenzo%40kernel.org
patch subject: [PATCH v4 2/3] NFSD: convert write_version to netlink command
config: alpha-defconfig (https://download.01.org/0day-ci/archive/20231104/[email protected]/config)
compiler: alpha-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231104/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

>> fs/nfsd/nfsctl.c:1810: warning: expecting prototype for nfsd_nl_version_get_doit(). Prototype was for nfsd_nl_version_get_dumpit() instead

vim +1810 fs/nfsd/nfsctl.c

1800
1801 /**
1802 * nfsd_nl_version_get_doit - Handle verion_get dumpit
1803 * @skb: reply buffer
1804 * @cb: netlink metadata and command arguments
1805 *
1806 * Returns the size of the reply or a negative errno.
1807 */
1808 int nfsd_nl_version_get_dumpit(struct sk_buff *skb,
1809 struct netlink_callback *cb)

> 1810	{

1811 struct nfsd_net *nn = net_generic(sock_net(skb->sk), nfsd_net_id);
1812 int i, ret = -ENOMEM;
1813
1814 mutex_lock(&nfsd_mutex);
1815
1816 for (i = 2; i <= 4; i++) {
1817 int j;
1818
1819 if (i < cb->args[0]) /* already consumed */
1820 continue;
1821
1822 if (!nfsd_vers(nn, i, NFSD_AVAIL))
1823 continue;
1824
1825 for (j = 0; j <= NFSD_SUPPORTED_MINOR_VERSION; j++) {
1826 void *hdr;
1827
1828 if (!nfsd_vers(nn, i, NFSD_TEST))
1829 continue;
1830
1831 /* NFSv{2,3} does not support minor numbers */
1832 if (i < 4 && j)
1833 continue;
1834
1835 if (i == 4 && !nfsd_minorversion(nn, j, NFSD_TEST))
1836 continue;
1837
1838 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
1839 cb->nlh->nlmsg_seq, &nfsd_nl_family,
1840 0, NFSD_CMD_VERSION_GET);
1841 if (!hdr)
1842 goto out;
1843
1844 if (nla_put_u32(skb, NFSD_A_SERVER_VERSION_MAJOR, i) ||
1845 nla_put_u32(skb, NFSD_A_SERVER_VERSION_MINOR, j))
1846 goto out;
1847
1848 genlmsg_end(skb, hdr);
1849 }
1850 }
1851 cb->args[0] = i;
1852 ret = skb->len;
1853 out:
1854 mutex_unlock(&nfsd_mutex);
1855
1856 return ret;
1857 }
1858

Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
#6 lore raw

PATCH v4 3/3 NFSD: convert write_ports to netlink command

In reply to Lorenzo Bianconi

Introduce write_ports netlink command similar to the ones available through the procfs.

---
 Documentation/netlink/specs/nfsd.yaml |  28 +++++++
 fs/nfsd/netlink.c                     |  18 +++++
 fs/nfsd/netlink.h                     |   3 +
 fs/nfsd/nfsctl.c                      | 104 ++++++++++++++++++++++++--
 include/uapi/linux/nfsd_netlink.h     |  10 +++
 tools/net/ynl/generated/nfsd-user.c   |  81 ++++++++++++++++++++
 tools/net/ynl/generated/nfsd-user.h   |  54 +++++++++++++
 7 files changed, 291 insertions(+), 7 deletions(-)
Documentation/netlink/specs/nfsd.yaml +28 -0
index 6c5e42bb20f6..1c342ad3c5fa 100644
@@ -80,6 +80,15 @@ attribute-sets:
       -
         name: status
         type: u8
+  -
+    name: server-listener
+    attributes:
+      -
+        name: transport-name
+        type: string
+      -
+        name: port
+        type: u32
 
 operations:
   list:
@@ -142,3 +151,22 @@ operations:
           attributes:
             - major
             - minor
+    -
+      name: listener-start
+      doc: start server listener
+      attribute-set: server-listener
+      flags: [ admin-perm ]
+      do:
+        request:
+          attributes:
+            - transport-name
+            - port
+    -
+      name: listener-get
+      doc: dump server listeners
+      attribute-set: server-listener
+      dump:
+        reply:
+          attributes:
+            - transport-name
+            - port
fs/nfsd/netlink.c +18 -0
index 0608a7bd193b..cd51393ede72 100644
@@ -22,6 +22,12 @@ static const struct nla_policy nfsd_version_set_nl_policy[NFSD_A_SERVER_VERSION_
 	[NFSD_A_SERVER_VERSION_STATUS] = { .type = NLA_U8, },
 };
 
+/* NFSD_CMD_LISTENER_START - do */
+static const struct nla_policy nfsd_listener_start_nl_policy[NFSD_A_SERVER_LISTENER_PORT + 1] = {
+	[NFSD_A_SERVER_LISTENER_TRANSPORT_NAME] = { .type = NLA_NUL_STRING, },
+	[NFSD_A_SERVER_LISTENER_PORT] = { .type = NLA_U32, },
+};
+
 /* Ops table for nfsd */
 static const struct genl_split_ops nfsd_nl_ops[] = {
 	{
@@ -55,6 +61,18 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
 		.dumpit	= nfsd_nl_version_get_dumpit,
 		.flags	= GENL_CMD_CAP_DUMP,
 	},
+	{
+		.cmd		= NFSD_CMD_LISTENER_START,
+		.doit		= nfsd_nl_listener_start_doit,
+		.policy		= nfsd_listener_start_nl_policy,
+		.maxattr	= NFSD_A_SERVER_LISTENER_PORT,
+		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
+	},
+	{
+		.cmd	= NFSD_CMD_LISTENER_GET,
+		.dumpit	= nfsd_nl_listener_get_dumpit,
+		.flags	= GENL_CMD_CAP_DUMP,
+	},
 };
 
 struct genl_family nfsd_nl_family __ro_after_init = {
fs/nfsd/netlink.h +3 -0
index 7d203cec08e4..9a51cb83f343 100644
@@ -21,6 +21,9 @@ int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info);
 int nfsd_nl_version_set_doit(struct sk_buff *skb, struct genl_info *info);
 int nfsd_nl_version_get_dumpit(struct sk_buff *skb,
 			       struct netlink_callback *cb);
+int nfsd_nl_listener_start_doit(struct sk_buff *skb, struct genl_info *info);
+int nfsd_nl_listener_get_dumpit(struct sk_buff *skb,
+				struct netlink_callback *cb);
 
 extern struct genl_family nfsd_nl_family;
 
fs/nfsd/nfsctl.c +97 -7

127 lines not on this page · raw message

include/uapi/linux/nfsd_netlink.h +10 -0
index 51f078b26af4..2690bab6cef2 100644
@@ -45,12 +45,22 @@ enum {
 	NFSD_A_SERVER_VERSION_MAX = (__NFSD_A_SERVER_VERSION_MAX - 1)
 };
 
+enum {
+	NFSD_A_SERVER_LISTENER_TRANSPORT_NAME = 1,
+	NFSD_A_SERVER_LISTENER_PORT,
+
+	__NFSD_A_SERVER_LISTENER_MAX,
+	NFSD_A_SERVER_LISTENER_MAX = (__NFSD_A_SERVER_LISTENER_MAX - 1)
+};
+
 enum {
 	NFSD_CMD_RPC_STATUS_GET = 1,
 	NFSD_CMD_THREADS_SET,
 	NFSD_CMD_THREADS_GET,
 	NFSD_CMD_VERSION_SET,
 	NFSD_CMD_VERSION_GET,
+	NFSD_CMD_LISTENER_START,
+	NFSD_CMD_LISTENER_GET,
 
 	__NFSD_CMD_MAX,
 	NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)
tools/net/ynl/generated/nfsd-user.c +81 -0

99 lines not on this page · raw message

tools/net/ynl/generated/nfsd-user.h +54 -0

58 lines not on this page · raw message

Signature · 1 line
2.41.0
#7 lore raw

Re: [PATCH v4 3/3] NFSD: convert write_ports to netlink command

kernel test robot noticed the following build warnings:

Hi Lorenzo,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on next-20231103]
[cannot apply to trondmy-nfs/linux-next v6.6]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Lorenzo-Bianconi/NFSD-convert-write_threads-to-netlink-command/20231104-202515
base:   linus/master
patch link:    https://lore.kernel.org/r/153b94db12b5c8fff270706673afffad5d84938c.1699095665.git.lorenzo%40kernel.org
patch subject: [PATCH v4 3/3] NFSD: convert write_ports to netlink command
config: alpha-defconfig (https://download.01.org/0day-ci/archive/20231105/[email protected]/config)
compiler: alpha-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231105/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

fs/nfsd/nfsctl.c: In function 'nfsd_nl_listener_start_doit':

>> fs/nfsd/nfsctl.c:1877:13: warning: variable 'ret' set but not used [-Wunused-but-set-variable]
    1877 |         int ret;
         |             ^~~
--
   fs/nfsd/nfsctl.c:1819: warning: expecting prototype for nfsd_nl_version_get_doit(). Prototype was for nfsd_nl_version_get_dumpit() instead
>> fs/nfsd/nfsctl.c:1901: warning: expecting prototype for nfsd_nl_version_get_dumpit(). Prototype was for nfsd_nl_listener_get_dumpit() instead

vim +/ret +1877 fs/nfsd/nfsctl.c

1867
1868 /**
1869 * nfsd_nl_listener_start_doit - start the provided nfs server listener
1870 * @skb: reply buffer
1871 * @info: netlink metadata and command arguments
1872 *
1873 * Return 0 on success or a negative errno.
1874 */
1875 int nfsd_nl_listener_start_doit(struct sk_buff *skb, struct genl_info *info)
1876 {

> 1877		int ret;
  1878	
  1879		if (GENL_REQ_ATTR_CHECK(info, NFSD_A_SERVER_LISTENER_TRANSPORT_NAME) ||
  1880		    GENL_REQ_ATTR_CHECK(info, NFSD_A_SERVER_LISTENER_PORT))
  1881			return -EINVAL;
  1882	
  1883		mutex_lock(&nfsd_mutex);
  1884		ret = ___write_ports_addxprt(genl_info_net(info), get_current_cred(),
  1885				nla_data(info->attrs[NFSD_A_SERVER_LISTENER_TRANSPORT_NAME]),
  1886				nla_get_u32(info->attrs[NFSD_A_SERVER_LISTENER_PORT]));
  1887		mutex_unlock(&nfsd_mutex);
  1888	
  1889		return 0;
  1890	}
  1891	
  1892	/**
  1893	 * nfsd_nl_version_get_dumpit - Handle listener_get dumpit
  1894	 * @skb: reply buffer
  1895	 * @cb: netlink metadata and command arguments
  1896	 *
  1897	 * Returns the size of the reply or a negative errno.
  1898	 */
  1899	int nfsd_nl_listener_get_dumpit(struct sk_buff *skb,
  1900					struct netlink_callback *cb)
> 1901	{

1902 struct nfsd_net *nn = net_generic(sock_net(skb->sk), nfsd_net_id);
1903 int i = 0, ret = -ENOMEM;
1904 struct svc_xprt *xprt;
1905 struct svc_serv *serv;
1906
1907 mutex_lock(&nfsd_mutex);
1908
1909 serv = nn->nfsd_serv;
1910 if (!serv) {
1911 mutex_unlock(&nfsd_mutex);
1912 return 0;
1913 }
1914
1915 spin_lock_bh(&serv->sv_lock);
1916 list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) {
1917 void *hdr;
1918
1919 if (i < cb->args[0]) /* already consumed */
1920 continue;
1921
1922 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
1923 cb->nlh->nlmsg_seq, &nfsd_nl_family,
1924 0, NFSD_CMD_LISTENER_GET);
1925 if (!hdr)
1926 goto out;
1927
1928 if (nla_put_string(skb, NFSD_A_SERVER_LISTENER_TRANSPORT_NAME,
1929 xprt->xpt_class->xcl_name))
1930 goto out;
1931
1932 if (nla_put_u32(skb, NFSD_A_SERVER_LISTENER_PORT,
1933 svc_xprt_local_port(xprt)))
1934 goto out;
1935
1936 genlmsg_end(skb, hdr);
1937 i++;
1938 }
1939 cb->args[0] = i;
1940 ret = skb->len;
1941 out:
1942 spin_unlock_bh(&serv->sv_lock);
1943
1944 mutex_unlock(&nfsd_mutex);
1945
1946 return ret;
1947 }
1948

Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
maintainer
#8 lore raw
In reply to Lorenzo Bianconi
Quoted 34 lines · Lorenzo Bianconi

Introduce write_threads, write_version and write_ports netlink commands similar to the ones available through the procfs.

Changes since v3:
- drop write_maxconn and write_maxblksize for the moment
- add write_version and write_ports commands Changes since v2:
- use u32 to store nthreads in nfsd_nl_threads_set_doit
- rename server-attr in control-plane in nfsd.yaml specs Changes since v1:
- remove write_v4_end_grace command
- add write_maxblksize and write_maxconn netlink commands

This patch can be tested with user-space tool reported below:
https://github.com/LorenzoBianconi/nfsd-netlink.git
This series is based on the commit below available in net-next tree

commit e0fadcffdd172d3a762cb3d0e2e185b8198532d9

Author: Jakub Kicinski <[email protected]>
Date:   Fri Oct 6 06:50:32 2023 -0700

tools: ynl-gen: handle do ops with no input attrs

The code supports dumps with no input attributes currently thru a combination of special-casing and luck. Clean up the handling of ops with no inputs. Create empty Structs, and skip printing of empty types.
This makes dos with no inputs work.

Lorenzo Bianconi (3):
NFSD: convert write_threads to netlink commands
NFSD: convert write_version to netlink commands
NFSD: convert write_ports to netlink commands

Quoted 9 lines
 Documentation/netlink/specs/nfsd.yaml |  83 ++++++++
 fs/nfsd/netlink.c                     |  54 ++++++
 fs/nfsd/netlink.h                     |   8 +
 fs/nfsd/nfsctl.c                      | 267 +++++++++++++++++++++++++-
 include/uapi/linux/nfsd_netlink.h     |  30 +++
 tools/net/ynl/generated/nfsd-user.c   | 254 ++++++++++++++++++++++++
 tools/net/ynl/generated/nfsd-user.h   | 156 +++++++++++++++
 7 files changed, 845 insertions(+), 7 deletions(-)

Nice work, Lorenzo! Now comes the bikeshedding...

With the nfsdfs interface, we sort of had to split things up into multiple files like this, but it has some drawbacks, in particular with weird behavior when people do things out of order.

Would it make more sense to instead have a single netlink command that sets up ports and versions, and then spawns the requisite amount of threads, all in one fell swoop?

That does presuppose we can send down a variable-length frame though, but I assume that is possible with netlink.

Signature · 1 line
Jeff Layton <[email protected]>
#9 lore raw
Quoted 45 lines · Lorenzo Bianconi
Quoted 34 lines

Introduce write_threads, write_version and write_ports netlink commands similar to the ones available through the procfs.

Changes since v3:
- drop write_maxconn and write_maxblksize for the moment
- add write_version and write_ports commands Changes since v2:
- use u32 to store nthreads in nfsd_nl_threads_set_doit
- rename server-attr in control-plane in nfsd.yaml specs Changes since v1:
- remove write_v4_end_grace command
- add write_maxblksize and write_maxconn netlink commands

This patch can be tested with user-space tool reported below:
https://github.com/LorenzoBianconi/nfsd-netlink.git
This series is based on the commit below available in net-next tree

commit e0fadcffdd172d3a762cb3d0e2e185b8198532d9

Author: Jakub Kicinski <[email protected]>
Date:   Fri Oct 6 06:50:32 2023 -0700

tools: ynl-gen: handle do ops with no input attrs

The code supports dumps with no input attributes currently thru a combination of special-casing and luck. Clean up the handling of ops with no inputs. Create empty Structs, and skip printing of empty types.
This makes dos with no inputs work.

Lorenzo Bianconi (3):
NFSD: convert write_threads to netlink commands
NFSD: convert write_version to netlink commands
NFSD: convert write_ports to netlink commands

Quoted 9 lines
 Documentation/netlink/specs/nfsd.yaml |  83 ++++++++
 fs/nfsd/netlink.c                     |  54 ++++++
 fs/nfsd/netlink.h                     |   8 +
 fs/nfsd/nfsctl.c                      | 267 +++++++++++++++++++++++++-
 include/uapi/linux/nfsd_netlink.h     |  30 +++
 tools/net/ynl/generated/nfsd-user.c   | 254 ++++++++++++++++++++++++
 tools/net/ynl/generated/nfsd-user.h   | 156 +++++++++++++++
 7 files changed, 845 insertions(+), 7 deletions(-)
Quoted 1 line

Nice work, Lorenzo! Now comes the bikeshedding...

Hi Jeff,

Quoted 4 lines

With the nfsdfs interface, we sort of had to split things up into multiple files like this, but it has some drawbacks, in particular with weird behavior when people do things out of order.

what do you mean with 'weird behavior'? Something not expected?

Quoted 4 lines

Would it make more sense to instead have a single netlink command that sets up ports and versions, and then spawns the requisite amount of threads, all in one fell swoop?

I do not have a strong opinion about it but I would say having a dedicated set/get for each paramater allow us to have more granularity (e.g. if you want to change just a parameter we do not need to send all of them to the kernel). What do you think?

Quoted 3 lines

That does presuppose we can send down a variable-length frame though, but I assume that is possible with netlink.

sure, we can do it.

Regards,
Lorenzo

Quoted 2 lines
Signature · 1 line
Jeff Layton <[email protected]>
maintainer
#10 lore raw
Quoted 47 lines · Lorenzo Bianconi
Quoted 45 lines · Lorenzo Bianconi
Quoted 34 lines

Introduce write_threads, write_version and write_ports netlink commands similar to the ones available through the procfs.

Changes since v3:
- drop write_maxconn and write_maxblksize for the moment
- add write_version and write_ports commands Changes since v2:
- use u32 to store nthreads in nfsd_nl_threads_set_doit
- rename server-attr in control-plane in nfsd.yaml specs Changes since v1:
- remove write_v4_end_grace command
- add write_maxblksize and write_maxconn netlink commands

This patch can be tested with user-space tool reported below:
https://github.com/LorenzoBianconi/nfsd-netlink.git
This series is based on the commit below available in net-next tree

commit e0fadcffdd172d3a762cb3d0e2e185b8198532d9

Author: Jakub Kicinski <[email protected]>
Date:   Fri Oct 6 06:50:32 2023 -0700

    tools: ynl-gen: handle do ops with no input attrs

    The code supports dumps with no input attributes currently thru a combination of special-casing and luck. Clean up the handling of ops with no inputs. Create empty Structs, and skip printing of empty types.
    This makes dos with no inputs work.

Lorenzo Bianconi (3):
  NFSD: convert write_threads to netlink commands
  NFSD: convert write_version to netlink commands
  NFSD: convert write_ports to netlink commands

Quoted 9 lines
 Documentation/netlink/specs/nfsd.yaml |  83 ++++++++
 fs/nfsd/netlink.c                     |  54 ++++++
 fs/nfsd/netlink.h                     |   8 +
 fs/nfsd/nfsctl.c                      | 267 +++++++++++++++++++++++++-
 include/uapi/linux/nfsd_netlink.h     |  30 +++
 tools/net/ynl/generated/nfsd-user.c   | 254 ++++++++++++++++++++++++
 tools/net/ynl/generated/nfsd-user.h   | 156 +++++++++++++++
 7 files changed, 845 insertions(+), 7 deletions(-)
Quoted 1 line

Nice work, Lorenzo! Now comes the bikeshedding...

Quoted 9 lines

Hi Jeff,

Quoted 4 lines

With the nfsdfs interface, we sort of had to split things up into multiple files like this, but it has some drawbacks, in particular with weird behavior when people do things out of order.

what do you mean with 'weird behavior'? Something not expected?

Yeah.

For instance, if you set up sockets but never write anything to the "threads" file, those sockets will sit around in perpetuity. Granted most people use rpc.nfsd to start the server, so this generally doesn't happen often, but it's always been a klunky interface regardless.

Quoted 10 lines
Quoted 4 lines

Would it make more sense to instead have a single netlink command that sets up ports and versions, and then spawns the requisite amount of threads, all in one fell swoop?

I do not have a strong opinion about it but I would say having a dedicated set/get for each paramater allow us to have more granularity (e.g. if you want to change just a parameter we do not need to send all of them to the kernel). What do you think?

It's pretty rare to need to twiddle settings on the server while it's up and running. Restarting the server in the face of even minor changes is not generally a huge problem, so I don't see this as necessary.

Also, it's always been a bit hit and miss as to which settings take immediate effect. For instance, if I (e.g.) turn off NFSv4 serving altogether on a running server, it doesn't purge the existing NFSv4 state, but v4 RPCs would be immediately rejected. Eventually it would time out, but it is odd.

Personally, I think this is amenable to a declarative interface:

Have userland always send down a complete description of what the server should look like, and then the kernel can do what it needs to make that happen (starting/stopping threads, opening/closing sockets, changing versions served, etc.).

Quoted 5 lines
Quoted 3 lines

That does presuppose we can send down a variable-length frame though, but I assume that is possible with netlink.

sure, we can do it.

Signature · 1 line
Jeff Layton <[email protected]>
#11 lore raw
Quoted 80 lines · Jeff Layton
Quoted 47 lines · Lorenzo Bianconi
Quoted 45 lines · Lorenzo Bianconi
Quoted 34 lines

Introduce write_threads, write_version and write_ports netlink commands similar to the ones available through the procfs.

Changes since v3:
- drop write_maxconn and write_maxblksize for the moment
- add write_version and write_ports commands Changes since v2:
- use u32 to store nthreads in nfsd_nl_threads_set_doit
- rename server-attr in control-plane in nfsd.yaml specs Changes since v1:
- remove write_v4_end_grace command
- add write_maxblksize and write_maxconn netlink commands

This patch can be tested with user-space tool reported below:
https://github.com/LorenzoBianconi/nfsd-netlink.git
This series is based on the commit below available in net-next tree

commit e0fadcffdd172d3a762cb3d0e2e185b8198532d9

Author: Jakub Kicinski <[email protected]>
Date:   Fri Oct 6 06:50:32 2023 -0700

tools: ynl-gen: handle do ops with no input attrs

The code supports dumps with no input attributes currently thru a combination of special-casing and luck. Clean up the handling of ops with no inputs. Create empty Structs, and skip printing of empty types.
This makes dos with no inputs work.

Lorenzo Bianconi (3):
NFSD: convert write_threads to netlink commands
NFSD: convert write_version to netlink commands
NFSD: convert write_ports to netlink commands

Quoted 9 lines
 Documentation/netlink/specs/nfsd.yaml |  83 ++++++++
 fs/nfsd/netlink.c                     |  54 ++++++
 fs/nfsd/netlink.h                     |   8 +
 fs/nfsd/nfsctl.c                      | 267 +++++++++++++++++++++++++-
 include/uapi/linux/nfsd_netlink.h     |  30 +++
 tools/net/ynl/generated/nfsd-user.c   | 254 ++++++++++++++++++++++++
 tools/net/ynl/generated/nfsd-user.h   | 156 +++++++++++++++
 7 files changed, 845 insertions(+), 7 deletions(-)
Quoted 1 line

Nice work, Lorenzo! Now comes the bikeshedding...

Quoted 9 lines

Hi Jeff,

Quoted 4 lines

With the nfsdfs interface, we sort of had to split things up into multiple files like this, but it has some drawbacks, in particular with weird behavior when people do things out of order.

what do you mean with 'weird behavior'? Something not expected?

Yeah.

For instance, if you set up sockets but never write anything to the "threads" file, those sockets will sit around in perpetuity. Granted most people use rpc.nfsd to start the server, so this generally doesn't happen often, but it's always been a klunky interface regardless.

Quoted 10 lines
Quoted 4 lines

Would it make more sense to instead have a single netlink command that sets up ports and versions, and then spawns the requisite amount of threads, all in one fell swoop?

I do not have a strong opinion about it but I would say having a dedicated set/get for each paramater allow us to have more granularity (e.g. if you want to change just a parameter we do not need to send all of them to the kernel). What do you think?

Quoted 3 lines

It's pretty rare to need to twiddle settings on the server while it's up and running. Restarting the server in the face of even minor changes is not generally a huge problem, so I don't see this as necessary.

I don't have a problem creating a single "set" netlink command that takes a number of optional arguments to adjust nfsd's configuration in a single operation.

And a matching "get" command to query all of the server settings at one time.

Quoted 14 lines

Also, it's always been a bit hit and miss as to which settings take immediate effect. For instance, if I (e.g.) turn off NFSv4 serving altogether on a running server, it doesn't purge the existing NFSv4 state, but v4 RPCs would be immediately rejected. Eventually it would time out, but it is odd.

Personally, I think this is amenable to a declarative interface:

Have userland always send down a complete description of what the server should look like, and then the kernel can do what it needs to make that happen (starting/stopping threads, opening/closing sockets, changing versions served, etc.).

Quoted 1 line
Quoted 1 line
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

That does presuppose we can send down a variable-length frame though, but I assume that is possible with netlink.

sure, we can do it.

Signature · 1 line
Jeff Layton <[email protected]>

--
Chuck Lever

#12 lore raw
In reply to Jeff Layton
Quoted 58 lines · Jeff Layton
Quoted 47 lines · Lorenzo Bianconi
Quoted 45 lines · Lorenzo Bianconi
Quoted 34 lines

Introduce write_threads, write_version and write_ports netlink commands similar to the ones available through the procfs.

Changes since v3:
- drop write_maxconn and write_maxblksize for the moment
- add write_version and write_ports commands Changes since v2:
- use u32 to store nthreads in nfsd_nl_threads_set_doit
- rename server-attr in control-plane in nfsd.yaml specs Changes since v1:
- remove write_v4_end_grace command
- add write_maxblksize and write_maxconn netlink commands

This patch can be tested with user-space tool reported below:
https://github.com/LorenzoBianconi/nfsd-netlink.git
This series is based on the commit below available in net-next tree

commit e0fadcffdd172d3a762cb3d0e2e185b8198532d9

Author: Jakub Kicinski <[email protected]>
Date:   Fri Oct 6 06:50:32 2023 -0700

    tools: ynl-gen: handle do ops with no input attrs

    The code supports dumps with no input attributes currently thru a combination of special-casing and luck. Clean up the handling of ops with no inputs. Create empty Structs, and skip printing of empty types.
    This makes dos with no inputs work.

Lorenzo Bianconi (3):
  NFSD: convert write_threads to netlink commands
  NFSD: convert write_version to netlink commands
  NFSD: convert write_ports to netlink commands

Quoted 9 lines
 Documentation/netlink/specs/nfsd.yaml |  83 ++++++++
 fs/nfsd/netlink.c                     |  54 ++++++
 fs/nfsd/netlink.h                     |   8 +
 fs/nfsd/nfsctl.c                      | 267 +++++++++++++++++++++++++-
 include/uapi/linux/nfsd_netlink.h     |  30 +++
 tools/net/ynl/generated/nfsd-user.c   | 254 ++++++++++++++++++++++++
 tools/net/ynl/generated/nfsd-user.h   | 156 +++++++++++++++
 7 files changed, 845 insertions(+), 7 deletions(-)
Quoted 1 line

Nice work, Lorenzo! Now comes the bikeshedding...

Quoted 9 lines

Hi Jeff,

Quoted 4 lines

With the nfsdfs interface, we sort of had to split things up into multiple files like this, but it has some drawbacks, in particular with weird behavior when people do things out of order.

what do you mean with 'weird behavior'? Something not expected?

Quoted 6 lines

Yeah.

For instance, if you set up sockets but never write anything to the "threads" file, those sockets will sit around in perpetuity. Granted most people use rpc.nfsd to start the server, so this generally doesn't happen often, but it's always been a klunky interface regardless.

If you set up sockets but *do* write something to the "threads" file, then those sockets will *still* sit around in perpetuity. i.e. until you shut down the NFS server (rpc.nfsd 0).

I don't really see the problem.

It is true that you can use use the interface to ask for meaningless things. The maxim that applies is "If you make it fool-proof, only a fool will use it". :-)

I'm not against exploring changes to the interface style in conjunction with moving from nfsd-fs to netlink, but I would want a bit more justification for any change.

Thanks,
NeilBrown

Quoted 12 lines
Quoted 11 lines
Quoted 5 lines

Would it make more sense to instead have a single netlink command that sets up ports and versions, and then spawns the requisite amount of threads, all in one fell swoop?

I do not have a strong opinion about it but I would say having a dedicated set/get for each paramater allow us to have more granularity (e.g. if you want to change just a parameter we do not need to send all of them to the kernel). What do you think?

Quoted 3 lines

It's pretty rare to need to twiddle settings on the server while it's up and running. Restarting the server in the face of even minor changes is not generally a huge problem, so I don't see this as necessary.

Restarting the server is not zero-cost. It restarts the grace period. So I would rather not require it for minor changes.

NeilBrown

Quoted 22 lines

Also, it's always been a bit hit and miss as to which settings take immediate effect. For instance, if I (e.g.) turn off NFSv4 serving altogether on a running server, it doesn't purge the existing NFSv4 state, but v4 RPCs would be immediately rejected. Eventually it would time out, but it is odd.

Personally, I think this is amenable to a declarative interface:

Have userland always send down a complete description of what the server should look like, and then the kernel can do what it needs to make that happen (starting/stopping threads, opening/closing sockets, changing versions served, etc.).

Quoted 5 lines
Quoted 3 lines

That does presuppose we can send down a variable-length frame though, but I assume that is possible with netlink.

sure, we can do it.

Signature · 1 line
Jeff Layton <[email protected]>
maintainer
#13 lore raw
Quoted 72 lines · NeilBrown
Quoted 58 lines · Jeff Layton
Quoted 47 lines · Lorenzo Bianconi
Quoted 45 lines · Lorenzo Bianconi
Quoted 34 lines

Introduce write_threads, write_version and write_ports netlink commands similar to the ones available through the procfs.

Changes since v3:
- drop write_maxconn and write_maxblksize for the moment
- add write_version and write_ports commands Changes since v2:
- use u32 to store nthreads in nfsd_nl_threads_set_doit
- rename server-attr in control-plane in nfsd.yaml specs Changes since v1:
- remove write_v4_end_grace command
- add write_maxblksize and write_maxconn netlink commands

This patch can be tested with user-space tool reported below:
https://github.com/LorenzoBianconi/nfsd-netlink.git
This series is based on the commit below available in net-next tree

commit e0fadcffdd172d3a762cb3d0e2e185b8198532d9

Author: Jakub Kicinski <[email protected]>
Date:   Fri Oct 6 06:50:32 2023 -0700

    tools: ynl-gen: handle do ops with no input attrs

    The code supports dumps with no input attributes currently thru a combination of special-casing and luck. Clean up the handling of ops with no inputs. Create empty Structs, and skip printing of empty types.
    This makes dos with no inputs work.

Lorenzo Bianconi (3):
  NFSD: convert write_threads to netlink commands
  NFSD: convert write_version to netlink commands
  NFSD: convert write_ports to netlink commands

Quoted 9 lines
 Documentation/netlink/specs/nfsd.yaml |  83 ++++++++
 fs/nfsd/netlink.c                     |  54 ++++++
 fs/nfsd/netlink.h                     |   8 +
 fs/nfsd/nfsctl.c                      | 267 +++++++++++++++++++++++++-
 include/uapi/linux/nfsd_netlink.h     |  30 +++
 tools/net/ynl/generated/nfsd-user.c   | 254 ++++++++++++++++++++++++
 tools/net/ynl/generated/nfsd-user.h   | 156 +++++++++++++++
 7 files changed, 845 insertions(+), 7 deletions(-)
Quoted 1 line

Nice work, Lorenzo! Now comes the bikeshedding...

Quoted 9 lines

Hi Jeff,

Quoted 4 lines

With the nfsdfs interface, we sort of had to split things up into multiple files like this, but it has some drawbacks, in particular with weird behavior when people do things out of order.

what do you mean with 'weird behavior'? Something not expected?

Quoted 6 lines

Yeah.

For instance, if you set up sockets but never write anything to the "threads" file, those sockets will sit around in perpetuity. Granted most people use rpc.nfsd to start the server, so this generally doesn't happen often, but it's always been a klunky interface regardless.

If you set up sockets but *do* write something to the "threads" file, then those sockets will *still* sit around in perpetuity. i.e. until you shut down the NFS server (rpc.nfsd 0).

I don't really see the problem.

Quoted 9 lines

It is true that you can use use the interface to ask for meaningless things. The maxim that applies is "If you make it fool-proof, only a fool will use it". :-)

I'm not against exploring changes to the interface style in conjunction with moving from nfsd-fs to netlink, but I would want a bit more justification for any change.

Mostly my justification is that that occasionally we do add new settings for nfsd, and having a single extensible command may make that simpler to deal with.

Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
Quoted 5 lines

Would it make more sense to instead have a single netlink command that sets up ports and versions, and then spawns the requisite amount of threads, all in one fell swoop?

I do not have a strong opinion about it but I would say having a dedicated set/get for each paramater allow us to have more granularity (e.g. if you want to change just a parameter we do not need to send all of them to the kernel). What do you think?

Quoted 8 lines
Quoted 3 lines

It's pretty rare to need to twiddle settings on the server while it's up and running. Restarting the server in the face of even minor changes is not generally a huge problem, so I don't see this as necessary.

Restarting the server is not zero-cost. It restarts the grace period. So I would rather not require it for minor changes.

That is a good point. That said, we wouldn't necessarily need to require restarting the server on a reconfigure. Some settings could be changed without a server restart.

In any case, I'll withdraw my objection and we can do this with multiple commands for now. We can always add a single command later, and just fix up rpc.nfsd to hide all of the details of the different interfaces at that time if we think it's helpful.

Cheers,
--
Jeff Layton <[email protected]>