2023-06-02 11:23:53

by Joel Granados

[permalink] [raw]
Subject: [PATCH 0/8] Remove child from struct ctl_table

Resending as the first set got mangled with smtp error.

This is part of the effort to remove the empty element of the ctl_table
structures (used to calculate size) and replace it with an ARRAY_SIZE call. By
replacing the child element in struct ctl_table with a flags element we make
sure that there are no forward recursions on child nodes and therefore set
ourselves up for just using an ARRAY_SIZE. We also added some self tests to
make sure that we do not break anything.

Patchset is separated in 4: parport fixes, selftests fixes, selftests additions and
replacement of child element. Tested everything with sysctl self tests and everything
seems "ok".

1. parport fixes: @mcgrof: this is related to my previous series and it plugs a
sysct table leak in the parport driver. Please tell me if you want me to repost
the parport series with this one stiched in.

2. Selftests fixes: Remove the prefixed zeros when passing a awk field to the
awk print command because it was causing $0009 to be interpreted as $0.
Replaced continue with return in sysctl.sh(test_case) so the test actually
gets skipped. The skip decision is now in sysctl.sh(skip_test).

3. Selftest additions: New test to confirm that unregister actually removes
targets. New test to confirm that permanently empty targets are indeed
created and that no other targets can be created "on top".

4. Replaced the child pointer in struct ctl_table with a u8 flag. The flag
is used to differentiate between permanently empty targets and non-empty ones.

Comments/feedback greatly appreciated

Best
Joel

Joel Granados (8):
parport: plug a sysctl register leak
test_sysctl: Fix test metadata getters
test_sysctl: Group node sysctl test under one func
test_sysctl: Add an unregister sysctl test
test_sysctl: Add an option to prevent test skip
test_sysclt: Test for registering a mount point
sysctl: Remove debugging dump_stack
sysctl: replace child with a flags var

drivers/parport/procfs.c | 23 ++---
fs/proc/proc_sysctl.c | 82 ++++------------
include/linux/sysctl.h | 4 +-
lib/test_sysctl.c | 91 ++++++++++++++++--
tools/testing/selftests/sysctl/sysctl.sh | 115 +++++++++++++++++------
5 files changed, 204 insertions(+), 111 deletions(-)

--
2.30.2



2023-06-02 11:23:53

by Joel Granados

[permalink] [raw]
Subject: [PATCH 1/8] parport: plug a sysctl register leak

parport registers two sysctl directories in the parport_proc_register
function but only one of them was getting unregistered in
parport_proc_unregister. Keep track of both sysctl table headers and
handle them together when (un)registering.

Signed-off-by: Joel Granados <[email protected]>
---
drivers/parport/procfs.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c
index cbb1fb5127ce..0f2d2e1ee28e 100644
--- a/drivers/parport/procfs.c
+++ b/drivers/parport/procfs.c
@@ -257,14 +257,16 @@ PARPORT_MAX_SPINTIME_VALUE;


struct parport_sysctl_table {
- struct ctl_table_header *sysctl_header;
+ struct ctl_table_header *port_header;
+ struct ctl_table_header *devices_header;
struct ctl_table vars[12];
struct ctl_table device_dir[2];
};

