Whamcloud - gitweb
LUDOC-384 flr: File Level Redundancy (FLR) Documenation 57/31657/7
authorJoe Gmitter <joseph.gmitter@intel.com>
Thu, 15 Mar 2018 22:52:12 +0000 (15:52 -0700)
committerJoseph Gmitter <joseph.gmitter@intel.com>
Thu, 22 Mar 2018 21:18:59 +0000 (21:18 +0000)
This patch creates the initial documentation for the File
Level Redundancy (FLR) feature introduced by LU-9771 in the
Lustre 2.11.0 release.

The FLR feature allows for storing of the same data on
multiple OSTs for a variety of possible benefits and use
cases.

Signed-off-by: Joe Gmitter <joseph.gmitter@intel.com>
Signed-off-by: Jian Yu <jian.yu@intel.com>
Change-Id: I4c4ccb9e5c90144f4686e3853d56ebee459cee70
Reviewed-on: https://review.whamcloud.com/31657
Tested-by: Jenkins
Reviewed-by: Jinshan Xiong <jinshan.xiong@gmail.com>
Reviewed-by: James Nunez <james.a.nunez@intel.com>
FileLevelRedundancy.xml [new file with mode: 0644]
III_LustreAdministration.xml
figures/FLR_DelayedWrite.png [new file with mode: 0644]

