LLAPI_LADVISE(3)

πŸ“¦ version 2.17.58, in ubuntu stonking

πŸ’… LLAPI_LADVISE(3) β€” bestie edition

okay so this is a page from section 3 of the manual, and it lives in the Lustre Library Functions family. it's called llapi_ladvise, and it's literally the vibe of "hey server, here's a lil hint about how i'm gonna do my I/O, do with that what you will." ✨


🌸 NAME 🌸

llapi_ladvise β€” give IO advice/hints on a Lustre file to the server 🫢


✨ SYNOPSIS ✨

#include <lustre/lustreapi.h>

int llapi_ladvise(int fd, unsigned long long flags,
                  int num_advise,
                  struct llapi_lu_ladvise *ladvise);

πŸ’– DESCRIPTION πŸ’–

so llapi_ladvise() takes an array of num_advise I/O hints β€” and bestie, there's a cap, it's a maximum of LAH_COUNT_MAX items, no sneaking extra in there πŸ™ˆ β€” and it ships them in ladvise for the file descriptor fd, sending them from your application out to one or more Lustre servers. oh and optionally, flags can tweak how the advice gets processed, using bitwise-or'd values, which are:

  • LF_ASYNC β€” the client returns to userspace immediately after submitting the ladvise RPCs, and just leaves the server threads to handle the advices asynchronously. no waiting, no stress, main character energy πŸ‘‘
  • LF_UNSET β€” unset/clear a previous advice. (Currently only supports LU_ADVISE_LOCKNOEXPAND.)

Each of the ladvise elements is an llapi_lu_ladvise structure, and it's giving exactly this:

struct llapi_lu_ladvise {
     __u16 lla_advice;   /* advice type */
     __u16 lla_value1;   /* values for different advice types */
     __u32 lla_value2;
     __u64 lla_start;    /* first byte of extent for advice */
     __u64 lla_end;      /* last byte of extent for advice */
     __u32 lla_value3;
     __u32 lla_value4;
};

and the fields break down like this:

  • lla_advice β€” specifies the advice for the given file range, and rn it's one of:
    • LU_LADVISE_WILLREAD β€” prefetch data into server cache using the optimum I/O size for the server. it's giving "pre-gaming the reads" 🌈
    • LU_LADVISE_DONTNEED β€” clean cached data for the specified file range(s) on the server.
    • LU_LADVISE_LOCKAHEAD β€” request an LDLM extent lock of the given mode on the given byte range.
    • LU_LADVISE_NOEXPAND β€” disable extent lock expansion behavior for I/O to this file descriptor.
  • lla_start β€” the offset in bytes for the start of this advice.
  • lla_end β€” the offset in bytes (non-inclusive, so don't @ me) for the end of this advice.
  • lla_value1, lla_value2, lla_value3, lla_value4 β€” extra arguments for future advice types, and bestie you should set these to zero unless they're explicitly required for a given advice type. the advice-specific names for these fields follow πŸ‘‡
  • lla_lockahead_mode β€” when you're using LU_ADVISE_LOCKAHEAD, the lla_value1 field is what communicates the requested lock mode, and you can call it lla_lockahead_mode.
  • lla_peradvice_flags β€” when you're using advices that support them, the lla_value2 field communicates per-advice flags and can be called lla_peradvice_flags. both LF_ASYNC and LF_UNSET are supported as peradvice flags.
  • lla_lockahead_result β€” when you're using LU_ADVISE_LOCKAHEAD, the lla_value3 field communicates the result of the request, and can be called lla_lockahead_result.

k so here's the thing: llapi_ladvise() forwards the advice to Lustre servers without guaranteeing how and when servers will react to the advice. actions may or may not be triggered when the advices are received β€” it depends on the type of the advice plus the real-time decision of whatever server-side components are affected. so like, it's a hint, not a demand. it's giving "suggestion box", not "manager override" πŸ’€

the typical usage of llapi_ladvise() is to let applications and users (thru lfs ladvise(1)) who have external knowledge about application I/O patterns intervene in server-side I/O handling. for example πŸ”₯: if a group of different clients are doing small random reads of a file, prefetching pages into OSS cache with big linear reads before the random IO is a net benefit. but fetching that data into each client cache with fadvise()? maybe not β€” because way more data ends up being sent to the clients. it's giving "don't ship the whole store to my house".

LU_LADVISE_LOCKAHEAD merits a special comment, and honestly it deserves one πŸ‘‘. while it's possible and encouraged to use it directly in your application to avoid lock contention (primarily for writing to a single file from multiple clients), it will also be available in the MPI-I/O / MPICH library from ANL for use with the i/o aggregation mode of that library. this is intended (eventually) to be the primary way this feature is used. glow up arc, fr fr.

and while it's conceptually similar to the posix_fadvise(2) and Linux fadvise(2) system calls, the main difference of llapi_ladvise() is that fadvise()/posix_fadvise() are client side mechanisms that do not pass advice to the filesystem, while llapi_ladvise() sends advice or hints to one or more Lustre servers where the file is actually stored. in some cases it may be desirable to use both interfaces β€” best of both worlds, no cap πŸ’…


πŸŽ€ RETURN VALUES πŸŽ€

llapi_ladvise() returns 0 on success, or -1 if an error occurred (and in that case, errno is set appropriately). so like, check your errno, bestie, it's trying to tell you something 😭


😭 ERRORS 😭

  • ENOMEM β€” insufficient memory to complete operation. not enough brain space, literally.
  • EINVAL β€” one or more invalid arguments are given. check ur args bestie πŸ™ˆ
  • EFAULT β€” memory region pointed by ladvise is not properly mapped.
  • EOPNOTSUPP β€” advice type is not supported. before Lustre 2.16, the NFS-specific error code was returned, but this does not print a useful error string. (iconic behaviour, honestly πŸ’€)

🌟 AVAILABILITY 🌟

llapi_ladvise() is part of the lustre(7) user application interface library since release 2.9.0. it's been here, it's been that girl 🧚


πŸ‘€ SEE ALSO πŸ‘€


and that's the whole page, bestie β€” shoutout to Lustre User API, dated 2024-08-27, and yes this was LLAPI_LADVISE(3) the entire time. slay, go prefetch something πŸ’–πŸ¦‹βœ¨

πŸ“¦ where this page comes from