mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] What if the line in /proc/mounts is too long when calling getmntent_r?
@ 2021-08-27  4:48 care
  2021-08-27 13:05 ` Érico Nogueira
  0 siblings, 1 reply; 6+ messages in thread
From: care @ 2021-08-27  4:48 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 3708 bytes --]

Hi!
  I want to get cgroups mount information from /proc/mounts, but when i calling struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen), i got nothing...
  I run the program in a container.

  alpine docker image:  amd64/alpine:3.14
  musl: 1.2.2
  program:  
#include <stdio.h&gt;#include <stdlib.h&gt;#include <mntent.h&gt;
#define CGROUP_MAX_VAL 512
int main(void){&nbsp; struct mntent ent;&nbsp; FILE *f;&nbsp; char buf[CGROUP_MAX_VAL];
&nbsp; f = setmntent("/proc/mounts", "r");&nbsp; if (f == NULL) {&nbsp; &nbsp; perror("setmntent");&nbsp; &nbsp; exit(1);&nbsp; }
&nbsp; while (getmntent_r(f, &amp;ent, buf, sizeof(buf)) != NULL) {&nbsp; &nbsp; printf("%s %s\n", ent.mnt_type, ent.mnt_opts);&nbsp; }
&nbsp; endmntent(f);}&nbsp; contents of file "/proc/mounts"
overlay / overlay rw,relatime,lowerdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/955/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/954/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/953/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/952/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/941/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/940/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/879/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/325/fs,upperdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/956/fs,workdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/956/work 0 0proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0tmpfs /dev tmpfs rw,nosuid,size=65536k,mode=755 0 0devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666 0 0mqueue /dev/mqueue mqueue rw,nosuid,nodev,noexec,relatime 0 0sysfs /sys sysfs ro,nosuid,nodev,noexec,relatime 0 0tmpfs /sys/fs/cgroup tmpfs rw,nosuid,nodev,noexec,relatime,mode=755 0 0cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0cgroup /sys/fs/cgroup/net_cls,net_prio cgroup rw,nosuid,nodev,noexec,relatime,net_prio,net_cls 0 0cgroup /sys/fs/cgroup/pids cgroup rw,nosuid,nodev,noexec,relatime,pids 0 0cgroup /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0cgroup /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0cgroup /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0cgroup /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0cgroup /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct,cpu 0 0cgroup /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0cgroup /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0...

&nbsp; I find the first line of the file /proc/mounts has 822 characters(In theory the 'overlay' could be even longer), more than CGROUP_MAX_VAL(512) defined in the proagram. Function fget in&nbsp;getmntent_r&nbsp;cann't get the whole line into linebuf, neither the character '\n'. And the function strchr(linebuf, '\n') returns false, causing program returnd.&nbsp;
&nbsp; The function&nbsp;struct mntent *getmntent(FILE *f)&nbsp;is a good chioce to deal this. But it can not be used in multiple threads, right?
&nbsp; Maybe the implementation of GNU libc&nbsp;struct mntent *__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)&nbsp;can be referenced.


&nbsp; thanks!

[-- Attachment #2: Type: text/html, Size: 10702 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread
* Re: [musl] What if the line in /proc/mounts is too long when calling getmntent_r?
@ 2021-08-27 13:26 Érico Nogueira
  2021-08-27 13:43 ` Rich Felker
  0 siblings, 1 reply; 6+ messages in thread
From: Érico Nogueira @ 2021-08-27 13:26 UTC (permalink / raw)
  To: musl, 2010267516

Apparently I failed to CC you	in my original reply, sorry.

Forwarded message from Érico Nogueira on Fri Aug 27, 2021 at 10:05 AM:

Unfortunately your message was sent all garbled (please try to stick to
plain text email ;), so I'm reproducing it cleanly underneath with my
answer:

>Hi!
>  I want to get cgroups mount information from /proc/mounts, but when i calling struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen), i got nothing...
>  I run the program in a container.
>
>  alpine docker image:  amd64/alpine:3.14
>  musl: 1.2.2
>  program:  
>
>    #include <stdio.h>
>
>    #include <stdlib.h>
>
>    #include <mntent.h>
>
>
>    #define CGROUP_MAX_VAL 512
>
>
>    int main(void)
>
>    {
>
>      struct mntent ent;
>
>      FILE *f;
>
>      char buf[CGROUP_MAX_VAL];
>
>
>      f = setmntent("/proc/mounts", "r");
>
>      if (f == NULL) {
>
>        perror("setmntent");
>
>        exit(1);
>
>      }
>
>
>      while (getmntent_r(f, &ent, buf, sizeof(buf)) != NULL) {
>
>        printf("%s %s\n", ent.mnt_type, ent.mnt_opts);
>
>      }

The man page specifies that getmntent_r can return NULL on error, you
should check errno to see if anything happened. In this case, it would
be ERANGE, which tells you your buffer was too small.

>
>
>      endmntent(f);
>
>    }
>
>  contents of file "/proc/mounts"
>
>    overlay / overlay rw,relatime,lowerdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/955/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/954/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/953/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/952/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/941/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/940/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/879/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/325/fs,upperdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/956/fs,workdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/956/work 0 0
>
>    proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
>
>    tmpfs /dev tmpfs rw,nosuid,size=65536k,mode=755 0 0
>
>    devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666 0 0
>
>    mqueue /dev/mqueue mqueue rw,nosuid,nodev,noexec,relatime 0 0
>
>    sysfs /sys sysfs ro,nosuid,nodev,noexec,relatime 0 0
>
>    tmpfs /sys/fs/cgroup tmpfs rw,nosuid,nodev,noexec,relatime,mode=755 0 0
>
>    cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0
>
>    cgroup /sys/fs/cgroup/net_cls,net_prio cgroup rw,nosuid,nodev,noexec,relatime,net_prio,net_cls 0 0
>
>    cgroup /sys/fs/cgroup/pids cgroup rw,nosuid,nodev,noexec,relatime,pids 0 0
>
>    cgroup /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0
>
>    cgroup /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
>
>    cgroup /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
>
>    cgroup /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0
>
>    cgroup /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
>
>    cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct,cpu 0 0
>
>    cgroup /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
>
>    cgroup /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
>
>    ...
>
>
>  I find the first line of the file /proc/mounts has 822 characters(In theory the 'overlay' could be even longer), more than CGROUP_MAX_VAL(512) defined in the proagram. Function fget in getmntent_r cann't get the whole line into linebuf, neither the character '\n'. And the function strchr(linebuf, '\n') returns false, causing program returnd. 
>  The function struct mntent *getmntent(FILE *f) is a good chioce to deal this. But it can not be used in multiple threads, right?

Correct, getmntent isn't thread safe.

>  Maybe the implementation of GNU libc struct mntent *__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz) can be referenced.

From what I can see, glibc silently throws away any and all chars that
don't fit in the provided buffer until it finds a newline. getmntent_r
isn't actually specified, so I guess its behavior is a bit up to the
implementation. Anyhow, musl's reports ERANGE properly (maybe the man
page can be fixed to mention it?) and you should use a dynamic buffer in
your program if you expect to deal with huge entries, and resize it if
getmntent_r fails with ERANGE.

>
>  thanks!


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-08-28  6:17 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-27  4:48 [musl] What if the line in /proc/mounts is too long when calling getmntent_r? care
2021-08-27 13:05 ` Érico Nogueira
2021-08-27 13:26 Érico Nogueira
2021-08-27 13:43 ` Rich Felker
2021-08-28  2:58   ` Érico Nogueira
2021-08-28  6:17     ` Markus Wichmann

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

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).