public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [RFC] proposed libc interface and man page for listmount
@ 2023-12-05 16:27 Miklos Szeredi
  2023-12-05 17:51 ` Matthew House
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Miklos Szeredi @ 2023-12-05 16:27 UTC (permalink / raw)
  To: libc-alpha, linux-man, Alejandro Colomar, Linux API,
	Florian Weimer, linux-fsdevel, Karel Zak, Ian Kent,
	David Howells, Christian Brauner, Amir Goldstein, Arnd Bergmann

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

Attaching the proposed man page for listing mounts (based on the new
listmount() syscall).

The raw interface is:

       syscall(__NR_listmount, const struct mnt_id_req __user *, req,
                  u64 __user *, buf, size_t, bufsize, unsigned int, flags);

The proposed libc API is.

       struct listmount *listmount_start(uint64_t mnt_id, unsigned int flags);
       uint64_t listmount_next(struct listmount *lm);
       void listmount_end(struct listmount *lm);

I'm on the opinion that no wrapper is needed for the raw syscall, just
like there isn't one for getdents(2).

Comments?

Thanks,
Miklos

Sample implementation:
--------------------------------

#define LM_BUFSIZE 4096

struct listmount {
        size_t num;
        size_t pos;
        uint64_t mnt_id;
        unsigned int flags;
        uint64_t buf[LM_BUFSIZE];
};

static int do_listmount(struct listmount *lm)
{
        struct mnt_id_req req = {
                .mnt_id = lm->mnt_id,
                .param = lm->buf[LM_BUFSIZE - 1],
        };
        long res;

        res = syscall(__NR_listmount, &req, lm->buf, LM_BUFSIZE, lm->flags);
        if (res != -1) {
                lm->num = res;
                lm->pos = 0;
        }
        return res;
}

struct listmount *listmount_start(uint64_t mnt_id, unsigned int flags)
{
        int res;
        struct listmount *lm = calloc(1, sizeof(*lm));

        if (lm) {
                lm->mnt_id = mnt_id;
                lm->flags = flags;
                res = do_listmount(lm);
                if (res == -1) {
                        free(lm);
                        lm = NULL;
                }
        }

        return lm;
}

uint64_t listmount_next(struct listmount *lm)
{
        int res;

        if (lm->pos == LM_BUFSIZE) {
                res = do_listmount(lm);
                if (res == -1)
                        return 0;
        }

        /* End of list? */
        if (lm->pos == lm->num)
                return 0;

        return lm->buf[lm->pos++];
}

void listmount_end(struct listmount *lm)
{
        free(lm);
}

[-- Attachment #2: listmount_start.3 --]
[-- Type: application/x-troff-man, Size: 1998 bytes --]

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

* Re: [RFC] proposed libc interface and man page for listmount
  2023-12-05 16:27 [RFC] proposed libc interface and man page for listmount Miklos Szeredi
@ 2023-12-05 17:51 ` Matthew House
  2023-12-06  9:38   ` Miklos Szeredi
  2023-12-05 18:26 ` Karel Zak
  2023-12-06 11:05 ` Florian Weimer
  2 siblings, 1 reply; 7+ messages in thread
From: Matthew House @ 2023-12-05 17:51 UTC (permalink / raw)
  To: Miklos Szeredi
  Cc: libc-alpha, linux-man, Alejandro Colomar, Linux API,
	Florian Weimer, linux-fsdevel, Karel Zak, Ian Kent,
	David Howells, Christian Brauner, Amir Goldstein, Arnd Bergmann

On Tue, Dec 5, 2023 at 11:28 AM Miklos Szeredi <miklos@szeredi.hu> wrote:
> Attaching the proposed man page for listing mounts (based on the new
> listmount() syscall).
>
> The raw interface is:
>
>        syscall(__NR_listmount, const struct mnt_id_req __user *, req,
>                   u64 __user *, buf, size_t, bufsize, unsigned int, flags);
>
> The proposed libc API is.
>
>        struct listmount *listmount_start(uint64_t mnt_id, unsigned int flags);
>        uint64_t listmount_next(struct listmount *lm);
>        void listmount_end(struct listmount *lm);
>
> I'm on the opinion that no wrapper is needed for the raw syscall, just
> like there isn't one for getdents(2).
>
> Comments?

One use case I've been thinking of involves inspecting the mount list
between syscall(__NR_clone3) and _exit(), so it has to be async-signal-
safe. It would be nice if there were a libc wrapper that accepted a user-
provided buffer and was async-signal-safe, so that I wouldn't have to add
yet another syscall wrapper and redefine the kernel types just for this
use case. (I can't trust the libc not to make its own funny versions of the
types' layouts for its own ends.)

Thank you,
Matthew House

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

* Re: [RFC] proposed libc interface and man page for listmount
  2023-12-05 16:27 [RFC] proposed libc interface and man page for listmount Miklos Szeredi
  2023-12-05 17:51 ` Matthew House