static const struct parport_sysctl_table parport_sysctl_template = {
- .sysctl_header = NULL,
- {
+ .port_header = NULL,
+ .devices_header = NULL,
+ {
{
.procname = "spintime",
.data = NULL,
@@ -429,7 +431,6 @@ parport_default_sysctl_table = {
int parport_proc_register(struct parport *port)
{
struct parport_sysctl_table *t;
- struct ctl_table_header *devices_h;
char *tmp_dir_path;
size_t tmp_path_len, port_name_len;
int bytes_written, i, err = 0;
@@ -464,8 +465,8 @@ int parport_proc_register(struct parport *port)
err = -ENOENT;
goto exit_free_tmp_dir_path;
}
- devices_h = register_sysctl(tmp_dir_path, t->device_dir);
- if (devices_h == NULL) {
+ t->devices_header = register_sysctl(tmp_dir_path, t->device_dir);
+ if (t->devices_header == NULL) {
err = -ENOENT;
goto exit_free_tmp_dir_path;
}
@@ -478,8 +479,8 @@ int parport_proc_register(struct parport *port)
goto unregister_devices_h;
}

- t->sysctl_header = register_sysctl(tmp_dir_path, t->vars);
- if (t->sysctl_header == NULL) {
+ t->port_header = register_sysctl(tmp_dir_path, t->vars);
+ if (t->port_header == NULL) {
err = -ENOENT;
goto unregister_devices_h;
}
@@ -490,7 +491,7 @@ int parport_proc_register(struct parport *port)
return 0;

unregister_devices_h:
- unregister_sysctl_table(devices_h);
+ unregister_sysctl_table(t->devices_header);

exit_free_tmp_dir_path:
kfree(tmp_dir_path);
@@ -505,7 +506,8 @@ int parport_proc_unregister(struct parport *port)
if (port->sysctl_table) {
struct parport_sysctl_table *t = port->sysctl_table;
port->sysctl_table = NULL;
- unregister_sysctl_table(t->sysctl_header);
+ unregister_sysctl_table(t->devices_header);
+ unregister_sysctl_table(t->port_header);
kfree(t);
}
return 0;
--
2.30.2


2023-06-06 19:07:27

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH 0/8] Remove child from struct ctl_table

On Fri, Jun 02, 2023 at 01:06:30PM +0200, Joel Granados wrote:
> Resending as the first set got mangled with smtp error.
>
> This is part of the effort to remove the empty element of the ctl_table
> structures (used to calculate size) and replace it with an ARRAY_SIZE call. By
> replacing the child element in struct ctl_table with a flags element we make
> sure that there are no forward recursions on child nodes and therefore set
> ourselves up for just using an ARRAY_SIZE. We also added some self tests to
> make sure that we do not break anything.
>
> Patchset is separated in 4: parport fixes, selftests fixes, selftests additions and
> replacement of child element. Tested everything with sysctl self tests and everything
> seems "ok".
>
> 1. parport fixes: @mcgrof: this is related to my previous series and it plugs a
> sysct table leak in the parport driver. Please tell me if you want me to repost
> the parport series with this one stiched in.
>
> 2. Selftests fixes: Remove the prefixed zeros when passing a awk field to the
> awk print command because it was causing $0009 to be interpreted as $0.
> Replaced continue with return in sysctl.sh(test_case) so the test actually
> gets skipped. The skip decision is now in sysctl.sh(skip_test).
>
> 3. Selftest additions: New test to confirm that unregister actually removes
> targets. New test to confirm that permanently empty targets are indeed
> created and that no other targets can be created "on top".
>
> 4. Replaced the child pointer in struct ctl_table with a u8 flag. The flag
> is used to differentiate between permanently empty targets and non-empty ones.
>
> Comments/feedback greatly appreciated

This all looks great, thanks so much for doing all this work! I pushed
to sysctl-next.

Luis

2023-06-07 08:21:56

by Joel Granados

[permalink] [raw]
Subject: Re: [PATCH 0/8] Remove child from struct ctl_table

On Tue, Jun 06, 2023 at 11:56:26AM -0700, Luis Chamberlain wrote:
> On Fri, Jun 02, 2023 at 01:06:30PM +0200, Joel Granados wrote:
> > Resending as the first set got mangled with smtp error.
> >
> > This is part of the effort to remove the empty element of the ctl_table
> > structures (used to calculate size) and replace it with an ARRAY_SIZE call. By
> > replacing the child element in struct ctl_table with a flags element we make
> > sure that there are no forward recursions on child nodes and therefore set
> > ourselves up for just using an ARRAY_SIZE. We also added some self tests to
> > make sure that we do not break anything.
> >
> > Patchset is separated in 4: parport fixes, selftests fixes, selftests additions and
> > replacement of child element. Tested everything with sysctl self tests and everything
> > seems "ok".
> >
> > 1. parport fixes: @mcgrof: this is related to my previous series and it plugs a
> > sysct table leak in the parport driver. Please tell me if you want me to repost
> > the parport series with this one stiched in.
> >
> > 2. Selftests fixes: Remove the prefixed zeros when passing a awk field to the
> > awk print command because it was causing $0009 to be interpreted as $0.
> > Replaced continue with return in sysctl.sh(test_case) so the test actually
> > gets skipped. The skip decision is now in sysctl.sh(skip_test).
> >
> > 3. Selftest additions: New test to confirm that unregister actually removes
> > targets. New test to confirm that permanently empty targets are indeed
> > created and that no other targets can be created "on top".
> >
> > 4. Replaced the child pointer in struct ctl_table with a u8 flag. The flag
> > is used to differentiate between permanently empty targets and non-empty ones.
> >
> > Comments/feedback greatly appreciated
>
> This all looks great, thanks so much for doing all this work! I pushed
> to sysctl-next.
I have a version where I replace the u8 flag with an enumeration with
two memebers. Tell me if it make sense to post the V2 and I'll send it
out after fixing it up a bit.

Best

Joel Granados


Attachments:
(No filename) (2.11 kB)
signature.asc (673.00 B)
Download all attachments