1 <?xml version='1.0' encoding='UTF-8'?>
2 <chapter xmlns="http://docbook.org/ns/docbook"
3 xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en-US"
4 xml:id="settinglustreproperties">
5 <title xml:id="settinglustreproperties.title">Setting Lustre Properties in a C Program (<literal>llapi</literal>)</title>
6 <para>This chapter describes the <literal>llapi</literal> library of commands used for setting Lustre file properties within a C program running in a cluster environment, such as a data processing or MPI application. The commands described in this chapter are:</para>
9 <para><xref linkend="dbdoclet.50438215_30970"/></para>
12 <para><xref linkend="dbdoclet.50438215_50149"/></para>
15 <para><xref linkend="dbdoclet.50438215_86607"/></para>
18 <para><xref linkend="dbdoclet.50438215_12433"/></para>
21 <para><xref linkend="dbdoclet.50438215_15718"/></para>
25 <para>Lustre programming interface man pages are found in the <literal>lustre/doc</literal> folder.</para>
27 <section xml:id="dbdoclet.50438215_30970">
29 <literal>llapi_file_create</literal>
31 <para>Use <literal>llapi_file_create</literal> to set Lustre properties for a new file.</para>
33 <title>Synopsis</title>
34 <screen>#include <lustre/lustreapi.h>
36 int llapi_file_create(char *name, long stripe_size, int stripe_offset, int stripe_count, int stripe_pattern);
40 <title>Description</title>
41 <para>The <literal>llapi_file_create()</literal> function sets a file descriptor's Lustre
42 file system striping information. The file descriptor is then accessed with
43 <literal>open()</literal>.</para>
44 <informaltable frame="all">
46 <colspec colname="c1" colwidth="50*"/>
47 <colspec colname="c2" colwidth="50*"/>
51 <para><emphasis role="bold">Option</emphasis></para>
54 <para><emphasis role="bold">Description</emphasis></para>
61 <para> <literal>llapi_file_create()</literal></para>
64 <para>If the file already exists, this parameter returns to '<literal>EEXIST</literal>'. If the stripe parameters are invalid, this parameter returns to '<literal>EINVAL</literal>'.</para>
69 <para> <literal>stripe_size</literal></para>
72 <para>This value must be an even multiple of system page size, as shown by <literal>getpagesize()</literal>. The default Lustre stripe size is 4MB.</para>
77 <para> <literal>stripe_offset</literal></para>
80 <para>Indicates the starting OST for this file.</para>
85 <para> <literal>stripe_count</literal></para>
88 <para>Indicates the number of OSTs that this file will be striped across.</para>
93 <para> <literal>stripe_pattern</literal></para>
96 <para>Indicates the RAID pattern.</para>
103 <para>Currently, only RAID 0 is supported. To use the system defaults, set these values: <literal>stripe_size</literal> = 0, <literal>stripe_offset</literal> = -1, <literal>stripe_count</literal> = 0, <literal>stripe_pattern</literal> = 0</para>
107 <title>Examples</title>
108 <para>System default size is 4 MB.</para>
109 <screen>char *tfile = TESTFILE;
110 int stripe_size = 65536</screen>
111 <para>To start at default, run:</para>
112 <screen>int stripe_offset = -1</screen>
113 <para>To start at the default, run:</para>
114 <screen>int stripe_count = 1</screen>
115 <para>To set a single stripe for this example, run:</para>
116 <screen>int stripe_pattern = 0</screen>
117 <para>Currently, only RAID 0 is supported.</para>
118 <screen>int stripe_pattern = 0;
120 rc = llapi_file_create(tfile, stripe_size,stripe_offset, stripe_count,stripe_pattern);</screen>
121 <para>Result code is inverted, you may return with '<literal>EINVAL</literal>' or an ioctl error.</para>
123 fprintf(stderr,"llapi_file_create failed: %d (%s) 0, rc, strerror(-rc));return -1; }</screen>
124 <para><literal>llapi_file_create</literal> closes the file descriptor. You must re-open the descriptor. To do this, run:</para>
125 <screen>fd = open(tfile, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644); if (fd < 0) \ {
126 fprintf(stderr, "Can't open %s file: %s0, tfile,
133 <section xml:id="dbdoclet.50438215_50149">
134 <title>llapi_file_get_stripe</title>
135 <para>Use <literal>llapi_file_get_stripe</literal> to get striping information for a file or directory on a Lustre file system.</para>
137 <title>Synopsis</title>
139 #include <lustre/lustreapi.h>
141 int llapi_file_get_stripe(const char *<emphasis>path</emphasis>, void *<emphasis>lum</emphasis>);</screen>
144 <title>Description</title>
145 <para>The <literal>llapi_file_get_stripe()</literal> function returns striping information for a file or directory <emphasis>path</emphasis> in <emphasis>lum</emphasis> (which should point to a large enough memory region) in one of the following formats:</para>
146 <screen>struct lov_user_md_v1 {
150 __u64 lmm_object_seq;
151 __u32 lmm_stripe_size;
152 __u16 lmm_stripe_count;
153 __u16 lmm_stripe_offset;
154 struct lov_user_ost_data_v1 lmm_objects[0];
155 } __attribute__((packed));
156 struct lov_user_md_v3 {
160 __u64 lmm_object_seq;
161 __u32 lmm_stripe_size;
162 __u16 lmm_stripe_count;
163 __u16 lmm_stripe_offset;
164 char lmm_pool_name[LOV_MAXPOOLNAME];
165 struct lov_user_ost_data_v1 lmm_objects[0];
166 } __attribute__((packed));</screen>
167 <informaltable frame="all">
169 <colspec colname="c1" colwidth="50*"/>
170 <colspec colname="c2" colwidth="50*"/>
174 <para><emphasis role="bold">Option</emphasis></para>
177 <para><emphasis role="bold">Description</emphasis></para>
184 <para> <literal>lmm_magic</literal></para>
187 <para>Specifies the format of the returned striping information. <literal>LOV_MAGIC_V1</literal> is used for lov_user_md_v1. LOV_MAGIC_V3 is used for <literal>lov_user_md_v3</literal>.</para>
192 <para> <literal>lmm_pattern</literal></para>
195 <para>Holds the striping pattern. Only <literal>LOV_PATTERN_RAID0</literal> is
196 possible in this Lustre software release.</para>
201 <para> <literal>lmm_object_id</literal></para>
204 <para>Holds the MDS object ID.</para>
209 <para> <literal>lmm_object_gr</literal></para>
212 <para>Holds the MDS object group.</para>
217 <para> <literal>lmm_stripe_size</literal></para>
220 <para>Holds the stripe size in bytes.</para>
225 <para> <literal>lmm_stripe_count</literal></para>
228 <para>Holds the number of OSTs over which the file is striped.</para>
233 <para> <literal>lmm_stripe_offset</literal></para>
236 <para>Holds the OST index from which the file starts.</para>
241 <para> <literal>lmm_pool_name</literal></para>
244 <para>Holds the OST pool name to which the file belongs.</para>
249 <para> <literal>lmm_objects</literal></para>
252 <para>An array of <literal>lmm_stripe_count</literal> members containing per OST file information in</para>
253 <para>the following format:</para>
254 <screen>struct lov_user_ost_data_v1 {
259 } __attribute__((packed));</screen>
264 <para> <literal>l_object_id</literal></para>
267 <para>Holds the OST's object ID.</para>
272 <para> <literal>l_object_seq</literal></para>
275 <para>Holds the OST's object group.</para>
280 <para> <literal>l_ost_gen</literal></para>
283 <para>Holds the OST's index generation.</para>
288 <para> <literal>l_ost_idx</literal></para>
291 <para>Holds the OST's index in LOV.</para>
299 <title>Return Values</title>
300 <para><literal>llapi_file_get_stripe()</literal> returns:</para>
301 <para><literal>0</literal> On success</para>
302 <para><literal>!= 0</literal> On failure, <literal>errno</literal> is set appropriately</para>
305 <title>Errors</title>
306 <informaltable frame="all">
308 <colspec colname="c1" colwidth="50*"/>
309 <colspec colname="c2" colwidth="50*"/>
313 <para><emphasis role="bold">Errors</emphasis></para>
316 <para><emphasis role="bold">Description</emphasis></para>
323 <para> <literal>ENOMEM</literal></para>
326 <para>Failed to allocate memory</para>
331 <para> <literal>ENAMETOOLONG</literal></para>
334 <para>Path was too long</para>
339 <para> <literal>ENOENT</literal></para>
342 <para>Path does not point to a file or directory</para>
347 <para> <literal>ENOTTY</literal></para>
350 <para>Path does not point to a Lustre file system</para>
355 <para> <literal>EFAULT</literal></para>
358 <para>Memory region pointed by lum is not properly mapped</para>
366 <title>Examples</title>
368 #include <stdio.h>
369 #include <stdlib.h>
370 #include <errno.h>
371 #include <lustre/lustreapi.h>
373 static inline int maxint(int a, int b)
375 return a > b ? a : b;
377 static void *alloc_lum()
380 v1 = sizeof(struct lov_user_md_v1) +
381 LOV_MAX_STRIPE_COUNT * sizeof(struct lov_user_ost_data_v1);
382 v3 = sizeof(struct lov_user_md_v3) +
383 LOV_MAX_STRIPE_COUNT * sizeof(struct lov_user_ost_data_v1);
384 return malloc(maxint(v1, v3));
386 int main(int argc, char** argv)
388 struct lov_user_md *lum_file = NULL;
392 fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
395 lum_file = alloc_lum();
396 if (lum_file == NULL) {
400 rc = llapi_file_get_stripe(argv[1], lum_file);
405 /* stripe_size stripe_count */
406 printf("%d %d\n",
407 lum_file->lmm_stripe_size,
408 lum_file->lmm_stripe_count);
410 if (lum_file != NULL)
417 <section xml:id="dbdoclet.50438215_86607">
419 <literal>llapi_file_open</literal>
421 <para>The <literal>llapi_file_open</literal> command opens (or creates) a file or device on a
422 Lustre file system.</para>
424 <title>Synopsis</title>
425 <screen>#include <lustre/lustreapi.h>
426 int llapi_file_open(const char *<emphasis>name</emphasis>, int <emphasis>flags</emphasis>, int <emphasis>mode</emphasis>,
427 unsigned long long <emphasis>stripe_size</emphasis>, int <emphasis>stripe_offset</emphasis>,
428 int <emphasis>stripe_count</emphasis>, int <emphasis>stripe_pattern</emphasis>);
429 int llapi_file_create(const char *<emphasis>name</emphasis>, unsigned long long <emphasis>stripe_size</emphasis>,
430 int <emphasis>stripe_offset</emphasis>, int <emphasis>stripe_count</emphasis>,
431 int <emphasis>stripe_pattern</emphasis>);
435 <title>Description</title>
436 <para>The <literal>llapi_file_create()</literal> call is equivalent to the <literal>llapi_file_open</literal> call with <emphasis>flags</emphasis> equal to <literal>O_CREAT|O_WRONLY</literal> and <emphasis>mode</emphasis> equal to <literal>0644</literal>, followed by file close.</para>
437 <para><literal>llapi_file_open()</literal> opens a file with a given name on a Lustre file
439 <informaltable frame="all">
441 <colspec colname="c1" colwidth="50*"/>
442 <colspec colname="c2" colwidth="50*"/>
446 <para><emphasis role="bold">Option</emphasis></para>
449 <para><emphasis role="bold">Description</emphasis></para>
456 <para> <literal>flags</literal></para>
459 <para>Can be a combination of <literal>O_RDONLY</literal>, <literal>O_WRONLY</literal>, <literal>O_RDWR</literal>, <literal>O_CREAT</literal>, <literal>O_EXCL</literal>, <literal>O_NOCTTY</literal>, <literal>O_TRUNC</literal>, <literal>O_APPEND</literal>, <literal>O_NONBLOCK</literal>, <literal>O_SYNC</literal>, <literal>FASYNC</literal>, <literal>O_DIRECT</literal>, <literal>O_LARGEFILE</literal>, <literal>O_DIRECTORY</literal>, <literal>O_NOFOLLOW</literal>, <literal>O_NOATIME</literal>.</para>
464 <para> <literal>mode</literal></para>
467 <para>Specifies the permission bits to be used for a new file when <literal>O_CREAT</literal> is used.</para>
472 <para> <literal>stripe_size</literal></para>
475 <para>Specifies stripe size (in bytes). Should be multiple of 64 KB, not exceeding 4 GB.</para>
480 <para> <literal>stripe_offset</literal></para>
483 <para>Specifies an OST index from which the file should start. The default value is -1.</para>
488 <para> <literal>stripe_count</literal></para>
491 <para>Specifies the number of OSTs to stripe the file across. The default value is -1.</para>
496 <para> <literal>stripe_pattern</literal></para>
499 <para>Specifies the striping pattern. In this release of the Lustre software, only
500 <literal>LOV_PATTERN_RAID0</literal> is available. The default value is
509 <title>Return Values</title>
510 <para><literal>llapi_file_open()</literal> and <literal>llapi_file_create()</literal> return:</para>
511 <para><literal>>=0</literal> On success, for <literal>llapi_file_open</literal> the return value is a file descriptor</para>
512 <para><literal><0</literal> On failure, the absolute value is an error code</para>
515 <title>Errors</title>
516 <informaltable frame="all">
518 <colspec colname="c1" colwidth="50*"/>
519 <colspec colname="c2" colwidth="50*"/>
523 <para><emphasis role="bold">Errors</emphasis></para>
526 <para><emphasis role="bold">Description</emphasis></para>
533 <para> <literal>EINVAL</literal></para>
536 <para><literal>stripe_size</literal> or <literal>stripe_offset</literal> or <literal>stripe_count</literal> or <literal>stripe_pattern</literal> is invalid.</para>
541 <para> <literal>EEXIST</literal></para>
544 <para>Striping information has already been set and cannot be altered; <literal>name</literal> already exists.</para>
549 <para> <literal>EALREADY</literal></para>
552 <para>Striping information has already been set and cannot be altered</para>
557 <para> <literal>ENOTTY</literal></para>
561 <literal>name</literal> may not point to a Lustre file system.</para>
569 <title>Example</title>
571 #include <stdio.h>
572 #include <lustre/lustreapi.h>
574 int main(int argc, char *argv[])
579 rc = llapi_file_create(argv[1], 1048576, 0, 2, LOV_PATTERN_RAID0);
581 fprintf(stderr, "file creation has failed, %s\n", strerror(-rc));
584 printf("%s with stripe size 1048576, striped across 2 OSTs,"
585 " has been created!\n", argv[1]);
591 <section xml:id="dbdoclet.50438215_12433">
593 <literal>llapi_quotactl</literal>
595 <para>Use <literal>llapi_quotact</literal>l to manipulate disk quotas on a Lustre file system.</para>
597 <title>Synopsis</title>
598 <screen>#include <lustre/lustreapi.h>
599 int llapi_quotactl(char" " *mnt," " struct if_quotactl" " *qctl)
606 struct obd_dqinfo qc_dqinfo;
607 struct obd_dqblk qc_dqblk;
609 struct obd_uuid obd_uuid;
612 __u64 dqb_bhardlimit;
613 __u64 dqb_bsoftlimit;
615 __u64 dqb_ihardlimit;
616 __u64 dqb_isoftlimit;
634 <title>Description</title>
635 <para>The <literal>llapi_quotactl()</literal> command manipulates disk quotas on a Lustre file system mount. qc_cmd indicates a command to be applied to UID <literal>qc_id</literal> or GID <literal>qc_id</literal>.</para>
636 <informaltable frame="all">
638 <colspec colname="c1" colwidth="50*"/>
639 <colspec colname="c2" colwidth="50*"/>
643 <para><emphasis role="bold">Option</emphasis></para>
646 <para><emphasis role="bold">Description</emphasis></para>
653 <para> <literal>LUSTRE_Q_GETQUOTA</literal></para>
656 <para>Gets disk quota limits and current usage for user or group <emphasis>qc_id</emphasis>. <emphasis>qc_type</emphasis> is <literal>USRQUOTA</literal> or <literal>GRPQUOTA</literal>. <emphasis>uuid</emphasis> may be filled with <literal>OBD UUID</literal> string to query quota information from a specific node. <emphasis>dqb_valid</emphasis> may be set nonzero to query information only from MDS. If <emphasis>uuid</emphasis> is an empty string and <emphasis>dqb_valid</emphasis> is zero then cluster-wide limits and usage are returned. On return, <emphasis>obd_dqblk</emphasis> contains the requested information (block limits unit is kilobyte). Quotas must be turned on before using this command.</para>
661 <para> <literal>LUSTRE_Q_SETQUOTA</literal></para>
664 <para>Sets disk quota limits for user or group <emphasis>qc_id</emphasis>. <emphasis>qc_type</emphasis> is <literal>USRQUOTA</literal> or <literal>GRPQUOTA</literal>. <emphasis>dqb_valid</emphasis> must be set to <literal>QIF_ILIMITS</literal>, <literal>QIF_BLIMITS</literal> or <literal>QIF_LIMITS</literal> (both inode limits and block limits) dependent on updating limits. <emphasis>obd_dqblk</emphasis> must be filled with limits values (as set in <emphasis>dqb_valid</emphasis>, block limits unit is kilobyte). Quotas must be turned on before using this command.</para>
669 <para> <literal>LUSTRE_Q_GETINFO</literal></para>
672 <para>Gets information about quotas. <emphasis>qc_type</emphasis> is either
673 <literal>USRQUOTA</literal> or <literal>GRPQUOTA</literal>. On return,
674 <emphasis>dqi_igrace</emphasis> is inode grace time (in seconds),
675 <emphasis>dqi_bgrace</emphasis> is block grace time (in seconds),
676 <emphasis>dqi_flags</emphasis> is not used by the current release of the Lustre
682 <para> <literal>LUSTRE_Q_SETINFO</literal></para>
685 <para>Sets quota information (like grace times). <emphasis>qc_type</emphasis> is
686 either <literal>USRQUOTA</literal> or <literal>GRPQUOTA</literal>.
687 <emphasis>dqi_igrace</emphasis> is inode grace time (in seconds),
688 <emphasis>dqi_bgrace</emphasis> is block grace time (in seconds),
689 <emphasis>dqi_flags</emphasis> is not used by the current release of the Lustre
690 software and must be zeroed.</para>
698 <title>Return Values</title>
699 <para><literal>llapi_quotactl()</literal> returns:</para>
700 <para><literal>0</literal> On success</para>
701 <para><literal> -1 </literal> On failure and sets error number (<literal>errno</literal>) to indicate the error</para>
704 <title>Errors</title>
705 <para><literal>llapi_quotactl</literal> errors are described below.</para>
706 <informaltable frame="all">
708 <colspec colname="c1" colwidth="50*"/>
709 <colspec colname="c2" colwidth="50*"/>
713 <para><emphasis role="bold">Errors</emphasis></para>
716 <para><emphasis role="bold">Description</emphasis></para>
723 <para> <literal>EFAULT</literal></para>
726 <para><emphasis>qctl</emphasis> is invalid.</para>
731 <para> <literal>ENOSYS</literal></para>
734 <para>Kernel or Lustre modules have not been compiled with the <literal>QUOTA</literal> option.</para>
739 <para> <literal>ENOMEM</literal></para>
742 <para>Insufficient memory to complete operation.</para>
747 <para> <literal>ENOTTY</literal></para>
750 <para> <emphasis>qc_cmd</emphasis> is invalid.</para>
755 <para> <literal>ENOENT</literal></para>
758 <para> <emphasis>uuid</emphasis> does not correspond to OBD or <emphasis>mnt</emphasis> does not exist.</para>
763 <para> <literal>EPERM</literal></para>
766 <para>The call is privileged and the caller is not the super user.</para>
771 <para> <literal>ESRCH</literal></para>
774 <para>No disk quota is found for the indicated user. Quotas have not been turned on for this file system.</para>
782 <section xml:id="dbdoclet.50438215_15718">
784 <literal>llapi_path2fid</literal>
786 <para>Use <literal>llapi_path2fid</literal> to get the FID from the pathname.</para>
788 <title>Synopsis</title>
789 <screen>#include <lustre/lustreapi.h>
791 int llapi_path2fid(const char *path, unsigned long long *seq, unsigned long *oid, unsigned long *ver)</screen>
794 <title>Description</title>
795 <para>The <literal>llapi_path2fid</literal> function returns the FID (sequence : object ID : version) for the pathname.</para>
798 <title>Return Values</title>
799 <para><literal>llapi_path2fid</literal> returns:</para>
800 <para><literal>0</literal> On success</para>
801 <para>non-zero value On failure</para>
804 <section condition="l29">
806 <literal>llapi_ladvise</literal>
808 <para>Use <literal>llapi_ladvise</literal> to give IO advice/hints on a
809 Lustre file to the server.</para>
811 <title>Synopsis</title>
813 #include <lustre/lustreapi.h>
814 int llapi_ladvise(int fd, unsigned long long flags,
815 int num_advise, struct llapi_lu_ladvise *ladvise);
817 struct llapi_lu_ladvise {
818 __u16 lla_advice; /* advice type */
819 __u16 lla_value1; /* values for different advice types */
821 __u64 lla_start; /* first byte of extent for advice */
822 __u64 lla_end; /* last byte of extent for advice */
829 <title>Description</title>
830 <para>The <literal>llapi_ladvise</literal> function passes an array of
831 <emphasis>num_advise</emphasis> I/O hints (up to a maximum of
832 <emphasis>LAH_COUNT_MAX</emphasis> items) in ladvise for the file
833 descriptor <emphasis>fd</emphasis> from an application to one or more
834 Lustre servers. Optionally, <emphasis>flags</emphasis> can modify how
835 the advice will be processed via bitwise-or'd values:</para>
838 <para><literal>LF_ASYNC</literal>: Clients return to userspace
839 immediately after submitting ladvise RPCs, leaving server threads to
840 handle the advices asynchronously.</para>
843 <para><literal>LF_UNSET</literal>: Unset/clear a previous advice
844 (Currently only supports LU_ADVISE_LOCKNOEXPAND).</para>
847 <para>Each of the <emphasis>ladvise</emphasis> elements is an
848 <emphasis>llapi_lu_ladvise</emphasis> structure, which contains the
850 <informaltable frame="all">
852 <colspec colname="c1" colwidth="50*"/>
853 <colspec colname="c2" colwidth="50*"/>
857 <para><emphasis role="bold">Field</emphasis></para>
860 <para><emphasis role="bold">Description</emphasis></para>
867 <para> <literal>lla_ladvice</literal></para>
870 <para>Specifies the advice for the given file range, currently
872 <para><literal>LU_LADVISE_WILLREAD</literal>: Prefetch data
873 into server cache using optimum I/O size for the server.</para>
874 <para><literal>LU_LADVISE_DONTNEED</literal>: Clean cached data
875 for the specified file range(s) on the server.</para>
880 <para> <literal>lla_start</literal></para>
883 <para>The offset in bytes for the start of this advice.</para>
888 <para> <literal>lla_end</literal></para>
891 <para>The offset in bytes (non-inclusive) for the end of this
897 <para> <literal>lla_value1</literal></para>
898 <para> <literal>lla_value2</literal></para>
899 <para> <literal>lla_value3</literal></para>
900 <para> <literal>lla_value4</literal></para>
903 <para>Additional arguments for future advice types and
904 should be set to zero if not explicitly required for a given
905 advice type. Advice-specific names for these fields
911 <para> <literal>lla_lockahead_mode</literal></para>
914 <para>When using LU_ADVISE_LOCKAHEAD, the 'lla_value1' field
915 is used to communicate the requested lock mode, and can be
916 referred to as lla_lockahead_mode.</para>
921 <para> <literal>lla_peradvice_flags</literal></para>
924 <para>When using advices which support them, the 'lla_value2'
925 field is used to communicate per-advice flags and can be
926 referred to as 'lla_peradvice_flags'. Both LF_ASYNC and
927 LF_UNSET are supported as peradvice flags.</para>
932 <para> <literal>lla_lockahead_result</literal></para>
935 <para>When using LU_ADVISE_LOCKAHEAD, the 'lla_value3' field
936 is used to communicate the result of the request, and can be
937 referred to as lla_lockahead_result.</para>
944 <para><literal>llapi_ladvise()</literal> forwards the advice to Lustre
945 servers without guaranteeing how and when servers will react to the
946 advice. Actions may or may not be triggered when the advices are
947 received, depending on the type of the advice as well as the real-time
948 decision of the affected server-side components.
950 <para> A typical usage of <literal>llapi_ladvise()</literal> is to
951 enable applications and users (via <literal>lfs ladvise</literal>)
952 with external knowledge about application I/O patterns to intervene in
953 server-side I/O handling. For example, if a group of different clients
954 are doing small random reads of a file, prefetching pages into OSS
955 cache with big linear reads before the random IO is an overall net
956 benefit. Fetching that data into each client cache with
957 <emphasis>fadvise()</emphasis> may not be beneficial, due to much more
958 data being sent to the clients.
961 LU_LADVISE_LOCKAHEAD merits a special comment. While it is possible
962 and encouraged to use it directly in your application to avoid lock
963 contention (primarily for writing to a single file from multiple
964 clients), it will also be available in the MPI-I/O / MPICH library
965 from ANL for use with the i/o aggregation mode of that library. This
966 is intended (eventually) to be the primary way this feature is used.
969 At the time of writing, this support is proposed as a patch but is
970 not yet merged in to the public ANL code base. Users are encouraged
971 to check their MPICH documentation and/or check with their library
972 provider about support.
974 <para>While conceptually similar to the
975 <emphasis>posix_fadvise</emphasis> and Linux
976 <emphasis>fadvise</emphasis> system calls, the main difference of
977 <literal>llapi_ladvise()</literal> is that
978 <emphasis>fadvise() / posix_fadvise()</emphasis> are client side
979 mechanisms that do not pass advice to the filesystem, while
980 <literal>llapi_ladvise()</literal> sends advice or hints to one or
981 more Lustre servers on which the file is stored. In some cases it may
982 be desirable to use both interfaces.
986 <title>Return Values</title>
987 <para><literal>llapi_ladvise</literal> returns:</para>
988 <para><literal>0</literal> On success</para>
989 <para><literal>-1</literal> if an error occurred (in which case, errno
990 is set appropriately).</para>
993 <title>Errors</title>
995 <informaltable frame="all">
997 <colspec colname="c1" colwidth="50*"/>
998 <colspec colname="c2" colwidth="50*"/>
1002 <para><emphasis role="bold">Error</emphasis></para>
1005 <para><emphasis role="bold">Description</emphasis></para>
1012 <para> <literal>ENOMEM</literal></para>
1015 <para>Insufficient memory to complete operation.</para>
1020 <para> <literal>EINVAL</literal></para>
1023 <para>One or more invalid arguments are given.</para>
1028 <para> <literal>EFAULT</literal></para>
1031 <para>Memory region pointed by
1032 <literal>ladvise</literal> is not properly mapped.
1038 <para> <literal>ENOTSUPP</literal></para>
1041 <para>Advice type is not supported.</para>
1050 <section xml:id="dbdoclet.50438215_marker-1297700">
1051 <title>Example Using the <literal>llapi</literal> Library</title>
1052 <para>Use <literal>llapi_file_create</literal> to set Lustre software properties for a new file.
1053 For a synopsis and description of <literal>llapi_file_create</literal> and examples of how to
1054 use it, see <xref linkend="configurationfilesmoduleparameters"/>.</para>
1055 <para>You can set striping from inside programs like <literal>ioctl</literal>. To compile the sample program, you need to install the Lustre client source RPM.</para>
1056 <para><emphasis role="bold">A simple C program to demonstrate striping API - libtest.c</emphasis></para>
1058 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
1059 * vim:expandtab:shiftwidth=8:tabstop=8:
1061 * lustredemo - a simple example of lustreapi functions
1063 #include <stdio.h>
1064 #include <fcntl.h>
1065 #include <dirent.h>
1066 #include <errno.h>
1067 #include <stdlib.h>
1068 #include <lustre/lustreapi.h>
1069 #define MAX_OSTS 1024
1070 #define LOV_EA_SIZE(lum, num) (sizeof(*lum) + num * sizeof(*lum->lmm_objects))
1071 #define LOV_EA_MAX(lum) LOV_EA_SIZE(lum, MAX_OSTS)
1074 * This program provides crude examples of using the lustreapi API functions
1076 /* Change these definitions to suit */
1078 #define TESTDIR "/tmp" /* Results directory */
1079 #define TESTFILE "lustre_dummy" /* Name for the file we create/destroy */
1080 #define FILESIZE 262144 /* Size of the file in words */
1081 #define DUMWORD "DEADBEEF" /* Dummy word used to fill files */
1082 #define MY_STRIPE_WIDTH 2 /* Set this to the number of OST required */
1083 #define MY_LUSTRE_DIR "/mnt/lustre/ftest"
1085 int close_file(int fd)
1087 if (close(fd) < 0) {
1088 fprintf(stderr, "File close failed: %d (%s)\n", errno, strerror(errno));
1094 int write_file(int fd)
1096 char *stng = DUMWORD;
1099 for( cnt = 0; cnt < FILESIZE; cnt++) {
1100 write(fd, stng, sizeof(stng));
1104 /* Open a file, set a specific stripe count, size and starting OST
1105 * Adjust the parameters to suit */
1106 int open_stripe_file()
1108 char *tfile = TESTFILE;
1109 int stripe_size = 65536; /* System default is 4M */
1110 int stripe_offset = -1; /* Start at default */
1111 int stripe_count = MY_STRIPE_WIDTH; /*Single stripe for this demo*/
1112 int stripe_pattern = 0; /* only RAID 0 at this time */
1115 rc = llapi_file_create(tfile,
1116 stripe_size,stripe_offset,stripe_count,stripe_pattern);
1117 /* result code is inverted, we may return -EINVAL or an ioctl error.
1118 * We borrow an error message from sanity.c
1121 fprintf(stderr,"llapi_file_create failed: %d (%s) \n", rc, strerror(-rc));
1124 /* llapi_file_create closes the file descriptor, we must re-open */
1125 fd = open(tfile, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644);
1127 fprintf(stderr, "Can't open %s file: %d (%s)\n", tfile, errno, strerror(errno));
1133 /* output a list of uuids for this file */
1134 int get_my_uuids(int fd)
1136 struct obd_uuid uuids[1024], *uuidp; /* Output var */
1137 int obdcount = 1024;
1140 rc = llapi_lov_get_uuids(fd, uuids, &obdcount);
1142 fprintf(stderr, "get uuids failed: %d (%s)\n",errno, strerror(errno));
1144 printf("This file system has %d obds\n", obdcount);
1145 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) {
1146 printf("UUID %d is %s\n",i, uuidp->uuid);
1151 /* Print out some LOV attributes. List our objects */
1152 int get_file_info(char *path)
1155 struct lov_user_md *lump;
1159 lump = malloc(LOV_EA_MAX(lump));
1164 rc = llapi_file_get_stripe(path, lump);
1167 fprintf(stderr, "get_stripe failed: %d (%s)\n",errno, strerror(errno));
1171 printf("Lov magic %u\n", lump->lmm_magic);
1172 printf("Lov pattern %u\n", lump->lmm_pattern);
1173 printf("Lov object id %llu\n", lump->lmm_object_id);
1174 printf("Lov stripe size %u\n", lump->lmm_stripe_size);
1175 printf("Lov stripe count %hu\n", lump->lmm_stripe_count);
1176 printf("Lov stripe offset %u\n", lump->lmm_stripe_offset);
1177 for (i = 0; i < lump->lmm_stripe_count; i++) {
1178 printf("Object index %d Objid %llu\n", lump->lmm_objects[i].l_ost_idx, lump->lmm_objects[i].l_object_id);
1186 /* Ping all OSTs that belong to this filesystem */
1194 sprintf(osc_dir, "/proc/fs/lustre/osc");
1195 dir = opendir(osc_dir);
1197 printf("Can't open dir\n");
1200 while((d = readdir(dir)) != NULL) {
1201 if ( d->d_type == DT_DIR ) {
1202 if (! strncmp(d->d_name, "OSC", 3)) {
1203 printf("Pinging OSC %s ", d->d_name);
1204 rc = llapi_ping("osc", d->d_name);
1206 printf(" bad\n");
1208 printf(" good\n");
1224 sprintf(filename, "%s/%s",MY_LUSTRE_DIR, TESTFILE);
1226 printf("Open a file with striping\n");
1227 file = open_stripe_file();
1228 if ( file < 0 ) {
1229 printf("Exiting\n");
1232 printf("Getting uuid list\n");
1233 rc = get_my_uuids(file);
1234 printf("Write to the file\n");
1235 rc = write_file(file);
1236 rc = close_file(file);
1237 printf("Listing LOV data\n");
1238 rc = get_file_info(filename);
1239 printf("Ping our OSTs\n");
1242 /* the results should match lfs getstripe */
1243 printf("Confirming our results with lfs getstripe\n");
1244 sprintf(sys_cmd, "/usr/bin/lfs getstripe %s/%s", MY_LUSTRE_DIR, TESTFILE);
1247 printf("All done\n");
1251 <para><emphasis role="bold">Makefile for sample application:</emphasis></para>
1253 gcc -g -O2 -Wall -o lustredemo libtest.c -llustreapi
1255 rm -f core lustredemo *.o
1258 rm -f /mnt/lustre/ftest/lustredemo
1259 rm -f /mnt/lustre/ftest/lustre_dummy
1260 cp lustredemo /mnt/lustre/ftest/
1262 <section remap="h5">
1263 <title>See Also</title>
1267 <xref linkend="dbdoclet.50438215_30970"/>
1272 <xref linkend="dbdoclet.50438215_50149"/>
1277 <xref linkend="dbdoclet.50438215_86607"/>
1282 <xref linkend="dbdoclet.50438215_12433"/>
1289 <!--vim:expandtab:shiftwidth=2:tabstop=8:-->