@ 2023-12-05 18:26 ` Karel Zak
  2023-12-06  9:40   ` Miklos Szeredi
  2023-12-06 11:05 ` Florian Weimer
  2 siblings, 1 reply; 7+ messages in thread
From: Karel Zak @ 2023-12-05 18:26 UTC (permalink / raw)
  To: Miklos Szeredi
  Cc: libc-alpha, linux-man, Alejandro Colomar, Linux API,
	Florian Weimer, linux-fsdevel, Ian Kent, David Howells,
	Christian Brauner, Amir Goldstein, Arnd Bergmann

On Tue, Dec 05, 2023 at 05:27:58PM +0100, Miklos Szeredi wrote:
> Attaching the proposed man page for listing mounts (based on the new
> listmount() syscall).
> 
> The raw interface is:
> 
>        syscall(__NR_listmount, const struct mnt_id_req __user *, req,
>                   u64 __user *, buf, size_t, bufsize, unsigned int, flags);
> 
> The proposed libc API is.
> 
>        struct listmount *listmount_start(uint64_t mnt_id, unsigned int flags);
>        uint64_t listmount_next(struct listmount *lm);
>        void listmount_end(struct listmount *lm);

What about:

    getmountlist()
    nextmountlist()
    freemountlist()

For me, _start and _end() sounds strange. For example, We already use
get+free for getaddrinfo().

    Karel


-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com


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

* Re: [RFC] proposed libc interface and man page for listmount
  2023-12-05 17:51 ` Matthew House
@ 2023-12-06  9:38   ` Miklos Szeredi
  2023-12-06 16:53     ` Matthew House
  0 siblings, 1 reply; 7+ messages in thread
From: Miklos Szeredi @ 2023-12-06  9:38 UTC (permalink / raw)
  To: Matthew House
  Cc: libc-alpha, linux-man, Alejandro Colomar, Linux API,
	Florian Weimer, linux-fsdevel, Karel Zak, Ian Kent,
	David Howells, Christian Brauner, Amir Goldstein, Arnd Bergmann

