Whamcloud - gitweb
LUDOC-431 lnet: doc for asymmetrical route checking
[doc/manual.git] / SettingLustreProperties.xml
1 <?xml version='1.0' encoding='UTF-8'?><chapter xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en-US" xml:id="settinglustreproperties">
2   <title xml:id="settinglustreproperties.title">Setting Lustre Properties in a C Program (<literal>llapi</literal>)</title>
3   <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>
4   <itemizedlist>
5     <listitem>
6       <para><xref linkend="dbdoclet.50438215_30970"/></para>
7     </listitem>
8     <listitem>
9       <para><xref linkend="dbdoclet.50438215_50149"/></para>
10     </listitem>
11     <listitem>
12       <para><xref linkend="dbdoclet.50438215_86607"/></para>
13     </listitem>
14     <listitem>
15       <para><xref linkend="dbdoclet.50438215_12433"/></para>
16     </listitem>
17     <listitem>
18       <para><xref linkend="dbdoclet.50438215_15718"/></para>
19     </listitem>
20   </itemizedlist>
21   <note>
22     <para>Lustre programming interface man pages are found in the <literal>lustre/doc</literal> folder.</para>
23   </note>
24   <section xml:id="dbdoclet.50438215_30970">
25     <title>
26       <literal>llapi_file_create</literal>
27     </title>
28     <para>Use <literal>llapi_file_create</literal> to set Lustre properties for a new file.</para>
29     <section remap="h5">
30       <title>Synopsis</title>
31       <screen>#include &lt;lustre/lustreapi.h&gt;
32
33 int llapi_file_create(char *name, long stripe_size, int stripe_offset, int stripe_count, int stripe_pattern);
34 </screen>
35     </section>
36     <section remap="h5">
37       <title>Description</title>
38       <para>The <literal>llapi_file_create()</literal> function sets a file descriptor&apos;s Lustre
39         file system striping information. The file descriptor is then accessed with
40           <literal>open()</literal>.</para>
41       <informaltable frame="all">
42         <tgroup cols="2">
43           <colspec colname="c1" colwidth="50*"/>
44           <colspec colname="c2" colwidth="50*"/>
45           <thead>
46             <row>
47               <entry>
48                 <para><emphasis role="bold">Option</emphasis></para>
49               </entry>
50               <entry>
51                 <para><emphasis role="bold">Description</emphasis></para>
52               </entry>
53             </row>
54           </thead>
55           <tbody>
56             <row>
57               <entry>
58                 <para> <literal>llapi_file_create()</literal></para>
59               </entry>
60               <entry>
61                 <para>If the file already exists, this parameter returns to &apos;<literal>EEXIST</literal>&apos;. If the stripe parameters are invalid, this parameter returns to &apos;<literal>EINVAL</literal>&apos;.</para>
62               </entry>
63             </row>
64             <row>
65               <entry>
66                 <para> <literal>stripe_size</literal></para>
67               </entry>
68               <entry>
69                 <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>
70               </entry>
71             </row>
72             <row>
73               <entry>
74                 <para> <literal>stripe_offset</literal></para>
75               </entry>
76               <entry>
77                 <para>Indicates the starting OST for this file.</para>
78               </entry>
79             </row>
80             <row>
81               <entry>
82                 <para> <literal>stripe_count</literal></para>
83               </entry>
84               <entry>
85                 <para>Indicates the number of OSTs that this file will be striped across.</para>
86               </entry>
87             </row>
88             <row>
89               <entry>
90                 <para> <literal>stripe_pattern</literal></para>
91               </entry>
92               <entry>
93                 <para>Indicates the RAID pattern.</para>
94               </entry>
95             </row>
96           </tbody>
97         </tgroup>
98       </informaltable>
99       <note>
100         <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>
101       </note>
102     </section>
103     <section remap="h5">
104       <title>Examples</title>
105       <para>System default size is 4 MB.</para>
106       <screen>char *tfile = TESTFILE;
107 int stripe_size = 65536</screen>
108       <para>To start at default, run:</para>
109       <screen>int stripe_offset = -1</screen>
110       <para>To start at the default, run:</para>
111       <screen>int stripe_count = 1</screen>
112       <para>To set a single stripe for this example, run:</para>
113       <screen>int stripe_pattern = 0</screen>
114       <para>Currently, only RAID 0 is supported.</para>
115       <screen>int stripe_pattern = 0; 
116 int rc, fd; 
117 rc = llapi_file_create(tfile, stripe_size,stripe_offset, stripe_count,stripe_pattern);</screen>
118       <para>Result code is inverted, you may return with &apos;<literal>EINVAL</literal>&apos; or an ioctl error.</para>
119       <screen>if (rc) {
120 fprintf(stderr,&quot;llapi_file_create failed: %d (%s) 0, rc, strerror(-rc));return -1; }</screen>
121       <para><literal>llapi_file_create</literal> closes the file descriptor. You must re-open the descriptor. To do this, run:</para>
122       <screen>fd = open(tfile, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644); if (fd &lt; 0) \ { 
123 fprintf(stderr, &quot;Can&apos;t open %s file: %s0, tfile,
124 str-
125 error(errno));
126 return -1;
127 }</screen>
128     </section>
129   </section>
130   <section xml:id="dbdoclet.50438215_50149">
131     <title>llapi_file_get_stripe</title>
132     <para>Use <literal>llapi_file_get_stripe</literal> to get striping information for a file or directory on a Lustre file system.</para>
133     <section remap="h5">
134       <title>Synopsis</title>
135       <screen>
136 #include &lt;lustre/lustreapi.h&gt;
137  
138 int llapi_file_get_stripe(const char *<emphasis>path</emphasis>, void *<emphasis>lum</emphasis>);</screen>
139     </section>
140     <section remap="h5">
141       <title>Description</title>
142       <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>
143       <screen>struct lov_user_md_v1 {
144 __u32 lmm_magic;
145 __u32 lmm_pattern;
146 __u64 lmm_object_id;
147 __u64 lmm_object_seq;
148 __u32 lmm_stripe_size;
149 __u16 lmm_stripe_count;
150 __u16 lmm_stripe_offset;
151 struct lov_user_ost_data_v1 lmm_objects[0];
152 } __attribute__((packed));
153 struct lov_user_md_v3 {
154 __u32 lmm_magic;
155 __u32 lmm_pattern;
156 __u64 lmm_object_id;
157 __u64 lmm_object_seq;
158 __u32 lmm_stripe_size;
159 __u16 lmm_stripe_count;
160 __u16 lmm_stripe_offset;
161 char lmm_pool_name[LOV_MAXPOOLNAME];
162 struct lov_user_ost_data_v1 lmm_objects[0];
163 } __attribute__((packed));</screen>
164       <informaltable frame="all">
165         <tgroup cols="2">
166           <colspec colname="c1" colwidth="50*"/>
167           <colspec colname="c2" colwidth="50*"/>
168           <thead>
169             <row>
170               <entry>
171                 <para><emphasis role="bold">Option</emphasis></para>
172               </entry>
173               <entry>
174                 <para><emphasis role="bold">Description</emphasis></para>
175               </entry>
176             </row>
177           </thead>
178           <tbody>
179             <row>
180               <entry>
181                 <para> <literal>lmm_magic</literal></para>
182               </entry>
183               <entry>
184                 <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>
185               </entry>
186             </row>
187             <row>
188               <entry>
189                 <para> <literal>lmm_pattern</literal></para>
190               </entry>
191               <entry>
192                 <para>Holds the striping pattern. Only <literal>LOV_PATTERN_RAID0</literal> is
193                   possible in this Lustre software release.</para>
194               </entry>
195             </row>
196             <row>
197               <entry>
198                 <para> <literal>lmm_object_id</literal></para>
199               </entry>
200               <entry>
201                 <para>Holds the MDS object ID.</para>
202               </entry>
203             </row>
204             <row>
205               <entry>
206                 <para> <literal>lmm_object_gr</literal></para>
207               </entry>
208               <entry>
209                 <para>Holds the MDS object group.</para>
210               </entry>
211             </row>
212             <row>
213               <entry>
214                 <para> <literal>lmm_stripe_size</literal></para>
215               </entry>
216               <entry>
217                 <para>Holds the stripe size in bytes.</para>
218               </entry>
219             </row>
220             <row>
221               <entry>
222                 <para> <literal>lmm_stripe_count</literal></para>
223               </entry>
224               <entry>
225                 <para>Holds the number of OSTs over which the file is striped.</para>
226               </entry>
227             </row>
228             <row>
229               <entry>
230                 <para> <literal>lmm_stripe_offset</literal></para>
231               </entry>
232               <entry>
233                 <para>Holds the OST index from which the file starts.</para>
234               </entry>
235             </row>
236             <row>
237               <entry>
238                 <para> <literal>lmm_pool_name</literal></para>
239               </entry>
240               <entry>
241                 <para>Holds the OST pool name to which the file belongs.</para>
242               </entry>
243             </row>
244             <row>
245               <entry>
246                 <para> <literal>lmm_objects</literal></para>
247               </entry>
248               <entry>
249                 <para>An array of <literal>lmm_stripe_count</literal> members containing per OST file information in</para>
250                 <para>the following format:</para>
251                 <screen>struct lov_user_ost_data_v1 {
252                 __u64 l_object_id;
253                 __u64 l_object_seq;
254                 __u32 l_ost_gen;
255                 __u32 l_ost_idx;
256                 } __attribute__((packed));</screen>
257               </entry>
258             </row>
259             <row>
260               <entry>
261                 <para> <literal>l_object_id</literal></para>
262               </entry>
263               <entry>
264                 <para>Holds the OST&apos;s object ID.</para>
265               </entry>
266             </row>
267             <row>
268               <entry>
269                 <para> <literal>l_object_seq</literal></para>
270               </entry>
271               <entry>
272                 <para>Holds the OST&apos;s object group.</para>
273               </entry>
274             </row>
275             <row>
276               <entry>
277                 <para> <literal>l_ost_gen</literal></para>
278               </entry>
279               <entry>
280                 <para>Holds the OST&apos;s index generation.</para>
281               </entry>
282             </row>
283             <row>
284               <entry>
285                 <para> <literal>l_ost_idx</literal></para>
286               </entry>
287               <entry>
288                 <para>Holds the OST&apos;s index in LOV.</para>
289               </entry>
290             </row>
291           </tbody>
292         </tgroup>
293       </informaltable>
294     </section>
295     <section remap="h5">
296       <title>Return Values</title>
297       <para><literal>llapi_file_get_stripe()</literal> returns:</para>
298       <para><literal>0</literal> On success</para>
299       <para><literal>!= 0</literal> On failure, <literal>errno</literal> is set appropriately</para>
300     </section>
301     <section remap="h5">
302       <title>Errors</title>
303       <informaltable frame="all">
304         <tgroup cols="2">
305           <colspec colname="c1" colwidth="50*"/>
306           <colspec colname="c2" colwidth="50*"/>
307           <thead>
308             <row>
309               <entry>
310                 <para><emphasis role="bold">Errors</emphasis></para>
311               </entry>
312               <entry>
313                 <para><emphasis role="bold">Description</emphasis></para>
314               </entry>
315             </row>
316           </thead>
317           <tbody>
318             <row>
319               <entry>
320                 <para> <literal>ENOMEM</literal></para>
321               </entry>
322               <entry>
323                 <para>Failed to allocate memory</para>
324               </entry>
325             </row>
326             <row>
327               <entry>
328                 <para> <literal>ENAMETOOLONG</literal></para>
329               </entry>
330               <entry>
331                 <para>Path was too long</para>
332               </entry>
333             </row>
334             <row>
335               <entry>
336                 <para> <literal>ENOENT</literal></para>
337               </entry>
338               <entry>
339                 <para>Path does not point to a file or directory</para>
340               </entry>
341             </row>
342             <row>
343               <entry>
344                 <para> <literal>ENOTTY</literal></para>
345               </entry>
346               <entry>
347                 <para>Path does not point to a Lustre file system</para>
348               </entry>
349             </row>
350             <row>
351               <entry>
352                 <para> <literal>EFAULT</literal></para>
353               </entry>
354               <entry>
355                 <para>Memory region pointed by lum is not properly mapped</para>
356               </entry>
357             </row>
358           </tbody>
359         </tgroup>
360       </informaltable>
361     </section>
362     <section remap="h5">
363       <title>Examples</title>
364       <programlisting>
365 #include &lt;stdio.h&gt;
366 #include &lt;stdlib.h&gt;
367 #include &lt;errno.h&gt;
368 #include &lt;lustre/lustreapi.h&gt;
369
370 static inline int maxint(int a, int b)
371 {
372         return a &gt; b ? a : b;
373 }
374 static void *alloc_lum()
375 {
376         int v1, v3, join;
377         v1 = sizeof(struct lov_user_md_v1) +
378                 LOV_MAX_STRIPE_COUNT * sizeof(struct lov_user_ost_data_v1);
379         v3 = sizeof(struct lov_user_md_v3) +
380                 LOV_MAX_STRIPE_COUNT * sizeof(struct lov_user_ost_data_v1);
381         return malloc(maxint(v1, v3));
382 }
383 int main(int argc, char** argv)
384 {
385         struct lov_user_md *lum_file = NULL;
386         int rc;
387         int lum_size;
388         if (argc != 2) {
389                 fprintf(stderr, &quot;Usage: %s &lt;filename&gt;\n&quot;, argv[0]);
390                 return 1;
391         }
392         lum_file = alloc_lum();
393         if (lum_file == NULL) {
394                 rc = ENOMEM;
395                 goto cleanup;
396         }
397         rc = llapi_file_get_stripe(argv[1], lum_file);
398         if (rc) {
399                 rc = errno;
400                 goto cleanup;
401         }
402         /* stripe_size stripe_count */
403         printf(&quot;%d %d\n&quot;,
404                         lum_file-&gt;lmm_stripe_size,
405                         lum_file-&gt;lmm_stripe_count);
406 cleanup:
407         if (lum_file != NULL)
408                 free(lum_file);
409         return rc;
410 }
411 </programlisting>
412     </section>
413   </section>
414   <section xml:id="dbdoclet.50438215_86607">
415     <title>
416       <literal>llapi_file_open</literal>
417     </title>
418     <para>The <literal>llapi_file_open</literal> command opens (or creates) a file or device on a
419       Lustre file system.</para>
420     <section remap="h5">
421       <title>Synopsis</title>
422       <screen>#include &lt;lustre/lustreapi.h&gt;
423 int llapi_file_open(const char *<emphasis>name</emphasis>, int <emphasis>flags</emphasis>, int <emphasis>mode</emphasis>, 
424    unsigned long long <emphasis>stripe_size</emphasis>, int <emphasis>stripe_offset</emphasis>, 
425    int <emphasis>stripe_count</emphasis>, int <emphasis>stripe_pattern</emphasis>);
426 int llapi_file_create(const char *<emphasis>name</emphasis>, unsigned long long <emphasis>stripe_size</emphasis>, 
427    int <emphasis>stripe_offset</emphasis>, int <emphasis>stripe_count</emphasis>, 
428    int <emphasis>stripe_pattern</emphasis>);
429 </screen>
430     </section>
431     <section remap="h5">
432       <title>Description</title>
433       <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>
434       <para><literal>llapi_file_open()</literal> opens a file with a given name on a Lustre file
435         system.</para>
436       <informaltable frame="all">
437         <tgroup cols="2">
438           <colspec colname="c1" colwidth="50*"/>
439           <colspec colname="c2" colwidth="50*"/>
440           <thead>
441             <row>
442               <entry>
443                 <para><emphasis role="bold">Option</emphasis></para>
444               </entry>
445               <entry>
446                 <para><emphasis role="bold">Description</emphasis></para>
447               </entry>
448             </row>
449           </thead>
450           <tbody>
451             <row>
452               <entry>
453                 <para> <literal>flags</literal></para>
454               </entry>
455               <entry>
456                 <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>
457               </entry>
458             </row>
459             <row>
460               <entry>
461                 <para> <literal>mode</literal></para>
462               </entry>
463               <entry>
464                 <para>Specifies the permission bits to be used for a new file when <literal>O_CREAT</literal> is used.</para>
465               </entry>
466             </row>
467             <row>
468               <entry>
469                 <para> <literal>stripe_size</literal></para>
470               </entry>
471               <entry>
472                 <para>Specifies stripe size (in bytes). Should be multiple of 64 KB, not exceeding 4 GB.</para>
473               </entry>
474             </row>
475             <row>
476               <entry>
477                 <para> <literal>stripe_offset</literal></para>
478               </entry>
479               <entry>
480                 <para>Specifies an OST index from which the file should start. The default value is -1.</para>
481               </entry>
482             </row>
483             <row>
484               <entry>
485                 <para> <literal>stripe_count</literal></para>
486               </entry>
487               <entry>
488                 <para>Specifies the number of OSTs to stripe the file across. The default value is -1.</para>
489               </entry>
490             </row>
491             <row>
492               <entry>
493                 <para> <literal>stripe_pattern</literal></para>
494               </entry>
495               <entry>
496                 <para>Specifies the striping pattern. In this release of the Lustre software, only
497                     <literal>LOV_PATTERN_RAID0</literal> is available. The default value is
498                   0.</para>
499               </entry>
500             </row>
501           </tbody>
502         </tgroup>
503       </informaltable>
504     </section>
505     <section remap="h5">
506       <title>Return Values</title>
507       <para><literal>llapi_file_open()</literal> and <literal>llapi_file_create()</literal> return:</para>
508       <para><literal>&gt;=0</literal> On success, for <literal>llapi_file_open</literal> the return value is a file descriptor</para>
509       <para><literal>&lt;0</literal> On failure, the absolute value is an error code</para>
510     </section>
511     <section remap="h5">
512       <title>Errors</title>
513       <informaltable frame="all">
514         <tgroup cols="2">
515           <colspec colname="c1" colwidth="50*"/>
516           <colspec colname="c2" colwidth="50*"/>
517           <thead>
518             <row>
519               <entry>
520                 <para><emphasis role="bold">Errors</emphasis></para>
521               </entry>
522               <entry>
523                 <para><emphasis role="bold">Description</emphasis></para>
524               </entry>
525             </row>
526           </thead>
527           <tbody>
528             <row>
529               <entry>
530                 <para> <literal>EINVAL</literal></para>
531               </entry>
532               <entry>
533                 <para><literal>stripe_size</literal> or <literal>stripe_offset</literal> or <literal>stripe_count</literal> or <literal>stripe_pattern</literal> is invalid.</para>
534               </entry>
535             </row>
536             <row>
537               <entry>
538                 <para> <literal>EEXIST</literal></para>
539               </entry>
540               <entry>
541                 <para>Striping information has already been set and cannot be altered; <literal>name</literal> already exists.</para>
542               </entry>
543             </row>
544             <row>
545               <entry>
546                 <para> <literal>EALREADY</literal></para>
547               </entry>
548               <entry>
549                 <para>Striping information has already been set and cannot be altered</para>
550               </entry>
551             </row>
552             <row>
553               <entry>
554                 <para> <literal>ENOTTY</literal></para>
555               </entry>
556               <entry>
557                 <para>
558                   <literal>name</literal> may not point to a Lustre file system.</para>
559               </entry>
560             </row>
561           </tbody>
562         </tgroup>
563       </informaltable>
564     </section>
565     <section remap="h5">
566       <title>Example</title>
567       <programlisting>
568 #include &lt;stdio.h&gt;
569 #include &lt;lustre/lustreapi.h&gt;
570
571 int main(int argc, char *argv[])
572 {
573         int rc;
574         if (argc != 2)
575                 return -1;
576         rc = llapi_file_create(argv[1], 1048576, 0, 2, LOV_PATTERN_RAID0);
577         if (rc &lt; 0) {
578                 fprintf(stderr, &quot;file creation has failed, %s\n&quot;,         strerror(-rc));
579                 return -1;
580         }
581         printf(&quot;%s with stripe size 1048576, striped across 2 OSTs,&quot;
582                         &quot; has been created!\n&quot;, argv[1]);
583         return 0;
584 }
585 </programlisting>
586     </section>
587   </section>
588   <section xml:id="dbdoclet.50438215_12433">
589     <title>
590       <literal>llapi_quotactl</literal>
591     </title>
592     <para>Use <literal>llapi_quotact</literal>l to manipulate disk quotas on a Lustre file system.</para>
593     <section remap="h5">
594       <title>Synopsis</title>
595       <screen>#include &lt;lustre/lustreapi.h&gt;
596 int llapi_quotactl(char&quot; &quot; *mnt,&quot; &quot; struct if_quotactl&quot; &quot; *qctl)
597  
598 struct if_quotactl {
599         __u32                   qc_cmd;
600         __u32                   qc_type;
601         __u32                   qc_id;
602         __u32                   qc_stat;
603         struct obd_dqinfo       qc_dqinfo;
604         struct obd_dqblk        qc_dqblk;
605         char                    obd_type[16];
606         struct obd_uuid         obd_uuid;
607 };
608 struct obd_dqblk {
609         __u64 dqb_bhardlimit;
610         __u64 dqb_bsoftlimit;
611         __u64 dqb_curspace;
612         __u64 dqb_ihardlimit;
613         __u64 dqb_isoftlimit;
614         __u64 dqb_curinodes;
615         __u64 dqb_btime;
616         __u64 dqb_itime;
617         __u32 dqb_valid;
618         __u32 padding;
619 };
620 struct obd_dqinfo {
621         __u64 dqi_bgrace;
622         __u64 dqi_igrace;
623         __u32 dqi_flags;
624         __u32 dqi_valid;
625 };
626 struct obd_uuid {
627         char uuid[40];
628 };</screen>
629     </section>
630     <section remap="h5">
631       <title>Description</title>
632       <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>
633       <informaltable frame="all">
634         <tgroup cols="2">
635           <colspec colname="c1" colwidth="50*"/>
636           <colspec colname="c2" colwidth="50*"/>
637           <thead>
638             <row>
639               <entry>
640                 <para><emphasis role="bold">Option</emphasis></para>
641               </entry>
642               <entry>
643                 <para><emphasis role="bold">Description</emphasis></para>
644               </entry>
645             </row>
646           </thead>
647           <tbody>
648             <row>
649               <entry>
650                 <para> <literal>LUSTRE_Q_QUOTAON</literal></para>
651               </entry>
652               <entry>
653                 <para>Turns on quotas for a Lustre file system. Deprecated as of 2.4.0.
654                     <emphasis>qc_type</emphasis> is <literal>USRQUOTA</literal>,
655                     <literal>GRPQUOTA</literal> or <literal>UGQUOTA</literal> (both user and group
656                   quota). The quota files must exist. They are normally created with the
657                     <literal>llapi_quotacheck</literal> call. This call is restricted to the super
658                   user privilege. As of 2.4.0, quota is now enabled on a per file system basis via
659                     <literal>lctl conf_param</literal> (see <xref linkend="enabling_disk_quotas"/>)
660                   on the MGS node and quotacheck isn't needed any more.</para>
661               </entry>
662             </row>
663             <row>
664               <entry>
665                 <para> <literal>LUSTRE_Q_QUOTAOFF</literal></para>
666               </entry>
667               <entry>
668                 <para>Turns off quotas for a Lustre file system. Deprecated as of 2.4.0. <emphasis>qc_type</emphasis> is <literal>USRQUOTA</literal>, <literal>GRPQUOTA</literal> or <literal>UGQUOTA</literal> (both user and group quota). This call is restricted to the super user privilege. As of 2.4.0, quota is disabled via <literal>lctl conf_param</literal> (see <xref linkend="enabling_disk_quotas"/>).</para>
669               </entry>
670             </row>
671             <row>
672               <entry>
673                 <para> <literal>LUSTRE_Q_GETQUOTA</literal></para>
674               </entry>
675               <entry>
676                 <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>
677               </entry>
678             </row>
679             <row>
680               <entry>
681                 <para> <literal>LUSTRE_Q_SETQUOTA</literal></para>
682               </entry>
683               <entry>
684                 <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>
685               </entry>
686             </row>
687             <row>
688               <entry>
689                 <para> <literal>LUSTRE_Q_GETINFO</literal></para>
690               </entry>
691               <entry>
692                 <para>Gets information about quotas. <emphasis>qc_type</emphasis> is either
693                     <literal>USRQUOTA</literal> or <literal>GRPQUOTA</literal>. On return,
694                     <emphasis>dqi_igrace</emphasis> is inode grace time (in seconds),
695                     <emphasis>dqi_bgrace</emphasis> is block grace time (in seconds),
696                     <emphasis>dqi_flags</emphasis> is not used by the current release of the Lustre
697                   software.</para>
698               </entry>
699             </row>
700             <row>
701               <entry>
702                 <para> <literal>LUSTRE_Q_SETINFO</literal></para>
703               </entry>
704               <entry>
705                 <para>Sets quota information (like grace times). <emphasis>qc_type</emphasis> is
706                   either <literal>USRQUOTA</literal> or <literal>GRPQUOTA</literal>.
707                     <emphasis>dqi_igrace</emphasis> is inode grace time (in seconds),
708                     <emphasis>dqi_bgrace</emphasis> is block grace time (in seconds),
709                     <emphasis>dqi_flags</emphasis> is not used by the current release of the Lustre
710                   software and must be zeroed.</para>
711               </entry>
712             </row>
713           </tbody>
714         </tgroup>
715       </informaltable>
716     </section>
717     <section remap="h5">
718       <title>Return Values</title>
719       <para><literal>llapi_quotactl()</literal> returns:</para>
720       <para><literal>0</literal> On success</para>
721       <para><literal> -1 </literal> On failure and sets error number (<literal>errno</literal>) to indicate the error</para>
722     </section>
723     <section remap="h5">
724       <title>Errors</title>
725       <para><literal>llapi_quotactl</literal> errors are described below.</para>
726       <informaltable frame="all">
727         <tgroup cols="2">
728           <colspec colname="c1" colwidth="50*"/>
729           <colspec colname="c2" colwidth="50*"/>
730           <thead>
731             <row>
732               <entry>
733                 <para><emphasis role="bold">Errors</emphasis></para>
734               </entry>
735               <entry>
736                 <para><emphasis role="bold">Description</emphasis></para>
737               </entry>
738             </row>
739           </thead>
740           <tbody>
741             <row>
742               <entry>
743                 <para> <literal>EFAULT</literal></para>
744               </entry>
745               <entry>
746                 <para><emphasis>qctl</emphasis> is invalid.</para>
747               </entry>
748             </row>
749             <row>
750               <entry>
751                 <para> <literal>ENOSYS</literal></para>
752               </entry>
753               <entry>
754                 <para>Kernel or Lustre modules have not been compiled with the <literal>QUOTA</literal> option.</para>
755               </entry>
756             </row>
757             <row>
758               <entry>
759                 <para> <literal>ENOMEM</literal></para>
760               </entry>
761               <entry>
762                 <para>Insufficient memory to complete operation.</para>
763               </entry>
764             </row>
765             <row>
766               <entry>
767                 <para> <literal>ENOTTY</literal></para>
768               </entry>
769               <entry>
770                 <para> <emphasis>qc_cmd</emphasis> is invalid.</para>
771               </entry>
772             </row>
773             <row>
774               <entry>
775                 <para> <literal>EBUSY</literal></para>
776               </entry>
777               <entry>
778                 <para>Cannot process during quotacheck.</para>
779               </entry>
780             </row>
781             <row>
782               <entry>
783                 <para> <literal>ENOENT</literal></para>
784               </entry>
785               <entry>
786                 <para> <emphasis>uuid</emphasis> does not correspond to OBD or <emphasis>mnt</emphasis> does not exist.</para>
787               </entry>
788             </row>
789             <row>
790               <entry>
791                 <para> <literal>EPERM</literal></para>
792               </entry>
793               <entry>
794                 <para>The call is privileged and the caller is not the super user.</para>
795               </entry>
796             </row>
797             <row>
798               <entry>
799                 <para> <literal>ESRCH</literal></para>
800               </entry>
801               <entry>
802                 <para>No disk quota is found for the indicated user. Quotas have not been turned on for this file system.</para>
803               </entry>
804             </row>
805           </tbody>
806         </tgroup>
807       </informaltable>
808     </section>
809   </section>
810   <section xml:id="dbdoclet.50438215_15718">
811     <title>
812       <literal>llapi_path2fid</literal>
813     </title>
814     <para>Use <literal>llapi_path2fid</literal> to get the FID from the pathname.</para>
815     <section remap="h5">
816       <title>Synopsis</title>
817       <screen>#include &lt;lustre/lustreapi.h&gt;
818  
819 int llapi_path2fid(const char *path, unsigned long long *seq, unsigned long *oid, unsigned long *ver)</screen>
820     </section>
821     <section remap="h5">
822       <title>Description</title>
823       <para>The <literal>llapi_path2fid</literal> function returns the FID (sequence : object ID : version) for the pathname.</para>
824     </section>
825     <section remap="h5">
826       <title>Return Values</title>
827       <para><literal>llapi_path2fid</literal> returns:</para>
828       <para><literal>0</literal> On success</para>
829       <para>non-zero value On failure</para>
830     </section>
831   </section>
832   <section condition="l29">
833       <title>
834           <literal>llapi_ladvise</literal>
835       </title>
836       <para>Use <literal>llapi_ladvise</literal> to give IO advice/hints on a
837       Lustre file to the server.</para>
838       <section remap="h5">
839           <title>Synopsis</title>
840           <screen>
841 #include &lt;lustre/lustreapi.h&gt;
842 int llapi_ladvise(int fd, unsigned long long flags,
843                   int num_advise, struct llapi_lu_ladvise *ladvise);
844                                 
845 struct llapi_lu_ladvise {
846   __u16 lla_advice;       /* advice type */
847   __u16 lla_value1;       /* values for different advice types */
848   __u32 lla_value2;
849   __u64 lla_start;        /* first byte of extent for advice */
850   __u64 lla_end;          /* last byte of extent for advice */
851   __u32 lla_value3;
852   __u32 lla_value4;
853 };
854           </screen>
855       </section>
856       <section remap="h5">
857           <title>Description</title>
858           <para>The <literal>llapi_ladvise</literal> function passes an array of
859           <emphasis>num_advise</emphasis> I/O hints (up to a maximum of
860           <emphasis>LAH_COUNT_MAX</emphasis> items) in ladvise for the file
861           descriptor <emphasis>fd</emphasis> from an application to one or more
862           Lustre servers.  Optionally, <emphasis>flags</emphasis> can modify how
863           the advice will be processed via bitwise-or'd values:</para>
864           <itemizedlist>
865           <listitem>
866           <para><literal>LF_ASYNC</literal>: Clients return to userspace
867           immediately after submitting ladvise RPCs, leaving server threads to
868           handle the advices asynchronously.</para>
869           </listitem>
870           <listitem>
871           <para><literal>LF_UNSET</literal>: Unset/clear a previous advice
872           (Currently only supports LU_ADVISE_LOCKNOEXPAND).</para>
873           </listitem>
874           </itemizedlist>
875           <para>Each of the <emphasis>ladvise</emphasis> elements is an
876           <emphasis>llapi_lu_ladvise</emphasis> structure, which contains the
877           following fields:
878           <informaltable frame="all">
879             <tgroup cols="2">
880               <colspec colname="c1" colwidth="50*"/>
881               <colspec colname="c2" colwidth="50*"/>
882               <thead>
883                 <row>
884                   <entry>
885                     <para><emphasis role="bold">Field</emphasis></para>
886                   </entry>
887                   <entry>
888                     <para><emphasis role="bold">Description</emphasis></para>
889                   </entry>
890                 </row>
891               </thead>
892               <tbody>
893               <row>
894               <entry>
895                 <para> <literal>lla_ladvice</literal></para>
896               </entry>
897               <entry>
898                 <para>Specifies the advice for the given file range, currently
899                 one of:</para>
900                 <para><literal>LU_LADVISE_WILLREAD</literal>:  Prefetch data
901                 into server cache using optimum I/O size for the server.</para>
902                 <para><literal>LU_LADVISE_DONTNEED</literal>:  Clean cached data
903                 for the specified file range(s) on the server.</para>
904               </entry>
905               </row>
906               <row>
907                 <entry>
908                   <para> <literal>lla_start</literal></para>
909                 </entry>
910                 <entry>
911                   <para>The offset in bytes for the start of this advice.</para>
912                 </entry>
913               </row>
914               <row>
915                 <entry>
916                   <para> <literal>lla_end</literal></para>
917                 </entry>
918                 <entry>
919                   <para>The offset in bytes (non-inclusive) for the end of this
920                   advice.</para>
921                 </entry>
922               </row>
923               <row>
924                 <entry>
925                   <para> <literal>lla_value1</literal></para>
926                   <para> <literal>lla_value2</literal></para>
927                   <para> <literal>lla_value3</literal></para>
928                   <para> <literal>lla_value4</literal></para>
929                 </entry>
930                 <entry>
931                     <para>Additional arguments for future advice types and
932                     should be set to zero if not explicitly required for a given
933                     advice type.  Advice-specific names for these fields
934                     follow.</para>
935                 </entry>
936               </row>
937               <row>
938                 <entry>
939                   <para> <literal>lla_lockahead_mode</literal></para>
940                 </entry>
941                 <entry>
942                   <para>When using LU_ADVISE_LOCKAHEAD, the 'lla_value1' field
943                   is used to communicate the requested lock mode, and can be
944                   referred to as lla_lockahead_mode.</para>
945                 </entry>
946               </row>
947               <row>
948                 <entry>
949                   <para> <literal>lla_peradvice_flags</literal></para>
950                 </entry>
951                 <entry>
952                   <para>When using advices which support them, the 'lla_value2'
953                   field is used to communicate per-advice flags and can be
954                   referred to as 'lla_peradvice_flags'. Both LF_ASYNC and
955                   LF_UNSET are supported as peradvice flags.</para>
956                 </entry>
957               </row>
958               <row>
959                 <entry>
960                   <para> <literal>lla_lockahead_result</literal></para>
961                 </entry>
962                 <entry>
963                   <para>When using LU_ADVISE_LOCKAHEAD, the 'lla_value3' field
964                   is used to communicate the result of the request, and can be
965                   referred to as lla_lockahead_result.</para>
966                 </entry>
967               </row>
968               </tbody>
969               </tgroup>
970           </informaltable>
971           </para>
972           <para><literal>llapi_ladvise()</literal> forwards the advice to Lustre
973           servers without guaranteeing how and when servers will react to the
974           advice. Actions may or may not be triggered when the advices are
975           received, depending on the type of the advice as well as the real-time
976           decision of the affected server-side components.
977           </para>
978           <para> A typical usage of <literal>llapi_ladvise()</literal> is to
979           enable applications and users (via <literal>lfs ladvise</literal>)
980           with external knowledge about application I/O patterns to intervene in
981           server-side I/O handling. For example, if a group of different clients
982           are doing small random reads of a file, prefetching pages into OSS
983           cache with big linear reads before the random IO is an overall net
984           benefit.  Fetching that data into each client cache with
985           <emphasis>fadvise()</emphasis> may not be beneficial, due to much more
986           data being sent to the clients.
987           </para>
988           <para>
989           LU_LADVISE_LOCKAHEAD merits a special comment.  While it is possible
990           and encouraged to use it directly in your application to avoid lock
991           contention (primarily for writing to a single file from multiple
992           clients), it will also be available in the MPI-I/O / MPICH library
993           from ANL for use with the i/o aggregation mode of that library.  This
994           is intended (eventually) to be the primary way this feature is used.
995           </para>
996           <para>
997           At the time of writing, this support is proposed as a patch but is
998           not yet merged in to the public ANL code base.  Users are encouraged
999           to check their MPICH documentation and/or check with their library
1000           provider about support.
1001           </para>
1002           <para>While conceptually similar to the
1003           <emphasis>posix_fadvise</emphasis> and Linux
1004           <emphasis>fadvise</emphasis> system calls, the main difference of
1005           <literal>llapi_ladvise()</literal> is that
1006           <emphasis>fadvise() / posix_fadvise()</emphasis> are client side
1007           mechanisms that do not pass advice to the filesystem, while
1008           <literal>llapi_ladvise()</literal> sends advice or hints to one or
1009           more Lustre servers on which the file is stored.  In some cases it may
1010           be desirable to use both interfaces.
1011           </para>
1012       </section>
1013       <section remap="h5">
1014           <title>Return Values</title>
1015           <para><literal>llapi_ladvise</literal> returns:</para>
1016           <para><literal>0</literal> On success</para>
1017           <para><literal>-1</literal> if an error occurred (in which case, errno
1018           is set appropriately).</para>
1019       </section>
1020       <section remap="h5">
1021           <title>Errors</title>
1022         <para>
1023           <informaltable frame="all">
1024             <tgroup cols="2">
1025               <colspec colname="c1" colwidth="50*"/>
1026               <colspec colname="c2" colwidth="50*"/>
1027               <thead>
1028                 <row>
1029                   <entry>
1030                     <para><emphasis role="bold">Error</emphasis></para>
1031                   </entry>
1032                   <entry>
1033                     <para><emphasis role="bold">Description</emphasis></para>
1034                   </entry>
1035                 </row>
1036               </thead>
1037               <tbody>
1038                 <row>
1039                   <entry>
1040                     <para> <literal>ENOMEM</literal></para>
1041                   </entry>
1042                   <entry>
1043                     <para>Insufficient memory to complete operation.</para>
1044                   </entry>
1045                 </row>
1046                 <row>
1047                   <entry>
1048                     <para> <literal>EINVAL</literal></para>
1049                   </entry>
1050                   <entry>
1051                     <para>One or more invalid arguments are given.</para>
1052                   </entry>
1053                 </row>
1054                 <row>
1055                   <entry>
1056                     <para> <literal>EFAULT</literal></para>
1057                   </entry>
1058                   <entry>
1059                     <para>Memory region pointed by
1060                     <literal>ladvise</literal> is not properly mapped.
1061                     </para>
1062                   </entry>
1063                 </row>
1064                 <row>
1065                   <entry>
1066                     <para> <literal>ENOTSUPP</literal></para>
1067                   </entry>
1068                   <entry>
1069                     <para>Advice type is not supported.</para>
1070                   </entry>
1071                 </row>
1072               </tbody>
1073             </tgroup>
1074           </informaltable>
1075           </para>
1076       </section>
1077   </section>
1078   <section xml:id="dbdoclet.50438215_marker-1297700">
1079     <title>Example Using the <literal>llapi</literal> Library</title>
1080     <para>Use <literal>llapi_file_create</literal> to set Lustre software properties for a new file.
1081       For a synopsis and description of <literal>llapi_file_create</literal> and examples of how to
1082       use it, see <xref linkend="configurationfilesmoduleparameters"/>.</para>
1083     <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>
1084     <para><emphasis role="bold">A simple C program to demonstrate striping API - libtest.c</emphasis></para>
1085     <programlisting>
1086 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
1087  * vim:expandtab:shiftwidth=8:tabstop=8:
1088  *
1089  * lustredemo - a simple example of lustreapi functions
1090  */
1091 #include &lt;stdio.h&gt;
1092 #include &lt;fcntl.h&gt;
1093 #include &lt;dirent.h&gt;
1094 #include &lt;errno.h&gt;
1095 #include &lt;stdlib.h&gt;
1096 #include &lt;lustre/lustreapi.h&gt;
1097 #define MAX_OSTS 1024
1098 #define LOV_EA_SIZE(lum, num) (sizeof(*lum) + num * sizeof(*lum-&gt;lmm_objects))
1099 #define LOV_EA_MAX(lum) LOV_EA_SIZE(lum, MAX_OSTS)
1100
1101 /*
1102  * This program provides crude examples of using the lustreapi API functions
1103  */
1104 /* Change these definitions to suit */
1105
1106 #define TESTDIR &quot;/tmp&quot;           /* Results directory */
1107 #define TESTFILE &quot;lustre_dummy&quot;  /* Name for the file we create/destroy */
1108 #define FILESIZE 262144                    /* Size of the file in words */
1109 #define DUMWORD &quot;DEADBEEF&quot;       /* Dummy word used to fill files */
1110 #define MY_STRIPE_WIDTH 2                  /* Set this to the number of OST required */
1111 #define MY_LUSTRE_DIR &quot;/mnt/lustre/ftest&quot;
1112
1113 int close_file(int fd)
1114 {
1115         if (close(fd) &lt; 0) {
1116                 fprintf(stderr, &quot;File close failed: %d (%s)\n&quot;, errno, strerror(errno));
1117                 return -1;
1118         }
1119         return 0;
1120 }
1121
1122 int write_file(int fd)
1123 {
1124         char *stng =  DUMWORD;
1125         int cnt = 0;
1126
1127         for( cnt = 0; cnt &lt; FILESIZE; cnt++) {
1128                 write(fd, stng, sizeof(stng));
1129         }
1130         return 0;
1131 }
1132 /* Open a file, set a specific stripe count, size and starting OST
1133  *    Adjust the parameters to suit */
1134 int open_stripe_file()
1135 {
1136         char *tfile = TESTFILE;
1137         int stripe_size = 65536;    /* System default is 4M */
1138         int stripe_offset = -1;     /* Start at default */
1139         int stripe_count = MY_STRIPE_WIDTH;  /*Single stripe for this demo*/
1140         int stripe_pattern = 0;     /* only RAID 0 at this time */
1141         int rc, fd;
1142
1143         rc = llapi_file_create(tfile,
1144                         stripe_size,stripe_offset,stripe_count,stripe_pattern);
1145         /* result code is inverted, we may return -EINVAL or an ioctl error.
1146          * We borrow an error message from sanity.c
1147          */
1148         if (rc) {
1149                 fprintf(stderr,&quot;llapi_file_create failed: %d (%s) \n&quot;, rc, strerror(-rc));
1150                 return -1;
1151         }
1152         /* llapi_file_create closes the file descriptor, we must re-open */
1153         fd = open(tfile, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644);
1154         if (fd &lt; 0) {
1155                 fprintf(stderr, &quot;Can't open %s file: %d (%s)\n&quot;, tfile, errno, strerror(errno));
1156                 return -1;
1157         }
1158         return fd;
1159 }
1160
1161 /* output a list of uuids for this file */
1162 int get_my_uuids(int fd)
1163 {
1164         struct obd_uuid uuids[1024], *uuidp;        /* Output var */
1165         int obdcount = 1024;
1166         int rc,i;
1167
1168         rc = llapi_lov_get_uuids(fd, uuids, &amp;obdcount);
1169         if (rc != 0) {
1170                 fprintf(stderr, &quot;get uuids failed: %d (%s)\n&quot;,errno, strerror(errno));
1171         }
1172         printf(&quot;This file system has %d obds\n&quot;, obdcount);
1173         for (i = 0, uuidp = uuids; i &lt; obdcount; i++, uuidp++) {
1174                 printf(&quot;UUID %d is %s\n&quot;,i, uuidp-&gt;uuid);
1175         }
1176         return 0;
1177 }
1178
1179 /* Print out some LOV attributes. List our objects */
1180 int get_file_info(char *path)
1181 {
1182
1183         struct lov_user_md *lump;
1184         int rc;
1185         int i;
1186
1187         lump = malloc(LOV_EA_MAX(lump));
1188         if (lump == NULL) {
1189                 return -1;
1190         }
1191
1192         rc = llapi_file_get_stripe(path, lump);
1193
1194         if (rc != 0) {
1195                 fprintf(stderr, &quot;get_stripe failed: %d (%s)\n&quot;,errno, strerror(errno));
1196                 return -1;
1197         }
1198
1199         printf(&quot;Lov magic %u\n&quot;, lump-&gt;lmm_magic);
1200         printf(&quot;Lov pattern %u\n&quot;, lump-&gt;lmm_pattern);
1201         printf(&quot;Lov object id %llu\n&quot;, lump-&gt;lmm_object_id);
1202         printf(&quot;Lov stripe size %u\n&quot;, lump-&gt;lmm_stripe_size);
1203         printf(&quot;Lov stripe count %hu\n&quot;, lump-&gt;lmm_stripe_count);
1204         printf(&quot;Lov stripe offset %u\n&quot;, lump-&gt;lmm_stripe_offset);
1205         for (i = 0; i &lt; lump-&gt;lmm_stripe_count; i++) {
1206                 printf(&quot;Object index %d Objid %llu\n&quot;, lump-&gt;lmm_objects[i].l_ost_idx, lump-&gt;lmm_objects[i].l_object_id);
1207         }
1208
1209         free(lump);
1210         return rc;
1211
1212 }
1213
1214 /* Ping all OSTs that belong to this filesystem */
1215 int ping_osts()
1216 {
1217         DIR *dir;
1218         struct dirent *d;
1219         char osc_dir[100];
1220         int rc;
1221
1222         sprintf(osc_dir, &quot;/proc/fs/lustre/osc&quot;);
1223         dir = opendir(osc_dir);
1224         if (dir == NULL) {
1225                 printf(&quot;Can't open dir\n&quot;);
1226                 return -1;
1227         }
1228         while((d = readdir(dir)) != NULL) {
1229                 if ( d-&gt;d_type == DT_DIR ) {
1230                         if (! strncmp(d-&gt;d_name, &quot;OSC&quot;, 3)) {
1231                                 printf(&quot;Pinging OSC %s &quot;, d-&gt;d_name);
1232                                 rc = llapi_ping(&quot;osc&quot;, d-&gt;d_name);
1233                                 if (rc) {
1234                                         printf(&quot;  bad\n&quot;);
1235                                 } else {
1236                                         printf(&quot;  good\n&quot;);
1237                                 }
1238                         }
1239                 }
1240         }
1241         return 0;
1242
1243 }
1244
1245 int main()
1246 {
1247         int file;
1248         int rc;
1249         char filename[100];
1250         char sys_cmd[100];
1251
1252         sprintf(filename, &quot;%s/%s&quot;,MY_LUSTRE_DIR, TESTFILE);
1253
1254         printf(&quot;Open a file with striping\n&quot;);
1255         file = open_stripe_file();
1256         if ( file &lt; 0 ) {
1257                 printf(&quot;Exiting\n&quot;);
1258                 exit(1);
1259         }
1260         printf(&quot;Getting uuid list\n&quot;);
1261         rc = get_my_uuids(file);
1262         printf(&quot;Write to the file\n&quot;);
1263         rc = write_file(file);
1264         rc = close_file(file);
1265         printf(&quot;Listing LOV data\n&quot;);
1266         rc = get_file_info(filename);
1267         printf(&quot;Ping our OSTs\n&quot;);
1268         rc = ping_osts();
1269
1270         /* the results should match lfs getstripe */
1271         printf(&quot;Confirming our results with lfs getstripe\n&quot;);
1272         sprintf(sys_cmd, &quot;/usr/bin/lfs getstripe %s/%s&quot;, MY_LUSTRE_DIR, TESTFILE);
1273         system(sys_cmd);
1274
1275         printf(&quot;All done\n&quot;);
1276         exit(rc);
1277 }
1278 </programlisting>
1279     <para><emphasis role="bold">Makefile for sample application:</emphasis></para>
1280     <screen> 
1281 gcc -g -O2 -Wall -o lustredemo libtest.c -llustreapi
1282 clean:
1283 rm -f core lustredemo *.o
1284 run: 
1285 make
1286 rm -f /mnt/lustre/ftest/lustredemo
1287 rm -f /mnt/lustre/ftest/lustre_dummy
1288 cp lustredemo /mnt/lustre/ftest/
1289 </screen>
1290     <section remap="h5">
1291       <title>See Also</title>
1292       <itemizedlist>
1293         <listitem>
1294           <para>
1295             <xref linkend="dbdoclet.50438215_30970"/>
1296     </para>
1297         </listitem>
1298         <listitem>
1299           <para>
1300             <xref linkend="dbdoclet.50438215_50149"/>
1301     </para>
1302         </listitem>
1303         <listitem>
1304           <para>
1305             <xref linkend="dbdoclet.50438215_86607"/>
1306     </para>
1307         </listitem>
1308         <listitem>
1309           <para>
1310             <xref linkend="dbdoclet.50438215_12433"/>
1311     </para>
1312         </listitem>
1313       </itemizedlist>
1314     </section>
1315   </section>
1316 </chapter>