Whamcloud - gitweb
LUDOC-28 llapi: clean up sample code
[doc/manual.git] / SettingLustreProperties.xml
1 <?xml version='1.0' encoding='UTF-8'?>
2 <!-- This document was created with Syntext Serna Free. --><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">
3   <title xml:id="settinglustreproperties.title">Setting Lustre Properties in a C Program (<literal>llapi</literal>)</title>
4   <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>
5   <itemizedlist>
6     <listitem>
7       <para><xref linkend="dbdoclet.50438215_30970"/></para>
8     </listitem>
9     <listitem>
10       <para><xref linkend="dbdoclet.50438215_50149"/></para>
11     </listitem>
12     <listitem>
13       <para><xref linkend="dbdoclet.50438215_86607"/></para>
14     </listitem>
15     <listitem>
16       <para><xref linkend="dbdoclet.50438215_12433"/></para>
17     </listitem>
18     <listitem>
19       <para><xref linkend="dbdoclet.50438215_15718"/></para>
20     </listitem>
21   </itemizedlist>
22   <note>
23     <para>Lustre programming interface man pages are found in the <literal>lustre/doc</literal> folder.</para>
24   </note>
25   <section xml:id="dbdoclet.50438215_30970">
26     <title>
27       <literal>llapi_file_create</literal>
28     </title>
29     <para>Use <literal>llapi_file_create</literal> to set Lustre properties for a new file.</para>
30     <section remap="h5">
31       <title>Synopsis</title>
32       <screen>#include &lt;lustre/lustreapi.h&gt;
33
34 int llapi_file_create(char *name, long stripe_size, int stripe_offset, int stripe_count, int stripe_pattern);
35 </screen>
36     </section>
37     <section remap="h5">
38       <title>Description</title>
39       <para>The <literal>llapi_file_create()</literal> function sets a file descriptor&apos;s Lustre striping information. The file descriptor is then accessed with <literal>open()</literal>.</para>
40       <informaltable frame="all">
41         <tgroup cols="2">
42           <colspec colname="c1" colwidth="50*"/>
43           <colspec colname="c2" colwidth="50*"/>
44           <thead>
45             <row>
46               <entry>
47                 <para><emphasis role="bold">Option</emphasis></para>
48               </entry>
49               <entry>
50                 <para><emphasis role="bold">Description</emphasis></para>
51               </entry>
52             </row>
53           </thead>
54           <tbody>
55             <row>
56               <entry>
57                 <para> <literal>llapi_file_create()</literal></para>
58               </entry>
59               <entry>
60                 <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>
61               </entry>
62             </row>
63             <row>
64               <entry>
65                 <para> <literal>stripe_size</literal></para>
66               </entry>
67               <entry>
68                 <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>
69               </entry>
70             </row>
71             <row>
72               <entry>
73                 <para> <literal>stripe_offset</literal></para>
74               </entry>
75               <entry>
76                 <para>Indicates the starting OST for this file.</para>
77               </entry>
78             </row>
79             <row>
80               <entry>
81                 <para> <literal>stripe_count</literal></para>
82               </entry>
83               <entry>
84                 <para>Indicates the number of OSTs that this file will be striped across.</para>
85               </entry>
86             </row>
87             <row>
88               <entry>
89                 <para> <literal>stripe_pattern</literal></para>
90               </entry>
91               <entry>
92                 <para>Indicates the RAID pattern.</para>
93               </entry>
94             </row>
95           </tbody>
96         </tgroup>
97       </informaltable>
98       <note>
99         <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>
100       </note>
101     </section>
102     <section remap="h5">
103       <title>Examples</title>
104       <para>System default size is 4 MB.</para>
105       <screen>char *tfile = TESTFILE;
106 int stripe_size = 65536</screen>
107       <para>To start at default, run:</para>
108       <screen>int stripe_offset = -1</screen>
109       <para>To start at the default, run:</para>
110       <screen>int stripe_count = 1</screen>
111       <para>To set a single stripe for this example, run:</para>
112       <screen>int stripe_pattern = 0</screen>
113       <para>Currently, only RAID 0 is supported.</para>
114       <screen>int stripe_pattern = 0; 
115 int rc, fd; 
116 rc = llapi_file_create(tfile, stripe_size,stripe_offset, stripe_count,stripe_pattern);</screen>
117       <para>Result code is inverted, you may return with &apos;<literal>EINVAL</literal>&apos; or an ioctl error.</para>
118       <screen>if (rc) {
119 fprintf(stderr,&quot;llapi_file_create failed: %d (%s) 0, rc, strerror(-rc));return -1; }</screen>
120       <para><literal>llapi_file_create</literal> closes the file descriptor. You must re-open the descriptor. To do this, run:</para>
121       <screen>fd = open(tfile, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644); if (fd &lt; 0) \ { 
122 fprintf(stderr, &quot;Can&apos;t open %s file: %s0, tfile,
123 str-
124 error(errno));
125 return -1;
126 }</screen>
127     </section>
128   </section>
129   <section xml:id="dbdoclet.50438215_50149">
130     <title>llapi_file_get_stripe</title>
131     <para>Use <literal>llapi_file_get_stripe</literal> to get striping information for a file or directory on a Lustre file system.</para>
132     <section remap="h5">
133       <title>Synopsis</title>
134       <screen>
135 #include &lt;lustre/lustreapi.h&gt;
136  
137 int llapi_file_get_stripe(const char *<emphasis>path</emphasis>, void *<emphasis>lum</emphasis>);</screen>
138     </section>
139     <section remap="h5">
140       <title>Description</title>
141       <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>
142       <screen>struct lov_user_md_v1 {
143 __u32 lmm_magic;
144 __u32 lmm_pattern;
145 __u64 lmm_object_id;
146 __u64 lmm_object_seq;
147 __u32 lmm_stripe_size;
148 __u16 lmm_stripe_count;
149 __u16 lmm_stripe_offset;
150 struct lov_user_ost_data_v1 lmm_objects[0];
151 } __attribute__((packed));
152 struct lov_user_md_v3 {
153 __u32 lmm_magic;
154 __u32 lmm_pattern;
155 __u64 lmm_object_id;
156 __u64 lmm_object_seq;
157 __u32 lmm_stripe_size;
158 __u16 lmm_stripe_count;
159 __u16 lmm_stripe_offset;
160 char lmm_pool_name[LOV_MAXPOOLNAME];
161 struct lov_user_ost_data_v1 lmm_objects[0];
162 } __attribute__((packed));</screen>
163       <informaltable frame="all">
164         <tgroup cols="2">
165           <colspec colname="c1" colwidth="50*"/>
166           <colspec colname="c2" colwidth="50*"/>
167           <thead>
168             <row>
169               <entry>
170                 <para><emphasis role="bold">Option</emphasis></para>
171               </entry>
172               <entry>
173                 <para><emphasis role="bold">Description</emphasis></para>
174               </entry>
175             </row>
176           </thead>
177           <tbody>
178             <row>
179               <entry>
180                 <para> <literal>lmm_magic</literal></para>
181               </entry>
182               <entry>
183                 <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>
184               </entry>
185             </row>
186             <row>
187               <entry>
188                 <para> <literal>lmm_pattern</literal></para>
189               </entry>
190               <entry>
191                 <para>Holds the striping pattern. Only <literal>LOV_PATTERN_RAID0</literal> is possible in this Lustre version.</para>
192               </entry>
193             </row>
194             <row>
195               <entry>
196                 <para> <literal>lmm_object_id</literal></para>
197               </entry>
198               <entry>
199                 <para>Holds the MDS object ID.</para>
200               </entry>
201             </row>
202             <row>
203               <entry>
204                 <para> <literal>lmm_object_gr</literal></para>
205               </entry>
206               <entry>
207                 <para>Holds the MDS object group.</para>
208               </entry>
209             </row>
210             <row>
211               <entry>
212                 <para> <literal>lmm_stripe_size</literal></para>
213               </entry>
214               <entry>
215                 <para>Holds the stripe size in bytes.</para>
216               </entry>
217             </row>
218             <row>
219               <entry>
220                 <para> <literal>lmm_stripe_count</literal></para>
221               </entry>
222               <entry>
223                 <para>Holds the number of OSTs over which the file is striped.</para>
224               </entry>
225             </row>
226             <row>
227               <entry>
228                 <para> <literal>lmm_stripe_offset</literal></para>
229               </entry>
230               <entry>
231                 <para>Holds the OST index from which the file starts.</para>
232               </entry>
233             </row>
234             <row>
235               <entry>
236                 <para> <literal>lmm_pool_name</literal></para>
237               </entry>
238               <entry>
239                 <para>Holds the OST pool name to which the file belongs.</para>
240               </entry>
241             </row>
242             <row>
243               <entry>
244                 <para> <literal>lmm_objects</literal></para>
245               </entry>
246               <entry>
247                 <para>An array of <literal>lmm_stripe_count</literal> members containing per OST file information in</para>
248                 <para>the following format:</para>
249                 <screen>struct lov_user_ost_data_v1 {
250                 __u64 l_object_id;
251                 __u64 l_object_seq;
252                 __u32 l_ost_gen;
253                 __u32 l_ost_idx;
254                 } __attribute__((packed));</screen>
255               </entry>
256             </row>
257             <row>
258               <entry>
259                 <para> <literal>l_object_id</literal></para>
260               </entry>
261               <entry>
262                 <para>Holds the OST&apos;s object ID.</para>
263               </entry>
264             </row>
265             <row>
266               <entry>
267                 <para> <literal>l_object_seq</literal></para>
268               </entry>
269               <entry>
270                 <para>Holds the OST&apos;s object group.</para>
271               </entry>
272             </row>
273             <row>
274               <entry>
275                 <para> <literal>l_ost_gen</literal></para>
276               </entry>
277               <entry>
278                 <para>Holds the OST&apos;s index generation.</para>
279               </entry>
280             </row>
281             <row>
282               <entry>
283                 <para> <literal>l_ost_idx</literal></para>
284               </entry>
285               <entry>
286                 <para>Holds the OST&apos;s index in LOV.</para>
287               </entry>
288             </row>
289           </tbody>
290         </tgroup>
291       </informaltable>
292     </section>
293     <section remap="h5">
294       <title>Return Values</title>
295       <para><literal>llapi_file_get_stripe()</literal> returns:</para>
296       <para><literal>0</literal> On success</para>
297       <para><literal>!= 0</literal> On failure, <literal>errno</literal> is set appropriately</para>
298     </section>
299     <section remap="h5">
300       <title>Errors</title>
301       <informaltable frame="all">
302         <tgroup cols="2">
303           <colspec colname="c1" colwidth="50*"/>
304           <colspec colname="c2" colwidth="50*"/>
305           <thead>
306             <row>
307               <entry>
308                 <para><emphasis role="bold">Errors</emphasis></para>
309               </entry>
310               <entry>
311                 <para><emphasis role="bold">Description</emphasis></para>
312               </entry>
313             </row>
314           </thead>
315           <tbody>
316             <row>
317               <entry>
318                 <para> <literal>ENOMEM</literal></para>
319               </entry>
320               <entry>
321                 <para>Failed to allocate memory</para>
322               </entry>
323             </row>
324             <row>
325               <entry>
326                 <para> <literal>ENAMETOOLONG</literal></para>
327               </entry>
328               <entry>
329                 <para>Path was too long</para>
330               </entry>
331             </row>
332             <row>
333               <entry>
334                 <para> <literal>ENOENT</literal></para>
335               </entry>
336               <entry>
337                 <para>Path does not point to a file or directory</para>
338               </entry>
339             </row>
340             <row>
341               <entry>
342                 <para> <literal>ENOTTY</literal></para>
343               </entry>
344               <entry>
345                 <para>Path does not point to a Lustre file system</para>
346               </entry>
347             </row>
348             <row>
349               <entry>
350                 <para> <literal>EFAULT</literal></para>
351               </entry>
352               <entry>
353                 <para>Memory region pointed by lum is not properly mapped</para>
354               </entry>
355             </row>
356           </tbody>
357         </tgroup>
358       </informaltable>
359     </section>
360     <section remap="h5">
361       <title>Examples</title>
362       <programlisting>
363 #include &lt;stdio.h&gt;
364 #include &lt;stdlib.h&gt;
365 #include &lt;errno.h&gt;
366 #include &lt;lustre/lustreapi.h&gt;
367
368 static inline int maxint(int a, int b)
369 {
370         return a &gt; b ? a : b;
371 }
372 static void *alloc_lum()
373 {
374         int v1, v3, join;
375         v1 = sizeof(struct lov_user_md_v1) +
376                 LOV_MAX_STRIPE_COUNT * sizeof(struct lov_user_ost_data_v1);
377         v3 = sizeof(struct lov_user_md_v3) +
378                 LOV_MAX_STRIPE_COUNT * sizeof(struct lov_user_ost_data_v1);
379         return malloc(maxint(v1, v3));
380 }
381 int main(int argc, char** argv)
382 {
383         struct lov_user_md *lum_file = NULL;
384         int rc;
385         int lum_size;
386         if (argc != 2) {
387                 fprintf(stderr, &quot;Usage: %s &lt;filename&gt;\n&quot;, argv[0]);
388                 return 1;
389         }
390         lum_file = alloc_lum();
391         if (lum_file == NULL) {
392                 rc = ENOMEM;
393                 goto cleanup;
394         }
395         rc = llapi_file_get_stripe(argv[1], lum_file);
396         if (rc) {
397                 rc = errno;
398                 goto cleanup;
399         }
400         /* stripe_size stripe_count */
401         printf(&quot;%d %d\n&quot;,
402                         lum_file-&gt;lmm_stripe_size,
403                         lum_file-&gt;lmm_stripe_count);
404 cleanup:
405         if (lum_file != NULL)
406                 free(lum_file);
407         return rc;
408 }
409 </programlisting>
410     </section>
411   </section>
412   <section xml:id="dbdoclet.50438215_86607">
413     <title>
414       <literal>llapi_file_open</literal>
415     </title>
416     <para>The <literal>llapi_file_open</literal> command opens (or creates) a file or device on a Lustre filesystem.</para>
417     <section remap="h5">
418       <title>Synopsis</title>
419       <screen>#include &lt;lustre/lustreapi.h&gt;
420 int llapi_file_open(const char *<emphasis>name</emphasis>, int <emphasis>flags</emphasis>, int <emphasis>mode</emphasis>, 
421    unsigned long long <emphasis>stripe_size</emphasis>, int <emphasis>stripe_offset</emphasis>, 
422    int <emphasis>stripe_count</emphasis>, int <emphasis>stripe_pattern</emphasis>);
423 int llapi_file_create(const char *<emphasis>name</emphasis>, unsigned long long <emphasis>stripe_size</emphasis>, 
424    int <emphasis>stripe_offset</emphasis>, int <emphasis>stripe_count</emphasis>, 
425    int <emphasis>stripe_pattern</emphasis>);
426 </screen>
427     </section>
428     <section remap="h5">
429       <title>Description</title>
430       <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>
431       <para><literal>llapi_file_open()</literal> opens a file with a given name on a Lustre filesystem.</para>
432       <informaltable frame="all">
433         <tgroup cols="2">
434           <colspec colname="c1" colwidth="50*"/>
435           <colspec colname="c2" colwidth="50*"/>
436           <thead>
437             <row>
438               <entry>
439                 <para><emphasis role="bold">Option</emphasis></para>
440               </entry>
441               <entry>
442                 <para><emphasis role="bold">Description</emphasis></para>
443               </entry>
444             </row>
445           </thead>
446           <tbody>
447             <row>
448               <entry>
449                 <para> <literal>flags</literal></para>
450               </entry>
451               <entry>
452                 <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>
453               </entry>
454             </row>
455             <row>
456               <entry>
457                 <para> <literal>mode</literal></para>
458               </entry>
459               <entry>
460                 <para>Specifies the permission bits to be used for a new file when <literal>O_CREAT</literal> is used.</para>
461               </entry>
462             </row>
463             <row>
464               <entry>
465                 <para> <literal>stripe_size</literal></para>
466               </entry>
467               <entry>
468                 <para>Specifies stripe size (in bytes). Should be multiple of 64 KB, not exceeding 4 GB.</para>
469               </entry>
470             </row>
471             <row>
472               <entry>
473                 <para> <literal>stripe_offset</literal></para>
474               </entry>
475               <entry>
476                 <para>Specifies an OST index from which the file should start. The default value is -1.</para>
477               </entry>
478             </row>
479             <row>
480               <entry>
481                 <para> <literal>stripe_count</literal></para>
482               </entry>
483               <entry>
484                 <para>Specifies the number of OSTs to stripe the file across. The default value is -1.</para>
485               </entry>
486             </row>
487             <row>
488               <entry>
489                 <para> <literal>stripe_pattern</literal></para>
490               </entry>
491               <entry>
492                 <para>Specifies the striping pattern. In this version of Lustre, only <literal>LOV_PATTERN_RAID0</literal> is available. The default value is 0.</para>
493               </entry>
494             </row>
495           </tbody>
496         </tgroup>
497       </informaltable>
498     </section>
499     <section remap="h5">
500       <title>Return Values</title>
501       <para><literal>llapi_file_open()</literal> and <literal>llapi_file_create()</literal> return:</para>
502       <para><literal>&gt;=0</literal> On success, for <literal>llapi_file_open</literal> the return value is a file descriptor</para>
503       <para><literal>&lt;0</literal> On failure, the absolute value is an error code</para>
504     </section>
505     <section remap="h5">
506       <title>Errors</title>
507       <informaltable frame="all">
508         <tgroup cols="2">
509           <colspec colname="c1" colwidth="50*"/>
510           <colspec colname="c2" colwidth="50*"/>
511           <thead>
512             <row>
513               <entry>
514                 <para><emphasis role="bold">Errors</emphasis></para>
515               </entry>
516               <entry>
517                 <para><emphasis role="bold">Description</emphasis></para>
518               </entry>
519             </row>
520           </thead>
521           <tbody>
522             <row>
523               <entry>
524                 <para> <literal>EINVAL</literal></para>
525               </entry>
526               <entry>
527                 <para><literal>stripe_size</literal> or <literal>stripe_offset</literal> or <literal>stripe_count</literal> or <literal>stripe_pattern</literal> is invalid.</para>
528               </entry>
529             </row>
530             <row>
531               <entry>
532                 <para> <literal>EEXIST</literal></para>
533               </entry>
534               <entry>
535                 <para>Striping information has already been set and cannot be altered; <literal>name</literal> already exists.</para>
536               </entry>
537             </row>
538             <row>
539               <entry>
540                 <para> <literal>EALREADY</literal></para>
541               </entry>
542               <entry>
543                 <para>Striping information has already been set and cannot be altered</para>
544               </entry>
545             </row>
546             <row>
547               <entry>
548                 <para> <literal>ENOTTY</literal></para>
549               </entry>
550               <entry>
551                 <para> <literal>name</literal> may not point to a Lustre filesystem.</para>
552               </entry>
553             </row>
554           </tbody>
555         </tgroup>
556       </informaltable>
557     </section>
558     <section remap="h5">
559       <title>Example</title>
560       <programlisting>
561 #include &lt;stdio.h&gt;
562 #include &lt;lustre/lustreapi.h&gt;
563
564 int main(int argc, char *argv[])
565 {
566         int rc;
567         if (argc != 2)
568                 return -1;
569         rc = llapi_file_create(argv[1], 1048576, 0, 2, LOV_PATTERN_RAID0);
570         if (rc &lt; 0) {
571                 fprintf(stderr, &quot;file creation has failed, %s\n&quot;,         strerror(-rc));
572                 return -1;
573         }
574         printf(&quot;%s with stripe size 1048576, striped across 2 OSTs,&quot;
575                         &quot; has been created!\n&quot;, argv[1]);
576         return 0;
577 }
578 </programlisting>
579     </section>
580   </section>
581   <section xml:id="dbdoclet.50438215_12433">
582     <title>
583       <literal>llapi_quotactl</literal>
584     </title>
585     <para>Use <literal>llapi_quotact</literal>l to manipulate disk quotas on a Lustre file system.</para>
586     <section remap="h5">
587       <title>Synopsis</title>
588       <screen>#include &lt;lustre/lustreapi.h&gt;
589 int llapi_quotactl(char&quot; &quot; *mnt,&quot; &quot; struct if_quotactl&quot; &quot; *qctl)
590  
591 struct if_quotactl {
592         __u32                   qc_cmd;
593         __u32                   qc_type;
594         __u32                   qc_id;
595         __u32                   qc_stat;
596         struct obd_dqinfo       qc_dqinfo;
597         struct obd_dqblk        qc_dqblk;
598         char                    obd_type[16];
599         struct obd_uuid         obd_uuid;
600 };
601 struct obd_dqblk {
602         __u64 dqb_bhardlimit;
603         __u64 dqb_bsoftlimit;
604         __u64 dqb_curspace;
605         __u64 dqb_ihardlimit;
606         __u64 dqb_isoftlimit;
607         __u64 dqb_curinodes;
608         __u64 dqb_btime;
609         __u64 dqb_itime;
610         __u32 dqb_valid;
611         __u32 padding;
612 };
613 struct obd_dqinfo {
614         __u64 dqi_bgrace;
615         __u64 dqi_igrace;
616         __u32 dqi_flags;
617         __u32 dqi_valid;
618 };
619 struct obd_uuid {
620         char uuid[40];
621 };</screen>
622     </section>
623     <section remap="h5">
624       <title>Description</title>
625       <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>
626       <informaltable frame="all">
627         <tgroup cols="2">
628           <colspec colname="c1" colwidth="50*"/>
629           <colspec colname="c2" colwidth="50*"/>
630           <thead>
631             <row>
632               <entry>
633                 <para><emphasis role="bold">Option</emphasis></para>
634               </entry>
635               <entry>
636                 <para><emphasis role="bold">Description</emphasis></para>
637               </entry>
638             </row>
639           </thead>
640           <tbody>
641             <row>
642               <entry>
643                 <para> <literal>LUSTRE_Q_QUOTAON</literal></para>
644               </entry>
645               <entry>
646                 <para>Turns on 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). The quota files must exist. They are normally created with the <literal>llapi_quotacheck</literal> call. This call is restricted to the super user privilege. As of 2.4.0, quota is now enabled on a per-filesystem basis via <literal>lctl conf_param</literal> (see <xref linkend="enabling_disk_quotas"/>) on the MGS node and quotacheck isn't needed any more.</para>
647               </entry>
648             </row>
649             <row>
650               <entry>
651                 <para> <literal>LUSTRE_Q_QUOTAOFF</literal></para>
652               </entry>
653               <entry>
654                 <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>
655               </entry>
656             </row>
657             <row>
658               <entry>
659                 <para> <literal>LUSTRE_Q_GETQUOTA</literal></para>
660               </entry>
661               <entry>
662                 <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>
663               </entry>
664             </row>
665             <row>
666               <entry>
667                 <para> <literal>LUSTRE_Q_SETQUOTA</literal></para>
668               </entry>
669               <entry>
670                 <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>
671               </entry>
672             </row>
673             <row>
674               <entry>
675                 <para> <literal>LUSTRE_Q_GETINFO</literal></para>
676               </entry>
677               <entry>
678                 <para>Gets information about quotas. <emphasis>qc_type</emphasis> is either <literal>USRQUOTA</literal> or <literal>GRPQUOTA</literal>. On return, <emphasis>dqi_igrace</emphasis> is inode grace time (in seconds), <emphasis>dqi_bgrace</emphasis> is block grace time (in seconds), <emphasis>dqi_flags</emphasis> is not used by the current Lustre version.</para>
679               </entry>
680             </row>
681             <row>
682               <entry>
683                 <para> <literal>LUSTRE_Q_SETINFO</literal></para>
684               </entry>
685               <entry>
686                 <para>Sets quota information (like grace times). <emphasis>qc_type</emphasis> is either <literal>USRQUOTA</literal> or <literal>GRPQUOTA</literal>. <emphasis>dqi_igrace</emphasis> is inode grace time (in seconds), <emphasis>dqi_bgrace</emphasis> is block grace time (in seconds), <emphasis>dqi_flags</emphasis> is not used by the current Lustre version and must be zeroed.</para>
687               </entry>
688             </row>
689           </tbody>
690         </tgroup>
691       </informaltable>
692     </section>
693     <section remap="h5">
694       <title>Return Values</title>
695       <para><literal>llapi_quotactl()</literal> returns:</para>
696       <para><literal>0</literal> On success</para>
697       <para><literal> -1 </literal> On failure and sets error number (<literal>errno</literal>) to indicate the error</para>
698     </section>
699     <section remap="h5">
700       <title>Errors</title>
701       <para><literal>llapi_quotactl</literal> errors are described below.</para>
702       <informaltable frame="all">
703         <tgroup cols="2">
704           <colspec colname="c1" colwidth="50*"/>
705           <colspec colname="c2" colwidth="50*"/>
706           <thead>
707             <row>
708               <entry>
709                 <para><emphasis role="bold">Errors</emphasis></para>
710               </entry>
711               <entry>
712                 <para><emphasis role="bold">Description</emphasis></para>
713               </entry>
714             </row>
715           </thead>
716           <tbody>
717             <row>
718               <entry>
719                 <para> <literal>EFAULT</literal></para>
720               </entry>
721               <entry>
722                 <para><emphasis>qctl</emphasis> is invalid.</para>
723               </entry>
724             </row>
725             <row>
726               <entry>
727                 <para> <literal>ENOSYS</literal></para>
728               </entry>
729               <entry>
730                 <para>Kernel or Lustre modules have not been compiled with the <literal>QUOTA</literal> option.</para>
731               </entry>
732             </row>
733             <row>
734               <entry>
735                 <para> <literal>ENOMEM</literal></para>
736               </entry>
737               <entry>
738                 <para>Insufficient memory to complete operation.</para>
739               </entry>
740             </row>
741             <row>
742               <entry>
743                 <para> <literal>ENOTTY</literal></para>
744               </entry>
745               <entry>
746                 <para> <emphasis>qc_cmd</emphasis> is invalid.</para>
747               </entry>
748             </row>
749             <row>
750               <entry>
751                 <para> <literal>EBUSY</literal></para>
752               </entry>
753               <entry>
754                 <para>Cannot process during quotacheck.</para>
755               </entry>
756             </row>
757             <row>
758               <entry>
759                 <para> <literal>ENOENT</literal></para>
760               </entry>
761               <entry>
762                 <para> <emphasis>uuid</emphasis> does not correspond to OBD or <emphasis>mnt</emphasis> does not exist.</para>
763               </entry>
764             </row>
765             <row>
766               <entry>
767                 <para> <literal>EPERM</literal></para>
768               </entry>
769               <entry>
770                 <para>The call is privileged and the caller is not the super user.</para>
771               </entry>
772             </row>
773             <row>
774               <entry>
775                 <para> <literal>ESRCH</literal></para>
776               </entry>
777               <entry>
778                 <para>No disk quota is found for the indicated user. Quotas have not been turned on for this file system.</para>
779               </entry>
780             </row>
781           </tbody>
782         </tgroup>
783       </informaltable>
784     </section>
785   </section>
786   <section xml:id="dbdoclet.50438215_15718">
787     <title>
788       <literal>llapi_path2fid</literal>
789     </title>
790     <para>Use <literal>llapi_path2fid</literal> to get the FID from the pathname.</para>
791     <section remap="h5">
792       <title>Synopsis</title>
793       <screen>#include &lt;lustre/lustreapi.h&gt;
794  
795 int llapi_path2fid(const char *path, unsigned long long *seq, unsigned long *oid, unsigned long *ver)</screen>
796     </section>
797     <section remap="h5">
798       <title>Description</title>
799       <para>The <literal>llapi_path2fid</literal> function returns the FID (sequence : object ID : version) for the pathname.</para>
800     </section>
801     <section remap="h5">
802       <title>Return Values</title>
803       <para><literal>llapi_path2fid</literal> returns:</para>
804       <para><literal>0</literal> On success</para>
805       <para>non-zero value On failure</para>
806     </section>
807   </section>
808   <section xml:id="dbdoclet.50438215_marker-1297700">
809     <title>Example Using the <literal>llapi</literal> Library</title>
810     <para>Use <literal>llapi_file_create</literal> to set Lustre properties for a new file. For a synopsis and description of llapi_file_create and examples of how to use it, see <xref linkend="configurationfilesmoduleparameters"/>.</para>
811     <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>
812     <para><emphasis role="bold">A simple C program to demonstrate striping API - libtest.c</emphasis></para>
813     <programlisting>
814 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
815  * vim:expandtab:shiftwidth=8:tabstop=8:
816  *
817  * lustredemo - a simple example of lustreapi functions
818  */
819 #include &lt;stdio.h&gt;
820 #include &lt;fcntl.h&gt;
821 #include &lt;dirent.h&gt;
822 #include &lt;errno.h&gt;
823 #include &lt;stdlib.h&gt;
824 #include &lt;lustre/lustreapi.h&gt;
825 #define MAX_OSTS 1024
826 #define LOV_EA_SIZE(lum, num) (sizeof(*lum) + num * sizeof(*lum-&gt;lmm_objects))
827 #define LOV_EA_MAX(lum) LOV_EA_SIZE(lum, MAX_OSTS)
828
829 /*
830  * This program provides crude examples of using the lustreapi API functions
831  */
832 /* Change these definitions to suit */
833
834 #define TESTDIR &quot;/tmp&quot;           /* Results directory */
835 #define TESTFILE &quot;lustre_dummy&quot;  /* Name for the file we create/destroy */
836 #define FILESIZE 262144                    /* Size of the file in words */
837 #define DUMWORD &quot;DEADBEEF&quot;       /* Dummy word used to fill files */
838 #define MY_STRIPE_WIDTH 2                  /* Set this to the number of OST required */
839 #define MY_LUSTRE_DIR &quot;/mnt/lustre/ftest&quot;
840
841 int close_file(int fd)
842 {
843         if (close(fd) &lt; 0) {
844                 fprintf(stderr, &quot;File close failed: %d (%s)\n&quot;, errno, strerror(errno));
845                 return -1;
846         }
847         return 0;
848 }
849
850 int write_file(int fd)
851 {
852         char *stng =  DUMWORD;
853         int cnt = 0;
854
855         for( cnt = 0; cnt &lt; FILESIZE; cnt++) {
856                 write(fd, stng, sizeof(stng));
857         }
858         return 0;
859 }
860 /* Open a file, set a specific stripe count, size and starting OST
861  *    Adjust the parameters to suit */
862 int open_stripe_file()
863 {
864         char *tfile = TESTFILE;
865         int stripe_size = 65536;    /* System default is 4M */
866         int stripe_offset = -1;     /* Start at default */
867         int stripe_count = MY_STRIPE_WIDTH;  /*Single stripe for this demo*/
868         int stripe_pattern = 0;     /* only RAID 0 at this time */
869         int rc, fd;
870
871         rc = llapi_file_create(tfile,
872                         stripe_size,stripe_offset,stripe_count,stripe_pattern);
873         /* result code is inverted, we may return -EINVAL or an ioctl error.
874          * We borrow an error message from sanity.c
875          */
876         if (rc) {
877                 fprintf(stderr,&quot;llapi_file_create failed: %d (%s) \n&quot;, rc, strerror(-rc));
878                 return -1;
879         }
880         /* llapi_file_create closes the file descriptor, we must re-open */
881         fd = open(tfile, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644);
882         if (fd &lt; 0) {
883                 fprintf(stderr, &quot;Can't open %s file: %d (%s)\n&quot;, tfile, errno, strerror(errno));
884                 return -1;
885         }
886         return fd;
887 }
888
889 /* output a list of uuids for this file */
890 int get_my_uuids(int fd)
891 {
892         struct obd_uuid uuids[1024], *uuidp;        /* Output var */
893         int obdcount = 1024;
894         int rc,i;
895
896         rc = llapi_lov_get_uuids(fd, uuids, &amp;obdcount);
897         if (rc != 0) {
898                 fprintf(stderr, &quot;get uuids failed: %d (%s)\n&quot;,errno, strerror(errno));
899         }
900         printf(&quot;This file system has %d obds\n&quot;, obdcount);
901         for (i = 0, uuidp = uuids; i &lt; obdcount; i++, uuidp++) {
902                 printf(&quot;UUID %d is %s\n&quot;,i, uuidp-&gt;uuid);
903         }
904         return 0;
905 }
906
907 /* Print out some LOV attributes. List our objects */
908 int get_file_info(char *path)
909 {
910
911         struct lov_user_md *lump;
912         int rc;
913         int i;
914
915         lump = malloc(LOV_EA_MAX(lump));
916         if (lump == NULL) {
917                 return -1;
918         }
919
920         rc = llapi_file_get_stripe(path, lump);
921
922         if (rc != 0) {
923                 fprintf(stderr, &quot;get_stripe failed: %d (%s)\n&quot;,errno, strerror(errno));
924                 return -1;
925         }
926
927         printf(&quot;Lov magic %u\n&quot;, lump-&gt;lmm_magic);
928         printf(&quot;Lov pattern %u\n&quot;, lump-&gt;lmm_pattern);
929         printf(&quot;Lov object id %llu\n&quot;, lump-&gt;lmm_object_id);
930         printf(&quot;Lov stripe size %u\n&quot;, lump-&gt;lmm_stripe_size);
931         printf(&quot;Lov stripe count %hu\n&quot;, lump-&gt;lmm_stripe_count);
932         printf(&quot;Lov stripe offset %u\n&quot;, lump-&gt;lmm_stripe_offset);
933         for (i = 0; i &lt; lump-&gt;lmm_stripe_count; i++) {
934                 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);
935         }
936
937         free(lump);
938         return rc;
939
940 }
941
942 /* Ping all OSTs that belong to this filesystem */
943 int ping_osts()
944 {
945         DIR *dir;
946         struct dirent *d;
947         char osc_dir[100];
948         int rc;
949
950         sprintf(osc_dir, &quot;/proc/fs/lustre/osc&quot;);
951         dir = opendir(osc_dir);
952         if (dir == NULL) {
953                 printf(&quot;Can't open dir\n&quot;);
954                 return -1;
955         }
956         while((d = readdir(dir)) != NULL) {
957                 if ( d-&gt;d_type == DT_DIR ) {
958                         if (! strncmp(d-&gt;d_name, &quot;OSC&quot;, 3)) {
959                                 printf(&quot;Pinging OSC %s &quot;, d-&gt;d_name);
960                                 rc = llapi_ping(&quot;osc&quot;, d-&gt;d_name);
961                                 if (rc) {
962                                         printf(&quot;  bad\n&quot;);
963                                 } else {
964                                         printf(&quot;  good\n&quot;);
965                                 }
966                         }
967                 }
968         }
969         return 0;
970
971 }
972
973 int main()
974 {
975         int file;
976         int rc;
977         char filename[100];
978         char sys_cmd[100];
979
980         sprintf(filename, &quot;%s/%s&quot;,MY_LUSTRE_DIR, TESTFILE);
981
982         printf(&quot;Open a file with striping\n&quot;);
983         file = open_stripe_file();
984         if ( file &lt; 0 ) {
985                 printf(&quot;Exiting\n&quot;);
986                 exit(1);
987         }
988         printf(&quot;Getting uuid list\n&quot;);
989         rc = get_my_uuids(file);
990         printf(&quot;Write to the file\n&quot;);
991         rc = write_file(file);
992         rc = close_file(file);
993         printf(&quot;Listing LOV data\n&quot;);
994         rc = get_file_info(filename);
995         printf(&quot;Ping our OSTs\n&quot;);
996         rc = ping_osts();
997
998         /* the results should match lfs getstripe */
999         printf(&quot;Confirming our results with lfs getstripe\n&quot;);
1000         sprintf(sys_cmd, &quot;/usr/bin/lfs getstripe %s/%s&quot;, MY_LUSTRE_DIR, TESTFILE);
1001         system(sys_cmd);
1002
1003         printf(&quot;All done\n&quot;);
1004         exit(rc);
1005 }
1006 </programlisting>
1007     <para><emphasis role="bold">Makefile for sample application:</emphasis></para>
1008     <screen> 
1009 gcc -g -O2 -Wall -o lustredemo libtest.c -llustreapi
1010 clean:
1011 rm -f core lustredemo *.o
1012 run: 
1013 make
1014 rm -f /mnt/lustre/ftest/lustredemo
1015 rm -f /mnt/lustre/ftest/lustre_dummy
1016 cp lustredemo /mnt/lustre/ftest/
1017 </screen>
1018     <section remap="h5">
1019       <title>See Also</title>
1020       <itemizedlist>
1021         <listitem>
1022           <para>
1023             <xref linkend="dbdoclet.50438215_30970"/>
1024     </para>
1025         </listitem>
1026         <listitem>
1027           <para>
1028             <xref linkend="dbdoclet.50438215_50149"/>
1029     </para>
1030         </listitem>
1031         <listitem>
1032           <para>
1033             <xref linkend="dbdoclet.50438215_86607"/>
1034     </para>
1035         </listitem>
1036         <listitem>
1037           <para>
1038             <xref linkend="dbdoclet.50438215_12433"/>
1039     </para>
1040         </listitem>
1041       </itemizedlist>
1042     </section>
1043   </section>
1044 </chapter>