On Tue, 5 Dec 2023 at 18:51, Matthew House <mattlloydhouse@gmail.com> wrote:
>
> On Tue, Dec 5, 2023 at 11:28 AM Miklos Szeredi <miklos@szeredi.hu> wrote:
> > Attaching the proposed man page for listing mounts (based on the new
> > listmount() syscall).
> >
> > The raw interface is:
> >
> >        syscall(__NR_listmount, const struct mnt_id_req __user *, req,
> >                   u64 __user *, buf, size_t, bufsize, unsigned int, flags);
> >
> > The proposed libc API is.
> >
> >        struct listmount *listmount_start(uint64_t mnt_id, unsigned int flags);
> >        uint64_t listmount_next(struct listmount *lm);
> >        void listmount_end(struct listmount *lm);
> >
> > I'm on the opinion that no wrapper is needed for the raw syscall, just
> > like there isn't one for getdents(2).
> >
> > Comments?
>
> One use case I've been thinking of involves inspecting the mount list
> between syscall(__NR_clone3) and _exit(), so it has to be async-signal-
> safe. It would be nice if there were a libc wrapper that accepted a user-
> provided buffer and was async-signal-safe, so that I wouldn't have to add
> yet another syscall wrapper and redefine the kernel types just for this
> use case. (I can't trust the libc not to make its own funny versions of the
> types' layouts for its own ends.)

You can just #include <linux/mount.h> directly.

Thanks,
Miklos

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

* Re: [RFC] proposed libc interface and man page for listmount
  2023-12-05 18:26 ` Karel Zak
@ 2023-12-06  9:40   ` Miklos Szeredi
  0 siblings, 0 replies; 7+ messages in thread
From: Miklos Szeredi @ 2023-12-06  9:40 UTC (permalink / raw)
  To: Karel Zak
  Cc: libc-alpha, linux-man, Alejandro Colomar, Linux API,
	Florian Weimer, linux-fsdevel, Ian Kent, David Howells,
	Christian Brauner, Amir Goldstein, Arnd Bergmann

On Tue, 5 Dec 2023 at 19:26, Karel Zak <kzak@redhat.com> wrote:
>
> On Tue, Dec 05, 2023 at 05:27:58PM +0100, Miklos Szeredi wrote:
> > Attaching the proposed man page for listing mounts (based on the new
> > listmount() syscall).
> >
> > The raw interface is:
> >
> >        syscall(__NR_listmount, const struct mnt_id_req __user *, req,
> >                   u64 __user *, buf, size_t, bufsize, unsigned int, flags);
> >
> > The proposed libc API is.
> >
> >        struct listmount *listmount_start(uint64_t mnt_id, unsigned int flags);
> >        uint64_t listmount_next(struct listmount *lm);
> >        void listmount_end(struct listmount *lm);
>
> What about:
>
>     getmountlist()
>     nextmountlist()
>     freemountlist()
>
> For me, _start and _end() sounds strange. For example, We already use
> get+free for getaddrinfo().

Fine by me.  Just wanted to get the general scheme out for comment.

Thanks,
Miklos

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

* Re: [RFC] proposed libc interface and man page for listmount
  2023-12-05 16:27 [RFC] proposed libc interface and man page for listmount Miklos Szeredi
  2023-12-05 17:51 ` Matthew House
  2023-12-05 18:26 ` Karel Zak
@ 2023-12-06 11:05 ` Florian Weimer
  2 siblings, 0 replies; 7+ messages in thread
From: Florian Weimer @ 2023-12-06 11:05 UTC (permalink / raw)
  To: Miklos Szeredi
  Cc: libc-alpha, linux-man, Alejandro Colomar, Linux API,
	linux-fsdevel, Karel Zak, Ian Kent, David Howells,
	Christian Brauner, Amir Goldstein, Arnd Bergmann

* Miklos Szeredi:

> Attaching the proposed man page for listing mounts (based on the new
> listmount() syscall).
>
> The raw interface is:
>
>        syscall(__NR_listmount, const struct mnt_id_req __user *, req,
>                   u64 __user *, buf, size_t, bufsize, unsigned int, flags);
>
> The proposed libc API is.
>
>        struct listmount *listmount_start(uint64_t mnt_id, unsigned int flags);
>        uint64_t listmount_next(struct listmount *lm);
>        void listmount_end(struct listmount *lm);
>
> I'm on the opinion that no wrapper is needed for the raw syscall, just
> like there isn't one for getdents(2).

We do have a wrapper for getdents64.  It's useful because if you modify
the directory, you care about the buffer boundary because you should
rewind after processing the current buffer.  The inotify facility also
exposes a sequence of variably sized objects to applications, but does
not add a new system call for that.  That's just an aside, though.

The existing functions dealing with /proc/mounts or /etc/fstab are
called setmntent, getmntent or getmntment_r (the former with a bad
implementation, the latter with a bad interface), and endmntent.  This
follows the pattern of NSS enumeration interfaces, except that in the
mntent case, there is an explicit file handle, so a thread-safe
implementation is possible in principle.  Your proposed interface is
similar, so that's good.

I would also like to see a comment from the Hurd folks.  Presumably they
have something similar already for enumerating translators?

Thanks,
Florian


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

* Re: [RFC] proposed libc interface and man page for listmount
  2023-12-06  9:38   ` Miklos Szeredi
@ 2023-12-06 16:53     ` Matthew House
  0 siblings, 0 replies; 7+ messages in thread
From: Matthew House @ 2023-12-06 16:53 UTC (permalink / raw)
  To: Miklos Szeredi
  Cc: libc-alpha, linux-man, Alejandro Colomar, Linux API,
	Florian Weimer, linux-fsdevel, Karel Zak, Ian Kent,
	David Howells, Christian Brauner, Amir Goldstein, Arnd Bergmann

On Wed, Dec 6, 2023 at 4:38 AM Miklos Szeredi <miklos@szeredi.hu> wrote:
> On Tue, 5 Dec 2023 at 18:51, Matthew House <mattlloydhouse@gmail.com> wrote:
> > One use case I've been thinking of involves inspecting the mount list
> > between syscall(__NR_clone3) and _exit(), so it has to be async-signal-
> > safe. It would be nice if there were a libc wrapper that accepted a user-
> > provided buffer and was async-signal-safe, so that I wouldn't have to add
> > yet another syscall wrapper and redefine the kernel types just for this
> > use case. (I can't trust the libc not to make its own funny versions of the
> > types' layouts for its own ends.)
>
> You can just #include <linux/mount.h> directly.

The problem with including the <linux/*> headers is that they conflict with
the regular libc headers. So for instance, if I try to include both
<linux/mount.h> (for the listmount(2) kernel types) and <sys/mount.h> (for
the mount(2) and umount2(2) wrappers) on glibc, then I'll get a conflicting
definition for every single MS_* macro.

I suppose I could try to put all the listmount(2) stuff in a separate file,
but that would still require manual redefinitions of the listmount(2)
flags, unless I trusted libc to have its own identical redefinitions in
<sys/mount.h> or whatever header the wrapper would end up in, instead of
shuffling stuff around and translating it. Also, my current style in C is
to put all related code into a single file as possible, which this would
interfere with. At that point, I might as well redefine the whole thing.

Thank you,
Matthew House

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

end of thread, other threads:[~2023-12-06 16:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-05 16:27 [RFC] proposed libc interface and man page for listmount Miklos Szeredi
2023-12-05 17:51 ` Matthew House
2023-12-06  9:38   ` Miklos Szeredi
2023-12-06 16:53     ` Matthew House
2023-12-05 18:26 ` Karel Zak
2023-12-06  9:40   ` Miklos Szeredi
2023-12-06 11:05 ` Florian Weimer

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 read-only IMAP folder(s) and NNTP newsgroup(s).