* [RFC] eal: use C library to parse filesystem table
@ 2025-11-22 19:49 Stephen Hemminger
2025-11-24 13:53 ` Bruce Richardson
0 siblings, 1 reply; 2+ messages in thread
From: Stephen Hemminger @ 2025-11-22 19:49 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
Rather than doing parsing of /proc/mounts with open coded string
handling, use the standard C library routines.
These exist in BSD and Linux.
It also avoids any possible issues with escaped strings etc
which the library handles. See getmntent(3) man page.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/eal/linux/eal_hugepage_info.c | 45 ++++++++++---------------------
1 file changed, 14 insertions(+), 31 deletions(-)
diff --git a/lib/eal/linux/eal_hugepage_info.c b/lib/eal/linux/eal_hugepage_info.c
index d47a19c56a..ecc0374204 100644
--- a/lib/eal/linux/eal_hugepage_info.c
+++ b/lib/eal/linux/eal_hugepage_info.c
@@ -13,6 +13,7 @@
#include <inttypes.h>
#include <unistd.h>
#include <errno.h>
+#include <mntent.h>
#include <sys/mman.h>
#include <sys/stat.h>
@@ -195,23 +196,13 @@ get_default_hp_size(void)
static int
get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len)
{
- enum proc_mount_fieldnames {
- DEVICE = 0,
- MOUNTPT,
- FSTYPE,
- OPTIONS,
- _FIELDNAME_MAX
- };
static uint64_t default_size = 0;
const char proc_mounts[] = "/proc/mounts";
- const char hugetlbfs_str[] = "hugetlbfs";
- const size_t htlbfs_str_len = sizeof(hugetlbfs_str) - 1;
const char pagesize_opt[] = "pagesize=";
const size_t pagesize_opt_len = sizeof(pagesize_opt) - 1;
- const char split_tok = ' ';
- char *splitstr[_FIELDNAME_MAX];
char found[PATH_MAX] = "";
char buf[BUFSIZ];
+ struct mntent entry;
const struct internal_config *internal_conf =
eal_get_internal_configuration();
const size_t hugepage_dir_len = (internal_conf->hugepage_dir != NULL) ?
@@ -226,35 +217,28 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len)
return -1;
}
- FILE *fd = fopen(proc_mounts, "r");
- if (fd == NULL)
+ FILE *mounts = setmntent(proc_mounts, "r");
+ if (mounts == NULL)
rte_panic("Cannot open %s\n", proc_mounts);
if (default_size == 0)
default_size = get_default_hp_size();
- while (fgets(buf, sizeof(buf), fd)){
+ while (getmntent_r(mounts, &entry, buf, sizeof(buf))) {
const char *pagesz_str;
size_t mountpt_len = 0;
- if (rte_strsplit(buf, sizeof(buf), splitstr, _FIELDNAME_MAX,
- split_tok) != _FIELDNAME_MAX) {
- EAL_LOG(ERR, "Error parsing %s", proc_mounts);
- break; /* return NULL */
- }
-
- if (strncmp(splitstr[FSTYPE], hugetlbfs_str, htlbfs_str_len) != 0)
+ if (strcmp(entry.mnt_type, "hugetlbfs") != 0)
continue;
- pagesz_str = strstr(splitstr[OPTIONS], pagesize_opt);
+ pagesz_str = strstr(entry.mnt_opts, pagesize_opt);
/* if no explicit page size, the default page size is compared */
if (pagesz_str == NULL) {
if (hugepage_sz != default_size)
continue;
- }
- /* there is an explicit page size, so check it */
- else {
+ } else {
+ /* there is an explicit page size, so check it */
uint64_t pagesz = rte_str_to_size(&pagesz_str[pagesize_opt_len]);
if (pagesz != hugepage_sz)
continue;
@@ -264,18 +248,17 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len)
* If no --huge-dir option has been given, we're done.
*/
if (internal_conf->hugepage_dir == NULL) {
- strlcpy(found, splitstr[MOUNTPT], len);
+ strlcpy(found, entry.mnt_dir, len);
break;
}
- mountpt_len = strlen(splitstr[MOUNTPT]);
+ mountpt_len = strlen(entry.mnt_dir);
/*
* Ignore any mount that doesn't contain the --huge-dir directory
* or where mount point is not a parent path of --huge-dir
*/
- if (strncmp(internal_conf->hugepage_dir, splitstr[MOUNTPT],
- mountpt_len) != 0 ||
+ if (strncmp(internal_conf->hugepage_dir, entry.mnt_dir, mountpt_len) != 0 ||
(hugepage_dir_len > mountpt_len &&
internal_conf->hugepage_dir[mountpt_len] != '/')) {
continue;
@@ -286,10 +269,10 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len)
* (so /mnt/1 is preferred over /mnt for matching /mnt/1/2)).
*/
if (mountpt_len > strlen(found))
- strlcpy(found, splitstr[MOUNTPT], len);
+ strlcpy(found, entry.mnt_dir, len);
} /* end while fgets */
- fclose(fd);
+ endmntent(mounts);
if (found[0] != '\0') {
/* If needed, return the requested dir, not the mount point. */
--
2.51.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [RFC] eal: use C library to parse filesystem table
2025-11-22 19:49 [RFC] eal: use C library to parse filesystem table Stephen Hemminger
@ 2025-11-24 13:53 ` Bruce Richardson
0 siblings, 0 replies; 2+ messages in thread
From: Bruce Richardson @ 2025-11-24 13:53 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
On Sat, Nov 22, 2025 at 11:49:21AM -0800, Stephen Hemminger wrote:
> Rather than doing parsing of /proc/mounts with open coded string
> handling, use the standard C library routines.
> These exist in BSD and Linux.
>
> It also avoids any possible issues with escaped strings etc
> which the library handles. See getmntent(3) man page.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> lib/eal/linux/eal_hugepage_info.c | 45 ++++++++++---------------------
> 1 file changed, 14 insertions(+), 31 deletions(-)
>
<snip>
> - pagesz_str = strstr(splitstr[OPTIONS], pagesize_opt);
> + pagesz_str = strstr(entry.mnt_opts, pagesize_opt);
>
> /* if no explicit page size, the default page size is compared */
> if (pagesz_str == NULL) {
> if (hugepage_sz != default_size)
> continue;
> - }
> - /* there is an explicit page size, so check it */
> - else {
> + } else {
> + /* there is an explicit page size, so check it */
> uint64_t pagesz = rte_str_to_size(&pagesz_str[pagesize_opt_len]);
> if (pagesz != hugepage_sz)
> continue;
Since you are already changing this part, this if-else block can be
shortened down to avoid duplicating the continue check:
diff --git a/lib/eal/linux/eal_hugepage_info.c b/lib/eal/linux/eal_hugepage_info.c
index ecc0374204..0e54b35ce1 100644
--- a/lib/eal/linux/eal_hugepage_info.c
+++ b/lib/eal/linux/eal_hugepage_info.c
@@ -227,22 +227,16 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len)
while (getmntent_r(mounts, &entry, buf, sizeof(buf))) {
const char *pagesz_str;
size_t mountpt_len = 0;
+ uint64_t pagesz;
if (strcmp(entry.mnt_type, "hugetlbfs") != 0)
continue;
pagesz_str = strstr(entry.mnt_opts, pagesize_opt);
-
- /* if no explicit page size, the default page size is compared */
- if (pagesz_str == NULL) {
- if (hugepage_sz != default_size)
- continue;
- } else {
- /* there is an explicit page size, so check it */
- uint64_t pagesz = rte_str_to_size(&pagesz_str[pagesize_opt_len]);
- if (pagesz != hugepage_sz)
- continue;
- }
+ pagesz = (pagesz_str == NULL) ? default_size :
+ rte_str_to_size(&pagesz_str[pagesize_opt_len]);
+ if (pagesz != hugepage_sz)
+ continue;
/*
* If no --huge-dir option has been given, we're done.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-11-24 13:53 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-11-22 19:49 [RFC] eal: use C library to parse filesystem table Stephen Hemminger
2025-11-24 13:53 ` Bruce Richardson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).