1 <?xml version="1.0" encoding="UTF-8"?>
2 <chapter version="5.0" xml:lang="en-US" xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" xml:id='settinglustreproperties'>
4 <title xml:id='settinglustreproperties.title'>Setting Lustre Properties in a C Program (llapi)</title>
6 <para>This chapter describes the llapi 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>
7 <itemizedlist><listitem>
8 <para><xref linkend="dbdoclet.50438215_30970"/></para>
12 <para><xref linkend="dbdoclet.50438215_50149"/></para>
16 <para><xref linkend="dbdoclet.50438215_86607"/></para>
20 <para><xref linkend="dbdoclet.50438215_12433"/></para>
24 <para><xref linkend="dbdoclet.50438215_15718"/></para>
29 <note><para>Lustre programming interface man pages are found in the lustre/doc folder.</para></note>
31 <section xml:id="dbdoclet.50438215_30970">
32 <title>34.1 llapi_file_create</title>
33 <para>Use llapi_file_create to set Lustre properties for a new file.</para>
35 <title>Synopsis</title>
36 <screen>#include <lustre/liblustreapi.h>#include <lustre/lustre_user.h>
37 int llapi_file_create(char *name, long stripe_size, int stripe_offset, int \
38 stripe_count, int stripe_pattern);
42 <title>Description</title>
43 <para>The llapi_file_create() function sets a file descriptor's Lustre striping information. The file descriptor is then accessed with open ().</para>
44 <informaltable frame="all">
46 <colspec colname="c1" colwidth="50*"/>
47 <colspec colname="c2" colwidth="50*"/>
50 <entry><para><emphasis role="bold">Option</emphasis></para></entry>
51 <entry><para><emphasis role="bold">Description</emphasis></para></entry>
56 <entry><para> <emphasis role="bold">llapi_file_create()</emphasis></para></entry>
57 <entry><para> If the file already exists, this parameter returns to 'EEXIST'. If the stripe parameters are invalid, this parameter returns to 'EINVAL'.</para></entry>
60 <entry><para> <emphasis role="bold">stripe_size</emphasis></para></entry>
61 <entry><para> This value must be an even multiple of system page size, as shown by getpagesize (). The default Lustre stripe size is 4MB.</para></entry>
64 <entry><para> <emphasis role="bold">stripe_offset</emphasis></para></entry>
65 <entry><para> Indicates the starting OST for this file.</para></entry>
68 <entry><para> <emphasis role="bold">stripe_count</emphasis></para></entry>
69 <entry><para> Indicates the number of OSTs that this file will be striped across.</para></entry>
72 <entry><para> <emphasis role="bold">stripe_pattern</emphasis></para></entry>
73 <entry><para> Indicates the RAID pattern.</para></entry>
78 <note><para>Currently, only RAID 0 is supported. To use the system defaults, set these values: stripe_size = 0, stripe_offset = -1, stripe_count = 0, stripe_pattern = 0</para></note>
81 <title>Examples</title>
82 <para>System default size is 4 MB.</para>
83 <screen>char *tfile = TESTFILE;
84 int stripe_size = 65536
86 <para>To start at default, run:</para>
87 <screen>int stripe_offset = -1
89 <para>To start at the default, run:</para>
90 <screen>int stripe_count = 1
92 <para>To set a single stripe for this example, run:</para>
93 <screen>int stripe_pattern = 0
95 <para>Currently, only RAID 0 is supported.</para>
96 <screen>int stripe_pattern = 0;
98 rc = llapi_file_create(tfile, stripe_size,stripe_offset, stripe_count,strip\
101 <para>Result code is inverted, you may return with 'EINVAL' or an ioctl error.</para>
103 fprintf(stderr,"llapi_file_create failed: %d (%s) 0, rc, strerror(-rc));retu\
106 <para>llapi_file_create closes the file descriptor. You must re-open the descriptor. To do this, run:</para>
107 <screen>fd = open(tfile, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644); if (fd < 0) \\
108 { fprintf(stderr, "Can't open %s file: %s0, tfile,
116 <section xml:id="dbdoclet.50438215_50149">
117 <title>34.2 llapi_file_get_stripe</title>
118 <para>Use llapi_file_get_stripe to get striping information for a file or directory on a Lustre file system.</para>
120 <title>Synopsis</title>
121 <screen>#include <sys/types.h>
122 #include <sys/stat.h>
123 #include <fcntl.h>
124 #include <liblustre.h>
125 #include <lustre/lustre_idl.h>
126 #include <lustre/liblustreapi.h>
127 #include <lustre/lustre_user.h>
129 int llapi_file_get_stripe(const char *<emphasis>path</emphasis>, void *<emphasis>lum</emphasis>);
133 <title>Description</title>
134 <para>The llapi_file_get_stripe() 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>
135 <screen>struct lov_user_md_v1 {
139 __u64 lmm_object_seq;
140 __u32 lmm_stripe_size;
141 __u16 lmm_stripe_count;
142 __u16 lmm_stripe_offset;
143 struct lov_user_ost_data_v1 lmm_objects[0];
144 } __attribute__((packed));
145 struct lov_user_md_v3 {
149 __u64 lmm_object_seq;
150 __u32 lmm_stripe_size;
151 __u16 lmm_stripe_count;
152 __u16 lmm_stripe_offset;
153 char lmm_pool_name[LOV_MAXPOOLNAME];
154 struct lov_user_ost_data_v1 lmm_objects[0];
155 } __attribute__((packed));
157 <informaltable frame="all">
159 <colspec colname="c1" colwidth="50*"/>
160 <colspec colname="c2" colwidth="50*"/>
163 <entry><para><emphasis role="bold">Option</emphasis></para></entry>
164 <entry><para><emphasis role="bold">Description</emphasis></para></entry>
169 <entry><para> <emphasis role="bold">lmm_magic</emphasis></para></entry>
170 <entry><para> Specifies the format of the returned striping information. <emphasis role="bold">LOV_MAGIC_V1</emphasis> isused for lov_user_md_v1. <emphasis role="bold">LOV_MAGIC_V3</emphasis> is used for lov_user_md_v3.</para></entry>
173 <entry><para> <emphasis role="bold">lmm_pattern</emphasis></para></entry>
174 <entry><para> Holds the striping pattern. Only <emphasis role="bold">LOV_PATTERN_RAID0</emphasis> is possible in this Lustre version.</para></entry>
177 <entry><para> <emphasis role="bold">lmm_object_id</emphasis></para></entry>
178 <entry><para> Holds the MDS object ID.</para></entry>
181 <entry><para> <emphasis role="bold">lmm_object_gr</emphasis></para></entry>
182 <entry><para> Holds the MDS object group.</para></entry>
185 <entry><para> <emphasis role="bold">lmm_stripe_size</emphasis></para></entry>
186 <entry><para> Holds the stripe size in bytes.</para></entry>
189 <entry><para> <emphasis role="bold">lmm_stripe_count</emphasis></para></entry>
190 <entry><para> Holds the number of OSTs over which the file is striped.</para></entry>
193 <entry><para> <emphasis role="bold">lmm_stripe_offset</emphasis></para></entry>
194 <entry><para> Holds the OST index from which the file starts.</para></entry>
197 <entry><para> <emphasis role="bold">lmm_pool_name</emphasis></para></entry>
198 <entry><para> Holds the OST pool name to which the file belongs.</para></entry>
201 <entry><para> <emphasis role="bold">lmm_objects</emphasis></para></entry>
202 <entry><para> An array of lmm_stripe_count members containing per OST file information in</para><para>the following format:</para><para>struct lov_user_ost_data_v1 {</para><para>__u64 l_object_id;</para><para>__u64 l_object_seq;</para><para>__u32 l_ost_gen;</para><para>__u32 l_ost_idx;</para><para>} __attribute__((packed));</para></entry>
205 <entry><para> <emphasis role="bold">l_object_id</emphasis></para></entry>
206 <entry><para> Holds the OST's object ID.</para></entry>
209 <entry><para> <emphasis role="bold">l_object_seq</emphasis></para></entry>
210 <entry><para> Holds the OST's object group.</para></entry>
213 <entry><para> <emphasis role="bold">l_ost_gen</emphasis></para></entry>
214 <entry><para> Holds the OST's index generation.</para></entry>
217 <entry><para> <emphasis role="bold">l_ost_idx</emphasis></para></entry>
218 <entry><para> Holds the OST's index in LOV.</para></entry>
225 <title>Return Values</title>
226 <para>llapi_file_get_stripe() returns:</para>
227 <para><emphasis role="bold">0</emphasis> On success</para>
228 <para><emphasis role="bold">!= 0</emphasis> On failure, <emphasis>errno</emphasis> is set appropriately</para>
231 <title>Errors</title>
232 <informaltable frame="all">
234 <colspec colname="c1" colwidth="50*"/>
235 <colspec colname="c2" colwidth="50*"/>
238 <entry><para><emphasis role="bold">Errors</emphasis></para></entry>
239 <entry><para><emphasis role="bold">Description</emphasis></para></entry>
244 <entry><para> <emphasis role="bold">ENOMEM</emphasis></para></entry>
245 <entry><para> <emphasis role="bold">Failed to allocate memory</emphasis></para></entry>
248 <entry><para> <emphasis role="bold">ENAMETOOLONG</emphasis></para></entry>
249 <entry><para> Path was too long</para></entry>
252 <entry><para> <emphasis role="bold">ENOENT</emphasis></para></entry>
253 <entry><para> Path does not point to a file or directory</para></entry>
256 <entry><para> <emphasis role="bold">ENOTTY</emphasis></para></entry>
257 <entry><para> Path does not point to a Lustre file system</para></entry>
260 <entry><para> <emphasis role="bold">EFAULT</emphasis></para></entry>
261 <entry><para> Memory region pointed by lum is not properly mapped</para></entry>
268 <title>Examples</title>
269 <screen>#include <sys/vfs.h>
270 #include <liblustre.h>
271 #include <lnet/lnetctl.h>
272 #include <obd.h>
273 #include <lustre_lib.h>
274 #include <lustre/liblustreapi.h>
275 #include <obd_lov.h>
276 static inline int maxint(int a, int b)
278 return a > b ? a : b;
280 static void *alloc_lum()
283 v1 = sizeof(struct lov_user_md_v1) +
284 LOV_MAX_STRIPE_COUNT * sizeof(struct lov_user_ost_data_v1);
285 v3 = sizeof(struct lov_user_md_v3) +
286 LOV_MAX_STRIPE_COUNT * sizeof(struct lov_user_ost_data_v1);
287 return malloc(maxint(v1, v3));
289 int main(int argc, char** argv)
291 struct lov_user_md *lum_file = NULL;
295 fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
298 lum_file = alloc_lum();
299 if (lum_file == NULL) {
303 rc = llapi_file_get_stripe(argv[1], lum_file);
308 /* stripe_size stripe_count */
309 printf("%d %d\n",
310 lum_file->lmm_stripe_size,
311 lum_file->lmm_stripe_count);
313 if (lum_file != NULL)
320 <section xml:id="dbdoclet.50438215_86607">
321 <title>34.3 llapi_file_open</title>
322 <para>The llapi_file_open command opens (or creates) a file or device on a Lustre filesystem.</para>
324 <title>Synopsis</title>
325 <screen>#include <sys/types.h>
326 #include <sys/stat.h>
327 #include <fcntl.h>
328 #include <liblustre.h>
329 #include <lustre/lustre_idl.h>
330 #include <lustre/liblustreapi.h>
331 #include <lustre/lustre_user.h>
332 int llapi_file_open(const char *<emphasis>name</emphasis>, int <emphasis>flags</emphasis>, int <emphasis>mode</emphasis>,
333 unsigned long long <emphasis>stripe_size</emphasis>, int <emphasis>stripe_offset</emphasis>,
334 int <emphasis>stripe_count</emphasis>, int <emphasis>stripe_pattern</emphasis>);
335 int llapi_file_create(const char *<emphasis>name</emphasis>, unsigned long long <emphasis>stripe_size</emphasis>,
336 int <emphasis>stripe_offset</emphasis>, int <emphasis>stripe_count</emphasis>,
337 int <emphasis>stripe_pattern</emphasis>);
341 <title>Description</title>
342 <para>The llapi_file_create() call is equivalent to the llapi_file_open call with <emphasis>flags</emphasis> equal to O_CREAT|O_WRONLY and <emphasis>mode</emphasis> equal to 0644, followed by file close.</para>
343 <para>llapi_file_open() opens a file with a given name on a Lustre filesystem.</para>
344 <informaltable frame="all">
346 <colspec colname="c1" colwidth="50*"/>
347 <colspec colname="c2" colwidth="50*"/>
350 <entry><para><emphasis role="bold">Option</emphasis></para></entry>
351 <entry><para><emphasis role="bold">Description</emphasis></para></entry>
356 <entry><para> <emphasis role="bold">flags</emphasis></para></entry>
357 <entry><para> Can be a combination of O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND, O_NONBLOCK, O_SYNC, FASYNC, O_DIRECT, O_LARGEFILE, O_DIRECTORY, O_NOFOLLOW, O_NOATIME.</para></entry>
360 <entry><para> <emphasis role="bold">mode</emphasis></para></entry>
361 <entry><para> Specifies the permission bits to be used for a new file when O_CREAT is used.</para></entry>
364 <entry><para> <emphasis role="bold">stripe_size</emphasis></para></entry>
365 <entry><para> Specifies stripe size (in bytes). Should be multiple of 64 KB, not exceeding 4 GB.</para></entry>
368 <entry><para> <emphasis role="bold">stripe_offset</emphasis></para></entry>
369 <entry><para> Specifies an OST index from which the file should start. The default value is -1.</para></entry>
372 <entry><para> <emphasis role="bold">stripe_count</emphasis></para></entry>
373 <entry><para> Specifies the number of OSTs to stripe the file across. The default value is -1.</para></entry>
376 <entry><para> <emphasis role="bold">stripe_pattern</emphasis></para></entry>
377 <entry><para> Specifies the striping pattern. In this version of Lustre, only LOV_PATTERN_RAID0 is available. The default value is 0.</para></entry>
384 <title>Return Values</title>
385 <para>llapi_file_open() and llapi_file_create() return:</para>
386 <para><emphasis role="bold">>=0</emphasis> On success, for llapi_file_open the return value is a file descriptor</para>
387 <para><emphasis role="bold"><0</emphasis> On failure, the absolute value is an error code</para>
390 <title>Errors</title>
391 <informaltable frame="all">
393 <colspec colname="c1" colwidth="50*"/>
394 <colspec colname="c2" colwidth="50*"/>
397 <entry><para><emphasis role="bold">Errors</emphasis></para></entry>
398 <entry><para><emphasis role="bold">Description</emphasis></para></entry>
403 <entry><para> <emphasis role="bold">EINVAL</emphasis></para></entry>
404 <entry><para> <emphasis role="bold">stripe_size</emphasis> or <emphasis role="bold">stripe_offset</emphasis> or <emphasis role="bold">stripe_count</emphasis> or <emphasis role="bold">stripe_pattern</emphasis> is invalid.</para></entry>
407 <entry><para> <emphasis role="bold">EEXIST</emphasis></para></entry>
408 <entry><para> Striping information has already been set and cannot be altered; <emphasis role="bold">name</emphasis> already exists.</para></entry>
411 <entry><para> <emphasis role="bold">EALREADY</emphasis></para></entry>
412 <entry><para> Striping information has already been set and cannot be altered</para></entry>
415 <entry><para> <emphasis role="bold">ENOTTY</emphasis></para></entry>
416 <entry><para> <emphasis role="bold">name</emphasis> may not point to a Lustre filesystem.</para></entry>
423 <title>Example</title>
424 <screen>#include <sys/types.h>
425 #include <sys/stat.h>
426 #include <fcntl.h>
427 #include <errno.h>
428 #include <stdio.h>
429 #include <liblustre.h>
430 #include <lustre/lustre_idl.h>
431 #include <lustre/liblustreapi.h>
432 #include <lustre/lustre_user.h>
433 int main(int argc, char *argv[])
438 rc = llapi_file_create(argv[1], 1048576, 0, 2, LOV_PATTERN_RAID0);
440 fprintf(stderr, "file creation has failed, %s\n", strerror\
444 printf("%s with stripe size 1048576, striped across 2 OSTs,"
445 " has been created!\n", argv[1]);
451 <section xml:id="dbdoclet.50438215_12433">
452 <title>34.4 llapi_quotactl</title>
453 <para>Use llapi_quotactl to manipulate disk quotas on a Lustre file system.</para>
455 <title>Synopsis</title>
456 <screen>#include <liblustre.h>
457 #include <lustre/lustre_idl.h>
458 #include <lustre/liblustreapi.h>
459 #include <lustre/lustre_user.h>
460 int llapi_quotactl(char" " *mnt," " struct if_quotactl" " *qctl)
467 struct obd_dqinfo qc_dqinfo;
468 struct obd_dqblk qc_dqblk;
470 struct obd_uuid obd_uuid;
473 __u64 dqb_bhardlimit;
474 __u64 dqb_bsoftlimit;
476 __u64 dqb_ihardlimit;
477 __u64 dqb_isoftlimit;
496 <title>Description</title>
497 <para>The llapi_quotactl() command manipulates disk quotas on a Lustre file system mount. qc_cmd indicates a command to be applied to UID qc_id or GID qc_id.</para>
498 <informaltable frame="all">
500 <colspec colname="c1" colwidth="50*"/>
501 <colspec colname="c2" colwidth="50*"/>
504 <entry><para><emphasis role="bold">Option</emphasis></para></entry>
505 <entry><para><emphasis role="bold">Description</emphasis></para></entry>
510 <entry><para> <emphasis role="bold">LUSTRE_Q_QUOTAON</emphasis></para></entry>
511 <entry><para> Turns on quotas for a Lustre file system. <emphasis>qc_type</emphasis> is USRQUOTA, GRPQUOTA or UGQUOTA (both user and group quota). The quota files must exist. They are normally created with the llapi_quotacheck call. This call is restricted to the super user privilege.</para></entry>
514 <entry><para> <emphasis role="bold">LUSTRE_Q_QUOTAOFF</emphasis></para></entry>
515 <entry><para> Turns off quotas for a Lustre file system. <emphasis>qc_type</emphasis> is USRQUOTA, GRPQUOTA or UGQUOTA (both user and group quota). This call is restricted to the super user privilege.</para></entry>
518 <entry><para> <emphasis role="bold">LUSTRE_Q_GETQUOTA</emphasis></para></entry>
519 <entry><para> Gets disk quota limits and current usage for user or group <emphasis>qc_id</emphasis>. <emphasis>qc_type</emphasis> is USRQUOTA or GRPQUOTA. <emphasis>uuid</emphasis> may be filled with OBD UUID 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></entry>
522 <entry><para> <emphasis role="bold">LUSTRE_Q_SETQUOTA</emphasis></para></entry>
523 <entry><para> Sets disk quota limits for user or group <emphasis>qc_id</emphasis>. <emphasis>qc_type</emphasis> is USRQUOTA or GRPQUOTA. <emphasis>dqb_valid</emphasis> must be set to QIF_ILIMITS, QIF_BLIMITS or QIF_LIMITS (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></entry>
526 <entry><para> <emphasis role="bold">LUSTRE_Q_GETINFO</emphasis></para></entry>
527 <entry><para> Gets information about quotas. <emphasis>qc_type</emphasis> is either USRQUOTA or GRPQUOTA. 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></entry>
530 <entry><para> <emphasis role="bold">LUSTRE_Q_SETINFO</emphasis></para></entry>
531 <entry><para> Sets quota information (like grace times). <emphasis>qc_type</emphasis> is either USRQUOTA or GRPQUOTA. <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></entry>
538 <title>Return Values</title>
539 <para>llapi_quotactl() returns:</para>
540 <para><emphasis role="bold">0</emphasis> On success</para>
541 <para><emphasis role="bold">-1</emphasis> On failure and sets error number (errno) to indicate the error</para>
544 <title>Errors</title>
545 <para>llapi_quotactl errors are described below.</para>
546 <informaltable frame="all">
548 <colspec colname="c1" colwidth="50*"/>
549 <colspec colname="c2" colwidth="50*"/>
552 <entry><para><emphasis role="bold">Errors</emphasis></para></entry>
553 <entry><para><emphasis role="bold">Description</emphasis></para></entry>
558 <entry><para> <emphasis role="bold">EFAULT</emphasis></para></entry>
559 <entry><para> <emphasis>qctl</emphasis> is invalid.</para></entry>
562 <entry><para> <emphasis role="bold">ENOSYS</emphasis></para></entry>
563 <entry><para> Kernel or Lustre modules have not been compiled with the QUOTA option.</para></entry>
566 <entry><para> <emphasis role="bold">ENOMEM</emphasis></para></entry>
567 <entry><para> Insufficient memory to complete operation.</para></entry>
570 <entry><para> <emphasis role="bold">ENOTTY</emphasis></para></entry>
571 <entry><para> <emphasis>qc_cmd</emphasis> is invalid.</para></entry>
574 <entry><para> <emphasis role="bold">EBUSY</emphasis></para></entry>
575 <entry><para> Cannot process during quotacheck.</para></entry>
578 <entry><para> <emphasis role="bold">ENOENT</emphasis></para></entry>
579 <entry><para> <emphasis>uuid</emphasis> does not correspond to OBD or <emphasis>mnt</emphasis> does not exist.</para></entry>
582 <entry><para> <emphasis role="bold">EPERM</emphasis></para></entry>
583 <entry><para> The call is privileged and the caller is not the super user.</para></entry>
586 <entry><para> <emphasis role="bold">ESRCH</emphasis></para></entry>
587 <entry><para> No disk quota is found for the indicated user. Quotas have not been turned on for this file system.</para></entry>
594 <section xml:id="dbdoclet.50438215_15718">
595 <title>34.5 llapi_path2fid</title>
596 <para>Use llapi_path2fid to get the FID from the pathname.</para>
598 <title>Synopsis</title>
599 <screen>#include <lustre/liblustreapi.h>
600 #include <lustre/lustre_user.h>
602 int llapi_path2fid(const char *path, unsigned long long *seq, unsigned long\
603 *oid, unsigned long *ver)
607 <title>Description</title>
608 <para>The llapi_path2fid function returns the FID (sequence : object ID : version) for the pathname.</para>
611 <title>Return Values</title>
612 <para>llapi_path2fid returns:</para>
613 <para><emphasis role="bold">0</emphasis> On success</para>
614 <para>non-zero value On failure</para>
617 <section xml:id="dbdoclet.50438215_marker-1297700">
618 <title>34.6 Example Using the llapi Library</title>
619 <para>Use llapi_file_create 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>
620 <para>You can set striping from inside programs like ioctl. To compile the sample program, you need to download libtest.c and liblustreapi.c files from the Lustre source tree.</para>
621 <para><emphasis role="bold">A simple C program to demonstrate striping API - libtest.c</emphasis></para>
622 <screen>/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
623 * vim:expandtab:shiftwidth=8:tabstop=8:
625 * lustredemo - simple code examples of liblustreapi functions
628 #include <stdio.h>
629 #include <fcntl.h>
630 #include <sys/stat.h>
631 #include <sys/types.h>
632 #include <dirent.h>
633 #include <errno.h>
634 #include <string.h>
635 #include <unistd.h>
636 #include <stdlib.h>
637 #include <lustre/liblustreapi.h>
638 #include <lustre/lustre_user.h>
639 #define MAX_OSTS 1024
640 #define LOV_EA_SIZE(lum, num) (sizeof(*lum) + num * sizeof(*lum->lmm_objects\
642 #define LOV_EA_MAX(lum) LOV_EA_SIZE(lum, MAX_OSTS)
645 This program provides crude examples of using the liblustre API functions
648 /* Change these definitions to suit */
650 #define TESTDIR "/tmp" /* R\
652 #define TESTFILE "lustre_dummy" \
653 /* Name for the file we create/destroy */
654 #define FILESIZE 262144 \
655 /* Size of the file in words */
656 #define DUMWORD "DEADBEEF" \
657 /* Dummy word used to fill files */
658 #define MY_STRIPE_WIDTH 2 \
659 /* Set this to the number of OST required */
660 #define MY_LUSTRE_DIR "/mnt/lustre/ftest"
663 int close_file(int fd)
665 if (close(fd) < 0) {
666 fprintf(stderr, "File close failed: %d (%s)\n", errno, strerror(er\
673 int write_file(int fd)
675 char *stng = DUMWORD;
678 for( cnt = 0; cnt < FILESIZE; cnt++) {
679 write(fd, stng, sizeof(stng));
683 /* Open a file, set a specific stripe count, size and starting OST
684 Adjust the parameters to suit */
686 int open_stripe_file()
688 char *tfile = TESTFILE;
689 int stripe_size = 65536; \
690 /* System default is 4M */
691 int stripe_offset = -1; \
692 /* Start at default */
693 int stripe_count = MY_STRIPE_WIDTH; \
694 /*Single stripe for this demo*/
695 int stripe_pattern = 0; \
696 /* only RAID 0 at this time */
700 rc = llapi_file_create(tfile,
701 stripe_size,stripe_offset,stripe_count,stripe_pattern);
702 /* result code is inverted, we may return -EINVAL or an ioctl error.
703 We borrow an error message from sanity.c
706 fprintf(stderr,"llapi_file_create failed: %d (%s) \n", rc, st\
710 /* llapi_file_create closes the file descriptor, we must re-open */
711 fd = open(tfile, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644);
713 fprintf(stderr, "Can't open %s file: %d (%s)\n", tfile, errno\
720 /* output a list of uuids for this file */
721 int get_my_uuids(int fd)
723 struct obd_uuid uuids[1024], *uuidp; \
728 rc = llapi_lov_get_uuids(fd, uuids, &obdcount);
730 fprintf(stderr, "get uuids failed: %d (%s)\n",errno, strerror(errn\
733 printf("This file system has %d obds\n", obdcount);
734 for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) {
735 printf("UUID %d is %s\n",i, uuidp->uuid);
740 /* Print out some LOV attributes. List our objects */
741 int get_file_info(char *path)
744 struct lov_user_md *lump;
748 lump = malloc(LOV_EA_MAX(lump));
753 rc = llapi_file_get_stripe(path, lump);
756 fprintf(stderr, "get_stripe failed: %d (%s)\n",errno, strerror(err\
761 printf("Lov magic %u\n", lump->lmm_magic);
762 printf("Lov pattern %u\n", lump->lmm_pattern);
763 printf("Lov object id %llu\n", lump->lmm_object_id);
764 printf("Lov object group %llu\n", lump->lmm_object_gr);
765 printf("Lov stripe size %u\n", lump->lmm_stripe_size);
766 printf("Lov stripe count %hu\n", lump->lmm_stripe_count);
767 printf("Lov stripe offset %u\n", lump->lmm_stripe_offset);
768 for (i = 0; i < lump->lmm_stripe_count; i++) {
769 printf("Object index %d Objid %llu\n", lump->lmm_objects[i].l_ost_i\
770 dx, lump->lmm_objects[i].l_object_id);
778 /* Ping all OSTs that belong to this filesysem */
787 sprintf(osc_dir, "/proc/fs/lustre/osc");
788 dir = opendir(osc_dir);
790 printf("Can't open dir\n");
793 while((d = readdir(dir)) != NULL) {
794 if ( d->d_type == DT_DIR ) {
795 if (! strncmp(d->d_name, "OSC", 3)) {
796 printf("Pinging OSC %s ", d->d_name);
797 rc = llapi_ping("osc", d->d_name);
799 printf(" bad\n");
801 printf(" good\n");
817 sprintf(filename, "%s/%s",MY_LUSTRE_DIR, TESTFILE);
819 printf("Open a file with striping\n");
820 file = open_stripe_file();
822 printf("Exiting\n");
829 printf("Getting uuid list\n");
830 rc = get_my_uuids(file);
831 rintf("Write to the file\n");
832 rc = write_file(file);
833 rc = close_file(file);
834 printf("Listing LOV data\n");
835 rc = get_file_info(filename);
836 printf("Ping our OSTs\n");
839 /* the results should match lfs getstripe */
840 printf("Confirming our results with lfs getsrtipe\n");
841 sprintf(sys_cmd, "/usr/bin/lfs getstripe %s/%s", MY_LUSTRE_DIR, TESTFILE);
844 printf("All done\n");
848 <para><emphasis role="bold">Makefile for sample application:</emphasis></para>
850 gcc -g -O2 -Wall -o lustredemo libtest.c -llustreapi
852 rm -f core lustredemo *.o
855 rm -f /mnt/lustre/ftest/lustredemo
856 rm -f /mnt/lustre/ftest/lustre_dummy
857 cp lustredemo /mnt/lustre/ftest/
860 <title>See Also</title>
862 <xref linkend="dbdoclet.50438215_30970"/>llapi_file_create,
863 <xref linkend="dbdoclet.50438215_50149"/>llapi_file_get_stripe,
864 <xref linkend="dbdoclet.50438215_86607"/>llapi_file_open,
865 <xref linkend="dbdoclet.50438215_12433"/>llapi_quotactl</para>