diff --git a/FileLevelRedundancy.xml b/FileLevelRedundancy.xml
new file mode 100644 (file)
index 0000000..40bcf7a
--- /dev/null
@@ -0,0 +1,1298 @@
+<?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="flr"
+    condition="l2B">
+  <title xml:id="flr.title">File Level Redundancy (FLR)</title>
+  <para>This chapter describes File Level Redundancy (FLR).</para>
+  <section xml:id="flr.intro">
+    <title>Introduction</title>
+    <para> The Lustre file system was initially designed and implemented for HPC
+      use. It has been working well on high-end storage that has internal
+      redundancy and fault-tolerance. However, despite the expense and
+      complexity of these storage systems, storage failures still occur, and
+      before release 2.11, Lustre could not be more reliable than the
+      individual storage and servers’ components on which it was based. The
+      Lustre file system had no mechanism to mitigate storage hardware
+      failures and files would become inaccessible if a server was inaccessible
+      or otherwise out of service.</para>
+    <para>With the File Level Redundancy (FLR) feature introduced in Lustre
+      Release 2.11, any Lustre file can store the same data on multiple OSTs in
+      order for the system to be robust in the event of storage failures or
+      other outages.  With the choice of multiple mirrors, the best suited
+      mirror can be chosen to satisfy an individual request, which has a direct
+      impact on IO availability.  Furthermore, for files that are concurrently
+      read by many clients (e.g. input decks, shared libraries, or executables)
+      the aggregate parallel read performance of a single file can be improved
+      by creating multiple mirrors of the file data.</para>
+    <para>The first phase of the FLR feature has been implemented with delayed
+      write (<xref linkend="flr.delayedwrite.fig"/>). While writing to a
+      mirrored file, only one primary or preferred mirror will be updated
+      directly during the write, while other mirrors will be simply marked as
+      stale. The file can subsequently return to a mirrored state again by
+      synchronizing among mirrors with command line tools (run by the user or
+      administrator directly or via automated monitoring tools).</para>
+    <figure xml:id="flr.delayedwrite.fig">
+      <title>FLR Delayed Write</title>
+      <mediaobject>
+        <imageobject>
+          <imagedata scalefit="1" width="50%"
+          fileref="figures/FLR_DelayedWrite.png" />
+        </imageobject>
+        <textobject><phrase>FLR Delayed Write Diagram</phrase></textobject>
+      </mediaobject>
+    </figure>
+  </section>
+  <section xml:id="flr.operations">
+    <title>Operations</title>
+    <para>Lustre provides <literal>lfs mirror</literal> command line tools for
+      users to operate on mirrored files or directories.</para>
+    <section xml:id="flr.operations.createmirror">
+      <title>Creating a Mirrored File or Directory</title>
+      <para><emphasis role="strong">Command:</emphasis></para>
+      <screen>lfs mirror create &lt;--mirror-count|-N[mirror_count]
+[setstripe_options|[--flags&lt;=flags&gt;]]&gt; ... &lt;filename|directory&gt;</screen>
+      <para>The above command will create a mirrored file or directory specified
+        by <replaceable>filename</replaceable> or
+        <replaceable>directory</replaceable>, respectively.</para>
+      <informaltable>
+        <tgroup cols="2">
+          <colspec align="left" />
+          <colspec align="left" />
+          <thead>
+            <row>
+              <entry>Option</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry>--mirror-count|-N[mirror_count]</entry>
+              <entry>
+                <para>Indicates the number of mirrors to be created with the
+                  following setstripe options. It can be repeated multiple
+                  times to separate mirrors that have different layouts.
+                </para>
+                <para>The <replaceable>mirror_count</replaceable> argument is
+                  optional and defaults to <literal>1</literal> if it is not
+                  specified; if specified, it must follow the option without a
+                  space.</para>
+              </entry>
+            </row>
+            <row>
+              <entry>setstripe_options</entry>
+              <entry>
+                <para>Specifies a specific layout for the mirror. It can be a
+                  plain layout with a specific striping pattern or a composite
+                  layout, such as <xref linkend="pfl"/>. The options are
+                  the same as those for the <literal>lfs setstripe</literal>
+                  command.</para>
+                <para>If <replaceable>setstripe_options</replaceable> are not
+                  specified, then the stripe options inherited from the previous
+                  component will be used. If there is no previous component,
+                  then the <literal>stripe_count</literal> and
+                  <literal>stripe_size</literal> options inherited from the
+                  filesystem-wide default values will be used, and the OST
+                  <literal>pool_name</literal> inherited from the parent
+                  directory will be used.</para>
+              </entry>
+            </row>
+            <row>
+              <entry>--flags&lt;=flags&gt;</entry>
+              <entry>
+                <para>Sets flags to the mirror to be created.</para>
+                <para>Only the <literal>prefer</literal> flag is supported at
+                  this time. This flag will be set to all components that belong
+                  to the corresponding mirror. The <literal>prefer</literal>
+                  flag gives a hint to Lustre for which mirrors should be used
+                  to serve I/O.  When a mirrored file is being read, the
+                  component(s) with the <literal>prefer</literal> flag is likely
+                  to be picked to serve the read; and when a mirrored file is
+                  prepared to be written, the MDT will tend to choose the
+                  component with the <literal>prefer</literal> flag set and
+                  mark the other components with overlapping extents as stale.
+                  This flag just provides a hint to Lustre, which means Lustre
+                  may still choose mirrors without this flag set, for instance,
+                  if all preferred mirrors are unavailable when the I/O occurs.
+                  This flag can be set on multiple components.</para>
+                <para><emphasis role="strong">Note:</emphasis>  This flag will
+                  be set to all components that belong to the corresponding
+                  mirror. The <literal>--comp-flags</literal> option also
+                  exists, which can be set to individual components at mirror
+                  creation time.</para>
+              </entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </informaltable>
+      <para><emphasis role="strong">Note:</emphasis>  For redundancy and
+        fault-tolerance, users need to make sure that different mirrors must
+        be on different OSTs, even OSSs and racks. An understanding of cluster
+        topology is necessary to achieve this architecture. In the initial
+        implementation the use of the existing OST pools mechanism will allow
+        separating OSTs by any arbitrary criteria:  i.e. fault domain.
+        In practice, users can take advantage of OST pools by grouping OSTs
+        by topological information. Therefore, when creating a mirrored file,
+        users can indicate which OST pools can be used by mirrors.</para>
+      <para><emphasis role="strong">Examples:</emphasis></para>
+      <para>The following command creates a mirrored file with 2 plain layout
+        mirrors:</para>
+      <screen>client# lfs mirror create -N -S 4M -c 2 -p flash \
+                          -N -c -1 -p archive /mnt/testfs/file1</screen>
+      <para>The following command displays the layout information of the
+        mirrored file <literal>/mnt/testfs/file1</literal>:</para>
+      <screen>client# lfs getstripe /mnt/testfs/file1
+/mnt/testfs/file1
+  lcm_layout_gen:    2
+  lcm_mirror_count:  2
+  lcm_entry_count:   2
+    lcme_id:             65537
+    lcme_mirror_id:      1
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  2
+      lmm_stripe_size:   4194304
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 1
+      lmm_pool:          flash
+      lmm_objects:
+      - 0: { l_ost_idx: 1, l_fid: [0x100010000:0x2:0x0] }
+      - 1: { l_ost_idx: 0, l_fid: [0x100000000:0x2:0x0] }
+
+    lcme_id:             131074
+    lcme_mirror_id:      2
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  6
+      lmm_stripe_size:   4194304
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 3
+      lmm_pool:          archive
+      lmm_objects:
+      - 0: { l_ost_idx: 3, l_fid: [0x100030000:0x2:0x0] }
+      - 1: { l_ost_idx: 4, l_fid: [0x100040000:0x2:0x0] }
+      - 2: { l_ost_idx: 5, l_fid: [0x100050000:0x2:0x0] }
+      - 3: { l_ost_idx: 6, l_fid: [0x100060000:0x2:0x0] }
+      - 4: { l_ost_idx: 7, l_fid: [0x100070000:0x2:0x0] }
+      - 5: { l_ost_idx: 2, l_fid: [0x100020000:0x2:0x0] }</screen>
+      <para> The first mirror has 4MB stripe size and two stripes across OSTs in
+        the “flash” OST pool. The second mirror has 4MB stripe size inherited
+        from the first mirror, and stripes across all of the available OSTs in
+        the “archive” OST pool.</para>
+      <para>As mentioned above, it is recommended to use the
+        <literal>--pool|-p</literal> option (one of the
+        <literal>lfs setstripe</literal> options) with OST pools configured with
+        independent fault domains to ensure different mirrors will be placed on
+        different OSTs, servers, and/or racks, thereby improving availability
+        and performance.  If the setstripe options are not specified, it is
+        possible to create mirrors with objects on the same OST(s), which would
+        remove most of the benefit of using replication.</para>
+      <para>In the layout information printed by <literal>lfs getstripe</literal>,
+        <literal>lcme_mirror_id</literal> shows mirror ID, which is the unique
+        numerical identifier for a mirror. And <literal>lcme_flags</literal> shows
+        mirrored component flags. Valid flag names are:</para>
+        <itemizedlist>
+          <listitem>
+            <para><literal>init</literal> - indicates mirrored component has been
+              initialized (has allocated OST objects).</para>
+          </listitem>
+          <listitem>
+            <para><literal>stale</literal> - indicates mirrored component does not
+              have up-to-date data. Stale components will not be used for read or
+              write operations, and need to be resynchronized by running
+              <literal>lfs mirror resync</literal> command before they can be
+              accessed again.</para>
+          </listitem>
+          <listitem>
+            <para><literal>prefer</literal> - indicates mirrored component is
+              preferred for read or write. For example, the mirror is located on
+              SSD-based OSTs or is closer, fewer hops, on the network to the
+              client. This flag can be set by users at mirror creation time.</para>
+          </listitem>
+        </itemizedlist>
+      <para>The following command creates a mirrored file with 3 PFL mirrors:
+      </para>
+      <screen>client# lfs mirror create -N -E 4M -p flash --flags=prefer -E eof -c 2 \
+-N -E 16M -S 8M -c 4 -p archive --comp-flags=prefer -E eof -c -1 \
+-N -E 32M -c 1 -p none -E eof -c -1 /mnt/testfs/file2</screen>
+      <para>The following command displays the layout information of the
+        mirrored file <literal>/mnt/testfs/file2</literal>:</para>
+      <screen>client# lfs getstripe /mnt/testfs/file2
+/mnt/testfs/file2
+  lcm_layout_gen:    6
+  lcm_mirror_count:  3
+  lcm_entry_count:   6
+    lcme_id:             65537
+    lcme_mirror_id:      1
+    lcme_flags:          init,prefer
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   4194304
+      lmm_stripe_count:  1
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 1
+      lmm_pool:          flash
+      lmm_objects:
+      - 0: { l_ost_idx: 1, l_fid: [0x100010000:0x3:0x0] }
+
+    lcme_id:             65538
+    lcme_mirror_id:      1
+    lcme_flags:          prefer
+    lcme_extent.e_start: 4194304
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  2
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: -1
+      lmm_pool:          flash
+
+    lcme_id:             131075
+    lcme_mirror_id:      2
+    lcme_flags:          init,prefer
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   16777216
+      lmm_stripe_count:  4
+      lmm_stripe_size:   8388608
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 4
+      lmm_pool:          archive
+      lmm_objects:
+      - 0: { l_ost_idx: 4, l_fid: [0x100040000:0x3:0x0] }
+      - 1: { l_ost_idx: 5, l_fid: [0x100050000:0x3:0x0] }
+      - 2: { l_ost_idx: 6, l_fid: [0x100060000:0x3:0x0] }
+      - 3: { l_ost_idx: 7, l_fid: [0x100070000:0x3:0x0] }
+
+    lcme_id:             131076
+    lcme_mirror_id:      2
+    lcme_flags:          0
+    lcme_extent.e_start: 16777216
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  6
+      lmm_stripe_size:   8388608
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: -1
+      lmm_pool:          archive
+
+    lcme_id:             196613
+    lcme_mirror_id:      3
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   33554432
+      lmm_stripe_count:  1
+      lmm_stripe_size:   8388608
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 0
+      lmm_objects:
+      - 0: { l_ost_idx: 0, l_fid: [0x100000000:0x3:0x0] }
+
+    lcme_id:             196614
+    lcme_mirror_id:      3
+    lcme_flags:          0
+    lcme_extent.e_start: 33554432
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  -1
+      lmm_stripe_size:   8388608
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: -1</screen>
+      <para>For the first mirror, the first component inherits the stripe count
+        and stripe size from filesystem-wide default values. The second
+        component inherits the stripe size and OST pool from the first
+        component, and has two stripes. Both of the components are allocated
+        from the “flash” OST pool.  Also, the flag <literal>prefer</literal> is
+        applied to all the components of the first mirror, which tells the
+        client to read data from those components whenever they are available.
+      </para>
+      <para>For the second mirror, the first component has an 8MB stripe size
+        and 4 stripes across OSTs in the “archive” OST pool. The second
+        component inherits the stripe size and OST pool from the first
+        component, and stripes across all of the available OSTs in the “archive”
+        OST pool. The flag <literal>prefer</literal> is only applied to the
+        first component.</para>
+      <para>For the third mirror, the first component inherits the stripe size
+        of 8MB from the last component of the second mirror, and has one single
+        stripe. The OST pool name is cleared and inherited from the parent
+        directory (if it was set with OST pool name). The second component
+        inherits stripe size from the first component, and stripes across all of
+        the available OSTs.</para>
+    </section>
+    <section xml:id="flr.operations.extendmirror">
+      <title>Extending a Mirrored File</title>
+      <para><emphasis role="strong">Command:</emphasis></para>
+      <screen>lfs mirror extend [--no-verify] &lt;--mirror-count|-N[mirror_count]
+[setstripe_options|-f &lt;victim_file&gt;]&gt; ... &lt;filename&gt;</screen>
+      <para>The above command will append mirror(s) indicated by
+        <literal>setstripe options</literal> or just take the layout from
+        existing file <replaceable>victim_file</replaceable> into the file
+        <replaceable>filename</replaceable>. The
+        <replaceable>filename</replaceable> must be an existing file, however,
+        it can be a mirrored or regular non-mirrored file. If it is a
+        non-mirrored file, the command will convert it to a mirrored file.
+      </para>
+      <informaltable>
+        <tgroup cols="2">
+          <colspec align="left" />
+          <colspec align="left" />
+          <thead>
+            <row>
+              <entry>Option</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry>--mirror-count|-N[mirror_count]</entry>
+              <entry>
+                <para>Indicates the number of mirrors to be added with the
+                  following <literal>setstripe options</literal>. It can be
+                  repeated multiple times to separate mirrors that have
+                  different layouts.</para>
+                <para>The <replaceable>mirror_count</replaceable> argument is
+                  optional and defaults to <literal>1</literal> if it is not
+                  specified; if specified, it must follow the option without a
+                  space.</para>
+              </entry>
+            </row>
+            <row>
+              <entry>setstripe_options</entry>
+              <entry>
+                <para>Specifies a specific layout for the mirror. It can be a
+                  plain layout with specific striping pattern or a composite
+                  layout, such as <xref linkend="pfl"/>.  The options are the
+                  same as those for the <literal>lfs setstripe</literal>
+                  command.</para>
+                <para>If <replaceable>setstripe_options</replaceable> are not
+                  specified, then the stripe options inherited from the previous
+                  component will be used.  If there is no previous component,
+                  then the <literal>stripe_count</literal> and
+                  <literal>stripe_size</literal> options inherited from
+                  filesystem-wide default values will be used, and the OST
+                  <literal>pool_name</literal> inherited from parent directory
+                  will be used.</para>
+              </entry>
+            </row>
+            <row>
+              <entry>-f &lt;victim_file&gt;</entry>
+              <entry>
+                <para>If <replaceable>victim_file</replaceable> exists, the
+                  command will split the layout from that file and use it as a
+                  mirror added to the mirrored file. After the command is
+                  finished, the <replaceable>victim_file</replaceable> will be
+                  removed.</para>
+                <para><emphasis role="strong">Note</emphasis>: The
+                  <replaceable>setstripe_options</replaceable> cannot be
+                  specified with <literal>-f &lt;victim_file&gt;</literal>
+                  option in one command line.</para>
+              </entry>
+            </row>
+            <row>
+              <entry>--no-verify</entry>
+              <entry>If <replaceable>victim_file</replaceable> is specified, the
+                command will verify that the file contents from
+                <replaceable>victim_file</replaceable> are the same as
+                <replaceable>filename</replaceable>.  Otherwise, the command
+                will return a failure.  However, the option
+                <literal>--no-verify</literal> can be used to override this
+                verification. This option can save significant time on file
+                comparison if the file size is large, but use it only when the
+                file contents are known to be the same.</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </informaltable>
+      <para><emphasis role="strong">Note</emphasis>:  The
+        <literal>lfs mirror extend</literal> operation won't be applied to the
+        directory.</para>
+      <para><emphasis role="strong">Examples:</emphasis></para>
+      <para>The following commands create a non-mirrored file, convert it to
+        a mirrored file, and extend it with a plain layout mirror:</para>
+      <screen># lfs setstripe -p flash /mnt/testfs/file1
+# lfs getstripe /mnt/testfs/file1
+/mnt/testfs/file1
+lmm_stripe_count:  1
+lmm_stripe_size:   1048576
+lmm_pattern:       raid0
+lmm_layout_gen:    0
+lmm_stripe_offset: 0
+lmm_pool:          flash
+        obdidx           objid           objid           group
+             0               4            0x4                0
+
+# lfs mirror extend -N -S 8M -c -1 -p archive /mnt/testfs/file1
+# lfs getstripe /mnt/testfs/file1
+/mnt/testfs/file1
+  lcm_layout_gen:    2
+  lcm_mirror_count:  2
+  lcm_entry_count:   2
+    lcme_id:             65537
+    lcme_mirror_id:      1
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  1
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 0
+      lmm_pool:          flash
+      lmm_objects:
+      - 0: { l_ost_idx: 0, l_fid: [0x100000000:0x4:0x0] }
+
+    lcme_id:             131073
+    lcme_mirror_id:      2
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  6
+      lmm_stripe_size:   8388608
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 3
+      lmm_pool:          archive
+      lmm_objects:
+      - 0: { l_ost_idx: 3, l_fid: [0x100030000:0x3:0x0] }
+      - 1: { l_ost_idx: 4, l_fid: [0x100040000:0x4:0x0] }
+      - 2: { l_ost_idx: 5, l_fid: [0x100050000:0x4:0x0] }
+      - 3: { l_ost_idx: 6, l_fid: [0x100060000:0x4:0x0] }
+      - 4: { l_ost_idx: 7, l_fid: [0x100070000:0x4:0x0] }
+      - 5: { l_ost_idx: 2, l_fid: [0x100020000:0x3:0x0] }</screen>
+      <para>The following commands split the PFL layout from a
+        <replaceable>victim_file</replaceable> and use it as a mirror added to
+        the mirrored file <literal>/mnt/testfs/file1</literal> created in the
+        above example without data verification:</para>
+      <screen># lfs setstripe -E 16M -c 2 -p none \
+                -E eof -c -1 /mnt/testfs/victim_file
+# lfs getstripe /mnt/testfs/victim_file
+/mnt/testfs/victim_file
+  lcm_layout_gen:    2
+  lcm_mirror_count:  1
+  lcm_entry_count:   2
+    lcme_id:             1
+    lcme_mirror_id:      0
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   16777216
+      lmm_stripe_count:  2
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 5
+      lmm_objects:
+      - 0: { l_ost_idx: 5, l_fid: [0x100050000:0x5:0x0] }
+      - 1: { l_ost_idx: 6, l_fid: [0x100060000:0x5:0x0] }
+
+    lcme_id:             2
+    lcme_mirror_id:      0
+    lcme_flags:          0
+    lcme_extent.e_start: 16777216
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  -1
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: -1
+
+# lfs mirror extend --no-verify -N -f /mnt/testfs/victim_file \
+                    /mnt/testfs/file1
+# lfs getstripe /mnt/testfs/file1
+/mnt/testfs/file1
+  lcm_layout_gen:    3
+  lcm_mirror_count:  3
+  lcm_entry_count:   4
+    lcme_id:             65537
+    lcme_mirror_id:      1
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  1
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 0
+      lmm_pool:          flash
+      lmm_objects:
+      - 0: { l_ost_idx: 0, l_fid: [0x100000000:0x4:0x0] }
+
+    lcme_id:             131073
+    lcme_mirror_id:      2
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  6
+      lmm_stripe_size:   8388608
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 3
+      lmm_pool:          archive
+      lmm_objects:
+      - 0: { l_ost_idx: 3, l_fid: [0x100030000:0x3:0x0] }
+      - 1: { l_ost_idx: 4, l_fid: [0x100040000:0x4:0x0] }
+      - 2: { l_ost_idx: 5, l_fid: [0x100050000:0x4:0x0] }
+      - 3: { l_ost_idx: 6, l_fid: [0x100060000:0x4:0x0] }
+      - 4: { l_ost_idx: 7, l_fid: [0x100070000:0x4:0x0] }
+      - 5: { l_ost_idx: 2, l_fid: [0x100020000:0x3:0x0] }
+
+    lcme_id:             196609
+    lcme_mirror_id:      3
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   16777216
+      lmm_stripe_count:  2
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 5
+      lmm_objects:
+      - 0: { l_ost_idx: 5, l_fid: [0x100050000:0x5:0x0] }
+      - 1: { l_ost_idx: 6, l_fid: [0x100060000:0x5:0x0] }
+
+    lcme_id:             196610
+    lcme_mirror_id:      3
+    lcme_flags:          0
+    lcme_extent.e_start: 16777216
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  -1
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: -1</screen>
+      <para>After extending, the <replaceable>victim_file</replaceable> was
+        removed:</para>
+      <screen># ls /mnt/testfs/victim_file
+ls: cannot access /mnt/testfs/victim_file: No such file or directory</screen>
+    </section>
+    <section xml:id="flr.operations.splitmirror">
+      <title>Splitting a Mirrored File</title>
+      <para><emphasis role="strong">Command:</emphasis></para>
+      <screen>lfs mirror split &lt;--mirror-id &lt;mirror_id&gt;&gt;
+[--destroy|-d] [-f &lt;new_file&gt;] &lt;mirrored_file&gt;</screen>
+      <para>The above command will split a specified mirror with ID
+        <replaceable>&lt;mirror_id&gt;</replaceable> out of an existing mirrored
+        file specified by
+        <replaceable>mirrored_file</replaceable>. By default, a new file named
+        <literal>&lt;mirrored_file&gt;.mirror~&lt;mirror_id&gt;</literal> will
+        be created with the layout of the split mirror. If the
+        <literal>--destroy|-d</literal> option is specified, then the split
+        mirror will be destroyed. If the <literal>-f &lt;new_file&gt;</literal>
+        option is specified, then a file named
+        <replaceable>new_file</replaceable> will be created with the layout of
+        the split mirror. If <replaceable>mirrored_file</replaceable> has only
+        one mirror existing after split, it will be converted to a regular
+        non-mirrored file. If the original
+        <replaceable>mirrored_file</replaceable> is not a mirrored file, then
+        the command will return an error.</para>
+      <informaltable>
+        <tgroup cols="2">
+          <colspec align="left" />
+          <colspec align="left" />
+          <thead>
+            <row>
+              <entry>Option</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry>--mirror-id &lt;mirror_id&gt;</entry>
+              <entry>The unique numerical identifier for a mirror. The mirror
+                ID is unique within a mirrored file and is automatically
+                assigned at file creation or extension time. It can be fetched
+                by the <literal>lfs getstripe</literal> command.
+              </entry>
+            </row>
+            <row>
+              <entry>--destroy|-d</entry>
+              <entry>Indicates the split mirror will be destroyed.</entry>
+            </row>
+            <row>
+              <entry>-f &lt;new_file&gt;</entry>
+              <entry>Indicates a file named <replaceable>new_file</replaceable>
+                will be created with the layout of the split mirror.</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </informaltable>
+      <para><emphasis role="strong">Examples:</emphasis></para>
+      <para>The following commands create a mirrored file with 4 mirrors, then
+        split 3 mirrors separately from the mirrored file.</para>
+      <para>Creating a mirrored file with 4 mirrors:</para>
+      <screen># lfs mirror create -N2 -E 4M -p flash -E eof -c -1 \
+                    -N2 -S 8M -c 2 -p archive /mnt/testfs/file1
+# lfs getstripe /mnt/testfs/file1
+/mnt/testfs/file1
+  lcm_layout_gen:    6
+  lcm_mirror_count:  4
+  lcm_entry_count:   6
+    lcme_id:             65537
+    lcme_mirror_id:      1
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   4194304
+      lmm_stripe_count:  1
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 1
+      lmm_pool:          flash
+      lmm_objects:
+      - 0: { l_ost_idx: 1, l_fid: [0x100010000:0x4:0x0] }
+
+    lcme_id:             65538
+    lcme_mirror_id:      1
+    lcme_flags:          0
+    lcme_extent.e_start: 4194304
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  2
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: -1
+      lmm_pool:          flash
+
+    lcme_id:             131075
+    lcme_mirror_id:      2
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   4194304
+      lmm_stripe_count:  1
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 0
+      lmm_pool:          flash
+      lmm_objects:
+      - 0: { l_ost_idx: 0, l_fid: [0x100000000:0x5:0x0] }
+
+    lcme_id:             131076
+    lcme_mirror_id:      2
+    lcme_flags:          0
+    lcme_extent.e_start: 4194304
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  2
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: -1
+      lmm_pool:          flash
+
+    lcme_id:             196613
+    lcme_mirror_id:      3
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  2
+      lmm_stripe_size:   8388608
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 4
+      lmm_pool:          archive
+      lmm_objects:
+      - 0: { l_ost_idx: 4, l_fid: [0x100040000:0x5:0x0] }
+      - 1: { l_ost_idx: 5, l_fid: [0x100050000:0x6:0x0] }
+
+    lcme_id:             262150
+    lcme_mirror_id:      4
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  2
+      lmm_stripe_size:   8388608
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 7
+      lmm_pool:          archive
+      lmm_objects:
+      - 0: { l_ost_idx: 7, l_fid: [0x100070000:0x5:0x0] }
+      - 1: { l_ost_idx: 2, l_fid: [0x100020000:0x4:0x0] }</screen>
+      <para>Splitting the mirror with ID <literal>1</literal> from
+        <literal>/mnt/testfs/file1</literal> and creating
+        <literal>/mnt/testfs/file1.mirror~1</literal> with the layout of the
+        split mirror:</para>
+      <screen># lfs mirror split --mirror-id 1 /mnt/testfs/file1
+# lfs getstripe /mnt/testfs/file1.mirror~1
+/mnt/testfs/file1.mirror~1
+  lcm_layout_gen:    1
+  lcm_mirror_count:  1
+  lcm_entry_count:   2
+    lcme_id:             65537
+    lcme_mirror_id:      1
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   4194304
+      lmm_stripe_count:  1
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 1
+      lmm_pool:          flash
+      lmm_objects:
+      - 0: { l_ost_idx: 1, l_fid: [0x100010000:0x4:0x0] }
+
+    lcme_id:             65538
+    lcme_mirror_id:      1
+    lcme_flags:          0
+    lcme_extent.e_start: 4194304
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  2
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: -1
+      lmm_pool:          flash</screen>
+      <para>Splitting the mirror with ID <literal>2</literal> from
+        <literal>/mnt/testfs/file1</literal> and destroying it:</para>
+      <screen># lfs mirror split --mirror-id 2 -d /mnt/testfs/file1
+# lfs getstripe /mnt/testfs/file1
+/mnt/testfs/file1
+  lcm_layout_gen:    8
+  lcm_mirror_count:  2
+  lcm_entry_count:   2
+    lcme_id:             196613
+    lcme_mirror_id:      3
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  2
+      lmm_stripe_size:   8388608
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 4
+      lmm_pool:          archive
+      lmm_objects:
+      - 0: { l_ost_idx: 4, l_fid: [0x100040000:0x5:0x0] }
+      - 1: { l_ost_idx: 5, l_fid: [0x100050000:0x6:0x0] }
+
+    lcme_id:             262150
+    lcme_mirror_id:      4
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  2
+      lmm_stripe_size:   8388608
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 7
+      lmm_pool:          archive
+      lmm_objects:
+      - 0: { l_ost_idx: 7, l_fid: [0x100070000:0x5:0x0] }
+      - 1: { l_ost_idx: 2, l_fid: [0x100020000:0x4:0x0] }</screen>
+      <para>Splitting the mirror with ID <literal>3</literal> from
+        <literal>/mnt/testfs/file1</literal> and creating
+        <literal>/mnt/testfs/file2</literal> with the layout of the split
+        mirror:</para>
+      <screen># lfs mirror split --mirror-id 3 -f /mnt/testfs/file2 \
+                   /mnt/testfs/file1
+# lfs getstripe /mnt/testfs/file2
+/mnt/testfs/file2
+  lcm_layout_gen:    1
+  lcm_mirror_count:  1
+  lcm_entry_count:   1
+    lcme_id:             196613
+    lcme_mirror_id:      3
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  2
+      lmm_stripe_size:   8388608
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 4
+      lmm_pool:          archive
+      lmm_objects:
+      - 0: { l_ost_idx: 4, l_fid: [0x100040000:0x5:0x0] }
+      - 1: { l_ost_idx: 5, l_fid: [0x100050000:0x6:0x0] }
+
+# lfs getstripe /mnt/testfs/file1
+/mnt/testfs/file1
+  lcm_layout_gen:    9
+  lcm_mirror_count:  1
+  lcm_entry_count:   1
+    lcme_id:             262150
+    lcme_mirror_id:      4
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  2
+      lmm_stripe_size:   8388608
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 7
+      lmm_pool:          archive
+      lmm_objects:
+      - 0: { l_ost_idx: 7, l_fid: [0x100070000:0x5:0x0] }
+      - 1: { l_ost_idx: 2, l_fid: [0x100020000:0x4:0x0] }</screen>
+      <para>The above layout information showed that mirrors with ID
+        <literal>1, 2, and 3</literal> were all split from the mirrored file
+        <literal>/mnt/testfs/file1</literal>.</para>
+    </section>
+    <section xml:id="flr.operations.resyncmirror">
+      <title>Resynchronizing out-of-sync Mirrored File(s)</title>
+      <para><emphasis role="strong">Command:</emphasis></para>
+      <screen>lfs mirror resync [--only &lt;mirror_id[,...]&gt;]
+&lt;mirrored_file&gt; [&lt;mirrored_file2&gt;...]</screen>
+      <para>The above command will resynchronize out-of-sync mirrored file(s)
+        specified by <replaceable>mirrored_file</replaceable>. It
+        supports specifying multiple mirrored files in one command line.</para>
+      <para>If there is no stale mirror for the specified mirrored file(s), then
+        the command does nothing. Otherwise, it will copy data from synced
+        mirror to the stale mirror(s), and mark all successfully copied
+        mirror(s) as SYNC. If the
+        <literal>--only &lt;mirror_id[,...]&gt;</literal> option is specified,
+        then the command will only resynchronize the mirror(s) specified by the
+        <replaceable>mirror_id(s)</replaceable>. This option cannot be used when
+        multiple mirrored files are specified.</para>
+      <informaltable>
+        <tgroup cols="2">
+          <colspec align="left" />
+          <colspec align="left" />
+          <thead>
+            <row>
+              <entry>Option</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry>--only &lt;mirror_id[,...]&gt;</entry>
+              <entry>Indicates which mirror(s) specified by
+                <replaceable>mirror_id(s)</replaceable> needs to be
+                resynchronized. The <replaceable>mirror_id</replaceable> is the
+                unique numerical identifier for a mirror. Multiple
+                <replaceable>mirror_ids</replaceable> are separated by comma.
+                This option cannot be used when multiple mirrored files are
+                specified.</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </informaltable>
+      <para><emphasis role="strong">Note:</emphasis>  With delayed write
+        implemented in FLR phase 1, after writing to a mirrored file, users
+        need to run <literal>lfs mirror resync</literal> command to get all
+        mirrors synchronized.</para>
+      <para><emphasis role="strong">Examples:</emphasis></para>
+      <para>The following commands create a mirrored file with 3 mirrors, then
+        write some data into the file and resynchronizes stale mirrors.</para>
+      <para>Creating a mirrored file with 3 mirrors:</para>
+      <screen># lfs mirror create -N -E 4M -p flash -E eof \
+                    -N2 -p archive /mnt/testfs/file1
+# lfs getstripe /mnt/testfs/file1
+/mnt/testfs/file1
+  lcm_layout_gen:    4
+  lcm_mirror_count:  3
+  lcm_entry_count:   4
+    lcme_id:             65537
+    lcme_mirror_id:      1
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   4194304
+      lmm_stripe_count:  1
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 1
+      lmm_pool:          flash
+      lmm_objects:
+      - 0: { l_ost_idx: 1, l_fid: [0x100010000:0x5:0x0] }
+
+    lcme_id:             65538
+    lcme_mirror_id:      1
+    lcme_flags:          0
+    lcme_extent.e_start: 4194304
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  1
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: -1
+      lmm_pool:          flash
+
+    lcme_id:             131075
+    lcme_mirror_id:      2
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  1
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 3
+      lmm_pool:          archive
+      lmm_objects:
+      - 0: { l_ost_idx: 3, l_fid: [0x100030000:0x4:0x0] }
+
+    lcme_id:             196612
+    lcme_mirror_id:      3
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+      lmm_stripe_count:  1
+      lmm_stripe_size:   1048576
+      lmm_pattern:       raid0
+      lmm_layout_gen:    0
+      lmm_stripe_offset: 4
+      lmm_pool:          archive
+      lmm_objects:
+      - 0: { l_ost_idx: 4, l_fid: [0x100040000:0x6:0x0] }</screen>
+      <para>Writing some data into the mirrored file
+        <literal>/mnt/testfs/file1</literal>:</para>
+      <screen># yes | dd of=/mnt/testfs/file1 bs=1M count=2
+2+0 records in
+2+0 records out
+2097152 bytes (2.1 MB) copied, 0.0320613 s, 65.4 MB/s
+
+# lfs getstripe /mnt/testfs/file1
+/mnt/testfs/file1
+  lcm_layout_gen:    5
+  lcm_mirror_count:  3
+  lcm_entry_count:   4
+    lcme_id:             65537
+    lcme_mirror_id:      1
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   4194304
+    ......
+
+    lcme_id:             65538
+    lcme_mirror_id:      1
+    lcme_flags:          0
+    lcme_extent.e_start: 4194304
+    lcme_extent.e_end:   EOF
+    ......
+
+    lcme_id:             131075
+    lcme_mirror_id:      2
+    lcme_flags:          init,stale
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+    ......
+
+    lcme_id:             196612
+    lcme_mirror_id:      3
+    lcme_flags:          init,stale
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+    ......
+</screen>
+      <para>The above layout information showed that data were written into the
+        first component of mirror with ID <literal>1</literal>, and mirrors with
+        ID <literal>2</literal> and <literal>3</literal> were marked with
+        “stale” flag.</para>
+      <para>Resynchronizing the stale mirror with ID <literal>2</literal> for
+        the mirrored file <literal>/mnt/testfs/file1</literal>:</para>
+      <screen># lfs mirror resync --only 2 /mnt/testfs/file1
+# lfs getstripe /mnt/testfs/file1
+/mnt/testfs/file1
+  lcm_layout_gen:    7
+  lcm_mirror_count:  3
+  lcm_entry_count:   4
+    lcme_id:             65537
+    lcme_mirror_id:      1
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   4194304
+    ......
+
+    lcme_id:             65538
+    lcme_mirror_id:      1
+    lcme_flags:          0
+    lcme_extent.e_start: 4194304
+    lcme_extent.e_end:   EOF
+    ......
+
+    lcme_id:             131075
+    lcme_mirror_id:      2
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+    ......
+
+    lcme_id:             196612
+    lcme_mirror_id:      3
+    lcme_flags:          init,stale
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+    ......
+</screen>
+      <para>The above layout information showed that after resynchronizing, the
+        “stale” flag was removed from mirror with ID <literal>2</literal>.</para>
+      <para>Resynchronizing all of the stale mirrors for the mirrored file
+        <literal>/mnt/testfs/file1</literal>:</para>
+      <screen># lfs mirror resync /mnt/testfs/file1
+# lfs getstripe /mnt/testfs/file1
+/mnt/testfs/file1
+  lcm_layout_gen:    9
+  lcm_mirror_count:  3
+  lcm_entry_count:   4
+    lcme_id:             65537
+    lcme_mirror_id:      1
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   4194304
+    ......
+
+    lcme_id:             65538
+    lcme_mirror_id:      1
+    lcme_flags:          0
+    lcme_extent.e_start: 4194304
+    lcme_extent.e_end:   EOF
+    ......
+
+    lcme_id:             131075
+    lcme_mirror_id:      2
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+    ......
+
+    lcme_id:             196612
+    lcme_mirror_id:      3
+    lcme_flags:          init
+    lcme_extent.e_start: 0
+    lcme_extent.e_end:   EOF
+    ......
+</screen>
+      <para>The above layout information showed that after resynchronizing, none
+        of the mirrors were marked as stale.</para>
+    </section>
+    <section xml:id="flr.operations.verifymirror">
+      <title>Verifying Mirrored File(s)</title>
+      <para><emphasis role="strong">Command:</emphasis></para>
+      <screen>lfs mirror verify [--only &lt;mirror_id,mirror_id2[,...]&gt;]
+[--verbose|-v] &lt;mirrored_file&gt; [&lt;mirrored_file2&gt; ...]</screen>
+      <para>The above command will verify that each SYNC mirror (contains
+        up-to-date data) of a mirrored file, specified by
+        <replaceable>mirrored_file</replaceable>, has exactly the same data.  It
+        supports specifying multiple mirrored files in one command line.</para>
+      <para>This is a scrub tool that should be run on regular basis to make
+        sure that mirrored files are not corrupted. The command won't repair the
+        file if it turns out to be corrupted. Usually, an administrator should
+        check the file content from each mirror and decide which one is correct
+        and then invoke <literal>lfs mirror resync</literal> to repair it
+        manually.</para>
+      <informaltable>
+        <tgroup cols="2">
+          <colspec align="left" />
+          <colspec align="left" />
+          <thead>
+            <row>
+              <entry>Option</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry>--only &lt;mirror_id,mirror_id2[,...]&gt;</entry>
+              <entry><para>Indicates which mirrors specified by
+                <replaceable>mirror_ids</replaceable> need to be verified. The
+                <replaceable>mirror_id</replaceable> is the unique numerical
+                identifier for a mirror. Multiple
+                <replaceable>mirror_ids</replaceable> are separated by comma.
+                </para>
+                <para>Note: At least two <replaceable>mirror_ids</replaceable>
+                  are required. This option cannot be used when multiple
+                  mirrored files are specified.</para>
+              </entry>
+            </row>
+            <row>
+              <entry>--verbose|-v</entry>
+              <entry>Indicates the command will print where the differences are
+                if the data do not match. Otherwise, the command will just
+                return an error in that case. This option can be repeated for
+                multiple times to print more information.</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </informaltable>
+      <para><emphasis role="strong">Note:</emphasis></para>
+      <para>Mirror components that have “stale” or “offline” flags will be
+        skipped and not verified.</para>
+      <para><emphasis role="strong">Examples:</emphasis></para>
+      <para>The following command verifies that each mirror of a mirrored file
+        contains exactly the same data:</para>
+      <screen># lfs mirror verify /mnt/testfs/file1</screen>
+      <para>The following command has the <literal>-v</literal> option specified
+        to print where the differences are if the data does not match:</para>
+      <screen># lfs mirror verify -vvv /mnt/testfs/file2
+Chunks to be verified in /mnt/testfs/file2:
+[0, 0x200000)   [1, 2, 3, 4]    4
+[0x200000, 0x400000)    [1, 2, 3, 4]    4
+[0x400000, 0x600000)    [1, 2, 3, 4]    4
+[0x600000, 0x800000)    [1, 2, 3, 4]    4
+[0x800000, 0xa00000)    [1, 2, 3, 4]    4
+[0xa00000, 0x1000000)   [1, 2, 3, 4]    4
+[0x1000000, 0xffffffffffffffff) [1, 2, 3, 4]    4
+
+Verifying chunk [0, 0x200000) on mirror: 1 2 3 4
+CRC-32 checksum value for chunk [0, 0x200000):
+Mirror 1:       0x207b02f1
+Mirror 2:       0x207b02f1
+Mirror 3:       0x207b02f1
+Mirror 4:       0x207b02f1
+
+Verifying chunk [0, 0x200000) on mirror: 1 2 3 4 PASS
+
+Verifying chunk [0x200000, 0x400000) on mirror: 1 2 3 4
+CRC-32 checksum value for chunk [0x200000, 0x400000):
+Mirror 1:       0x207b02f1
+Mirror 2:       0x207b02f1
+Mirror 3:       0x207b02f1
+Mirror 4:       0x207b02f1
+
+Verifying chunk [0x200000, 0x400000) on mirror: 1 2 3 4 PASS
+
+Verifying chunk [0x400000, 0x600000) on mirror: 1 2 3 4
+CRC-32 checksum value for chunk [0x400000, 0x600000):
+Mirror 1:       0x42571b66
+Mirror 2:       0x42571b66
+Mirror 3:       0x42571b66
+Mirror 4:       0xabdaf92
+
+lfs mirror verify: chunk [0x400000, 0x600000) has different
+checksum value on mirror 1 and mirror 4.
+Verifying chunk [0x600000, 0x800000) on mirror: 1 2 3 4
+CRC-32 checksum value for chunk [0x600000, 0x800000):
+Mirror 1:       0x1f8ad0d8
+Mirror 2:       0x1f8ad0d8
+Mirror 3:       0x1f8ad0d8
+Mirror 4:       0x18975bf9
+
+lfs mirror verify: chunk [0x600000, 0x800000) has different
+checksum value on mirror 1 and mirror 4.
+Verifying chunk [0x800000, 0xa00000) on mirror: 1 2 3 4
+CRC-32 checksum value for chunk [0x800000, 0xa00000):
+Mirror 1:       0x69c17478
+Mirror 2:       0x69c17478
+Mirror 3:       0x69c17478
+Mirror 4:       0x69c17478
+
+Verifying chunk [0x800000, 0xa00000) on mirror: 1 2 3 4 PASS
+
+lfs mirror verify: '/mnt/testfs/file2' chunk [0xa00000, 0x1000000]
+exceeds file size 0xa00000: skipped</screen>
+      <para>The following command uses the <literal>--only</literal> option to
+        only verify the specified mirrors:</para>
+      <screen># lfs mirror verify -v --only 1,4 /mnt/testfs/file2
+CRC-32 checksum value for chunk [0, 0x200000):
+Mirror 1:       0x207b02f1
+Mirror 4:       0x207b02f1
+
+CRC-32 checksum value for chunk [0x200000, 0x400000):
+Mirror 1:       0x207b02f1
+Mirror 4:       0x207b02f1
+
+CRC-32 checksum value for chunk [0x400000, 0x600000):
+Mirror 1:       0x42571b66
+Mirror 4:       0xabdaf92
+
+lfs mirror verify: chunk [0x400000, 0x600000) has different
+checksum value on mirror 1 and mirror 4.
+CRC-32 checksum value for chunk [0x600000, 0x800000):
+Mirror 1:       0x1f8ad0d8
+Mirror 4:       0x18975bf9
+
+lfs mirror verify: chunk [0x600000, 0x800000) has different
+checksum value on mirror 1 and mirror 4.
+CRC-32 checksum value for chunk [0x800000, 0xa00000):
+Mirror 1:       0x69c17478
+Mirror 4:       0x69c17478
+
+lfs mirror verify: '/mnt/testfs/file2' chunk [0xa00000, 0x1000000]
+exceeds file size 0xa00000: skipped</screen>
+    </section>
+    <section xml:id="flr.operations.findingmirror">
+      <title>Finding Mirrored File(s)</title>
+      <para>The <literal>lfs find</literal> command is used to list files and
+        directories with specific attributes. The following two attribute
+        parameters are specific to a mirrored file or directory:</para>
+      <screen>lfs find &lt;directory|filename ...&gt;
+    [[!] --mirror-count|-N [+-]n]
+    [[!] --mirror-state &lt;[^]state&gt;]</screen>
+      <informaltable>
+        <tgroup cols="2">
+          <colspec align="left" />
+          <colspec align="left" />
+          <thead>
+            <row>
+              <entry>Option</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry>--mirror-count|-N [+-]n</entry>
+              <entry>Indicates mirror count.</entry>
+            </row>
+            <row>
+              <entry>--mirror-state &lt;[^]state&gt;</entry>
+              <entry>
+                <para>Indicates mirrored file state.</para>
+                <para>If <replaceable>^state</replaceable> is used, print only
+                  files not matching <replaceable>state</replaceable>. Only one
+                  state can be specified.</para>
+                <para>Valid state names are:</para>
+                <para><literal>ro</literal> – indicates the mirrored file is in
+                  read-only state. All of the mirrors contain the up-to-date
+                  data.</para>
+                <para><literal>wp</literal> – indicates the mirrored file is in
+                  a state of being written.</para>
+                <para><literal>sp</literal> – indicates the mirrored file is in
+                  a state of being resynchronized.</para>
+              </entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </informaltable>
+      <para><emphasis role="strong">Note:</emphasis></para>
+      <para>Specifying <literal>!</literal> before an option negates its meaning
+        (files NOT matching the parameter). Using <literal>+</literal> before a
+        numeric value means 'more than n', while <literal>-</literal> before a
+        numeric value means 'less than n'. If neither is used, it means
+        'equal to n', within the bounds of the unit specified (if any).</para>
+      <para><emphasis role="strong">Examples:</emphasis></para>
+      <para>The following command recursively lists all mirrored files that have
+        more than 2 mirrors under directory <literal>/mnt/testfs</literal>:
+      </para>
+      <screen># lfs find --mirror-count +2 --type f /mnt/testfs</screen>
+      <para>The following command recursively lists all out-of-sync mirrored
+        files under directory <literal>/mnt/testfs</literal>:</para>
+      <screen># lfs find --mirror-state=^ro --type f /mnt/testfs</screen>
+    </section>
+  </section>
+  <section xml:id="flr.interop">
+    <title>Interoperability</title>
+    <para>Introduced in Lustre release 2.11.0, the FLR feature is based on the
+      <xref linkend="pfl"/> feature introduced in Lustre 2.10.0</para>
+    <para>For Lustre release 2.9 and older clients, which do not understand the
+      PFL layout, they cannot access and open mirrored files created in the
+      Lustre 2.11 filesystem.</para>
+    <para>The following example shows the errors returned by accessing and
+      opening a mirrored file (created in Lustre 2.11 filesystem) on a Lustre
+      2.9 client:</para>
+    <screen># ls /mnt/testfs/mirrored_file
+ls: cannot access /mnt/testfs/mirrored_file: Invalid argument
+
+# cat /mnt/testfs/mirrored_file
+cat: /mnt/testfs/mirrored_file: Operation not supported</screen>
+    <para>For Lustre release 2.10 clients, which understand the PFL layout, but
+      do not understand a mirrored layout, they can access mirrored files
+      created in Lustre 2.11 filesystem, however, they cannot open them. This is
+      because the Lustre 2.10 clients do not verify overlapping components so
+      they would read and write mirrored files just as if they were normal PFL
+      files, which will cause a problem where synced mirrors actually contain
+      different data.</para>
+    <para>The following example shows the results returned by accessing and
+      opening a mirrored file (created in Lustre 2.11 filesystem) on a Lustre
+      2.10 client:</para>
+    <screen># ls /mnt/testfs/mirrored_file
+/mnt/testfs/mirrored_file
+
+# cat /mnt/testfs/mirrored_file
+cat: /mnt/testfs/mirrored_file: Operation not supported</screen>
+  </section>
+</chapter>
index 304e1d8..26b2392 100644 (file)
@@ -95,6 +95,7 @@
     <xi:include href="BackupAndRestore.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
     <xi:include href="ManagingStripingFreeSpace.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
     <xi:include href="DataOnMDT.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="FileLevelRedundancy.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
     <xi:include href="ManagingFileSystemIO.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
     <xi:include href="ManagingFailover.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
     <xi:include href="ConfiguringQuotas.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
diff --git a/figures/FLR_DelayedWrite.png b/figures/FLR_DelayedWrite.png
new file mode 100644 (file)
index 0000000..0f436cd
Binary files /dev/null and b/figures/FLR_DelayedWrite.png differ