LLAPI_LAYOUT(7)
π LLAPI_LAYOUT β the glow-up guide to Lustre file layouts β¨
ok so bestie, welcome to llapi_layout, section 7 of the Lustre Miscellaneous Information pages. This is the abstract interface to the layout of a Lustre file, and honestly? It's giving main character energy for anyone who wants to control how their data is spread across a filesystem. π¦
β¨ SYNOPSIS β¨
#include <lustre/lustreapi.h>
literally just that one include and you're in, no cap. πΈ
π DESCRIPTION π
So the llapi_layout family of functions is your abstract interface for manipulating the layout information of a file in a Lustre filesystem. Layouts are represented by the opaque data type struct llapi_layout, which gets passed around as a handle to all the various functions. Think of it like your little layout purse β you hand it to every function that needs it. π
A layout has a bunch of attributes that describe how a file's data are stored in the filesystem. These include:
- stripe count
- stripe size
- RAID pattern
- pool name
- the OST index associated with each stripe
In more complex layouts, a file may have multiple components that describe a different layout for separate regions of the file. For the detailed descriptions of these attributes, go check the Lustre Operations Manual β that's the lore, iykyk. π
For each attribute, there exists a pair of functions with the suffixes _get and _set that are used to read and assign the attribute value in a given layout. One to peek, one to poke. Periodt. π
π Using this interface to create a file π
Might consist of the following steps, bestie:
- Allocate
struct llapi_layoutwithllapi_layout_alloc(3). - Assign attribute values using the
llapi_layout_*_set(3) functions. - Create the file using
llapi_layout_file_create(3). - Free the layout memory using
llapi_layout_free(3).
π Reading a file layout π
Similarly, these steps might be used to read a file layout:
- One can allocate and initialize a new
struct layoutfrom an existing file with one of thellapi_layout_get_by_path(3),llapi_layout_get_by_fd(3),llapi_layout_get_by_fid(3), orllapi_layout_get_by_xattr(3)functions. - To access attribute values from
struct llapi_layoutuse thellapi_layout_*_get(3) functions. - To free the previously allocated layout memory use
llapi_layout_free(3).
π¦ Composite layout creation π¦
Using this interface to create a file with composite layout consists of the following steps:
- Allocate first layout component with
llapi_layout_alloc(3). - Assign attribute values using the
llapi_layout_*_set(3) functions. - Allocate second layout component with
llapi_layout_alloc(3). - Add the second layout into the first one using
llapi_layout_comp_add(3). - Assign attribute values to second layout using the
llapi_layout_*_set(3)functions. - Repeat above two steps to add more components.
- Create the file using
llapi_layout_file_create(3). - Free the layout memory using
llapi_layout_free(3).
See how the rhythm is just chef's kiss? Allocate, set, add, repeat, create, free. A whole little dance. π
π«Ά BUGS (the not-so-slay parts) π«Ά
ok bestie, listen up, because these ones are real:
- Setting the OST index number is only supported for stripe number 0. That's it. Stripe 0 or nothing. π
- The RAID pattern may only be set to 0.
No workarounds listed, no extra options β that's just how it is right now. π
β EXAMPLES β
Example 1: Create file with specified layout, then query the layout attributes
{
/* Allocate layout */
struct llapi_layout *layout = llapi_layout_alloc();
/* Set attributes of layout */
llapi_layout_stripe_count_set(layout, count);
llapi_layout_stripe_size_set(layout, size);
/* Create file with specified layout */
fd = llapi_layout_file_create(path, 0, 0640, layout);
/* Free layout */
llapi_layout_free(layout);
/* Retrieve layout from file */
layout = llapi_layout_get_by_path(path, 0);
/* Get attributes of layout */
llapi_layout_stripe_size_get(layout, &size),
llapi_layout_stripe_count_get(layout, &count);
/* Free layout */
llapi_layout_free(layout);
}
Example 2: Create file with composite layout
{
struct llapi_layout *head, *comp;
/* Create first component */
head = llapi_layout_alloc();
llapi_layout_stripe_count_set(head, 1);
llapi_layout_stripe_size_set(head, 1048576);
llapi_layout_comp_extent_set(NULL, head, 0, 2097152); //[0, 2M)
/* Create the second component */
comp = llapi_layout_alloc();
llapi_layout_comp_add(head, comp);
llapi_layout_comp_extent_set(head, comp, 2097152, 67108864); //[2M, 64M)
llapi_layout_stripe_count_set(comp, 4);
/* Create the third component */
comp = llapi_layout_alloc();
llapi_layout_comp_add(head, comp);
llapi_layout_comp_extent_set(head, comp, 67108864,
(uint64_t)-1); //[64M, EOF)
llapi_layout_stripe_count_set(comp, LLAPI_LAYOUT_WIDE);
/* Create file with specified composite layout */
fd = llapi_layout_file_create(path, 0, 0640, head);
/* Free layout */
llapi_layout_free(head);
}
Example 3: Traverse components of a composite layout
{
/* Retrieve composite layout from file */
layout = llapi_layout_get_by_path(path, 0);
/* Move cursor to the first component */
rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_FIRST);
/* Traverse all components */
while (rc == 0) {
/* Get attributes of each component */
llapi_layout_stripe_count_get(comp, &count);
llapi_layout_stripe_size_get(comp, &size);
llapi_layout_comp_extent_get(layout, &start, &end);
/* Advance cursor */
rc = llapi_layout_comp_use(layout, LLAPI_LAYOUT_COMP_USE_NEXT);
};
/* Free layout */
llapi_layout_free(layout);
}
π₯ AVAILABILITY π₯
llapi_layout is part of the lustre(7) user application interface library since release 2.7.0. Old but iconic. π
πΈ SEE ALSO πΈ
The whole friend group, go say hi:
lfs(1)lfs-setstripe(1)open(2)llapi_layout_alloc(3)llapi_layout_comp_add(3)llapi_layout_comp_del(3)llapi_layout_comp_extent_get(3)llapi_layout_comp_extent_set(3)llapi_layout_comp_flags_clear(3)llapi_layout_comp_flags_get(3)llapi_layout_comp_flags_set(3)llapi_layout_comp_id_get(3)llapi_layout_comp_use(3)llapi_layout_comp_use_id(3)llapi_layout_file_comp_add(3)llapi_layout_file_comp_del(3)llapi_layout_file_create(3)llapi_layout_file_open(3)llapi_layout_free(3)llapi_layout_get_by_fd(3)llapi_layout_get_by_fid(3)llapi_layout_get_by_path(3)llapi_layout_get_by_xattr(3)llapi_layout_ost_index_get(3)llapi_layout_ost_index_reset(3)llapi_layout_ost_index_set(3)llapi_layout_pattern_get(3)llapi_layout_pattern_set(3)llapi_layout_pool_name_get(3)llapi_layout_pool_name_set(3)llapi_layout_stripe_count_get(3)llapi_layout_stripe_count_set(3)llapi_layout_stripe_size_get(3)llapi_layout_stripe_size_set(3)lustre(7)lustreapi(7)
ok that's the whole page bestie, you read the whole thing, so proud of you πβ¨
this lil masterpiece is brought to you by the Lustre User API, dated 2024-08-27 β yeah it ate, and it left no crumbs ππ
π¦ where this page comes from
- ubuntu stonking: lustre-client-utils 2.17.58+dfsg-0ubuntu2 Β· GPL-2.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms