-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fincore: add recursive directory scanning #3529
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
How portable are the fts_*() functions? It will probably require some modifications to configure.ac and meson.build, along with some #ifdefs. Would it be more portable to use nftw(), which is POSIX compatible? (Yes, with fts it seems more elegant, just one while()). |
the manpage says "These functions are available in Linux since glibc2" |
@karelzak I looked at nftw(). It's a cool API, but it has a big disadvantage, there isn't any way to pass an argument to the handler, and we need both fincore_control and fincore_state to pass. |
Using Anyway, I agree that FTS looks better (no callbacks). We can try to use it since From fded72bd8269206ad4208e9a2372898a35070eea Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Wed, 16 Apr 2025 09:40:46 +0200
Subject: [PATCH] fincore: fincore_state refactoring
---
misc-utils/fincore.c | 34 ++++++++++++----------------------
1 file changed, 12 insertions(+), 22 deletions(-)
diff --git a/misc-utils/fincore.c b/misc-utils/fincore.c
index a2f240052..7a4b5185b 100644
--- a/misc-utils/fincore.c
+++ b/misc-utils/fincore.c
@@ -356,12 +356,12 @@ static int fincore_fd (struct fincore_control *ctl,
/*
* Returns: <0 on error, 0 success, 1 ignore.
*/
-static int fincore_name(struct fincore_control *ctl,
- struct fincore_state *st)
+static int fincore_name(struct fincore_control *ctl, const char *name)
{
int fd;
int rc = 0;
struct stat sb;
+ struct fincore_state _st = { .name = name }, *st = &_st;
if ((fd = open (st->name, O_RDONLY)) < 0) {
warn(_("failed to open: %s"), st->name);
@@ -381,15 +381,15 @@ static int fincore_name(struct fincore_control *ctl,
warn(_("failed ioctl to get size: %s"), st->name);
} else if (S_ISREG(sb.st_mode)) {
st->file_size = sb.st_size;
- } else {
- rc = 1; /* ignore things like symlinks
- * and directories*/
}
if (!rc)
rc = fincore_fd(ctl, fd, st);
- close (fd);
+ close(fd);
+
+ if (!rc)
+ rc = add_output_data(ctl, st);
return rc;
}
@@ -538,24 +538,14 @@ int main(int argc, char ** argv)
}
for(; optind < argc; optind++) {
- struct fincore_state st = {
- .name = argv[optind],
- };
-
- switch (fincore_name(&ctl, &st)) {
- case 0:
- add_output_data(&ctl, &st);
+ rc = fincore_name(&ctl, argv[optind]);
+ if (rc)
break;
- case 1:
- break; /* ignore */
- default:
- rc = EXIT_FAILURE;
- break;
- }
}
- scols_print_table(ctl.tb);
- scols_unref_table(ctl.tb);
+ if (rc == 0)
+ scols_print_table(ctl.tb);
- return rc;
+ scols_unref_table(ctl.tb);
+ return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
--
2.49.0 |
Unfortunately musl does not implement FTS. |
Yes, but if we all ignore FTS, it will never be adopted by other libcs. :-) I have no strong opinion about it. Both ways (nftw with global ctl strcut; or FTS with errx on poor libcs) work for me. |
For musl to adopt it I guess it would need to make it into POSIX first. |
@karelzak I like it, if you merge it I will rebase and fix my PR |
d36ba92
to
4b3976c
Compare
|
87dc1a0
to
bc197b5
Compare
@karelzak I had to refactor your change because it broke the test by changing the behavour in a substantial way. |
3fe1614
to
00afda6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some tests would also be great.
7161fa6
to
6b3c84c
Compare
@t-8ch the problem with the recursive test is that the scan order is not consistent among runs, making the output diff unreliable |
23c6c0b
to
a5ed630
Compare
It looks good (after the meson update). @t-8ch, is there any objection? |
You can run the output through |
I'd really like to see tests. |
@t-8ch the tests are there, but unfortunately an unrelated one (findmnt/listmount) started failing and the CI is red |
@karelzak I'm pretty sure that the test won't pass on a system with 16k or 64k page size, but I don't have such machine to test on |
Ah, yes, that's a good point. I thought about that too when @teknoraver sent the first version, but I forgot to discuss it. The mincore() and cachestat() functions are restricted to mapped files (such as regular files or /dev/mem, |
fts_open works with regular files as well. |
@glaubitz You tend to have access to a lot of exotic machines. Could you run the tests on a 64k pagesize machine? |
Yeah, I can boot a ppc64 machine into a kernel with 64k pages enabled. Debian provides kernel packages with 64k pagesize for both big- and little-endian ppc64. Can you tell me what repo and branch to test so I don't have to dig through the message list? |
@glaubitz hi! The repo is: and the branch I've fixed the test blindly, let me know if the pass on a 64k page size machine |
The test
|
@teknoraver I guess --raw option may help you. |
There is still some diff left, unfortunately:
|
How about appending sed?
|
@masatake I'd rather add --raw everywhere and make the test more stable. |
@glaubitz I removed all spaces from the expected files and used --raw. |
Yes, it works now:
|
I have turned 16k pages on on my ARM machine, and I've extended the test to work with such size too:
This is the default on Apple ARM machines running Linux |
The test failure in the distcheck CI job looks genuine. |
I saw it but I can't understand:
|
Maybe replace |
Add a --recursive flag to fincore which allows to recursively scan directories. Co-authored-by: Karel Zak <kzak@redhat.com> Signed-off-by: Matteo Croce <teknoraver@meta.com>
Hmm qemu-user armv7 is the only one failing now. --- /home/runner/work/util-linux/util-linux/tests/output/fincore/count.aggregate 2025-04-28 22:41:38.297718592 +0000
+++ /home/runner/work/util-linux/util-linux/tests/output/fincore/count 2025-04-28 22:41:47.448702913 +0000
@@ -58,8 +58,4 @@
1 4096 i_dir/JUST_PAGESIZE_incore_
return value: 0
[ RECURSIVE SCAN ]
-0 0 i_dir/EMPTY_FILE
-1 4095 i_dir/PAGESIZE_-1__incore_
-1 4096 i_dir/JUST_PAGESIZE_incore_
-PAGES SIZE FILE
return value: 0 This is weird, how can I reproduce such test locally? |
You don't have to insist on reproducing the issue locally. To shorten the debugging cycle, disable all CI/CD environments other than qemu-user armv7. |
Add a --recursive flag to
fincore
which allows to recursively scan directories.