-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
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? |
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 |
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. |
04860b5
to
7c4a015
Compare
I think that the problem is a bad behaviour of fts_read() with the combination {linux, glibc 2.39, armhf). |
OK. I think the configure.ac test is overkill :-) (don't forget that the user can update libc, etc.) It would be better to always compile if FTS is available, add the check to tests/helpers/test_sysinfo.c, and use it in the tests/ts/fin core/count to define @teknoraver sorry for all the extra work, it's more complicated than I had originally expected ;-) |
f332cd9
to
e20c640
Compare
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>
@karelzak it works, the armv7 test just skipped it as
|
Add a --recursive flag to
fincore
which allows to recursively scan directories.