erasure-code: locally repairable code plugin

Recursively apply erasure code techniques so that recovering from the
loss of some chunks only require a subset of the available chunks, most
of the time.

http://tracker.ceph.com/issues/7238 Fixes: #7238

Signed-off-by: Loic Dachary <loic@dachary.org>
erasure-code: high level LRC configuration

Add a configuration mode to the LRC plugin, suitable for most use cases
and simpler to explain and understand. It uses k,m parameters similar to
the jerasure and isa plugins and adds l for locality. For instance:

   k=4 m=2 l=3
   ruleset_locality=rack
   ruleset_failure_domain=host

Will translate into

   local_group_count = (k+m)/l

   ruleset-steps = "["
    " [\"choose\", \"rack\", " + local_group_count + "], "
    " [\"chooseleaf\", \"host\", " + (l + 1) + "], "
    "]";

   layers = "[ "
      "  [ \"DDc_DDc_\", \"\" ],"
      "  [ \"DDDc____\", \"\" ],"
      "  [ \"____DDDc\", \"\" ],"
      "]";

It is less flexible because k+m must be a multiple of l and other
similar relationships and also because it cannot express recursive
configurations with locality in the datacenter and locality in a rack
within the datacenter.

Signed-off-by: Loic Dachary <loic@dachary.org>
erasure-code: test LRC pool, profile and crush ruleset

Using the command line to create an LRC pool validates that the plugin
can be loaded and the ruleset created immediately after the crush table
is populated with the default rulesets.

Add a test that takes out the first OSD holding data for an object and
checks the recovery is effective by retrieving the object content and
checking it is as expected.

Signed-off-by: Loic Dachary <loic@dachary.org>
erasure-code: LRC plugin documentation

Signed-off-by: Loic Dachary <loic-201408@dachary.org>
erasure-code: ECRecPred must be true if all chunks can be recovered

ECRecPred assumes recovering any number of chunk is possible as long as
at least K chunks are available. It builds the want() set accordingly in
the constructor and arbitrarily set the first K chunks. But it would be
the same if it set the last K chunks.

While this is correct for jerasure and isa plugins, it is not true in
general. The predicate should assume that all chunks are going to be
recovered and return true if they can all be recovered. Otherwise, the
following can happen:

  * a PG has chunks 0,1,2,3 for K=2, M=2
  * ECRecPred is initialized a set want to 0,1 because K=2
  * ECRecPred claims the plugin can recover when provided 0,1
  * the plugin is then required to recover 0,1 using 2,3 and fails

This can happen for the LRC plugin with k=4,m=2,l=3 which is

  01234567
  DDc_DDc_
  DDDc____
  ____DDDc

and if chunks 0,1,2,3 are missing there is no way to recover chunks
4,5,6,7.

Signed-off-by: Loic Dachary <loic-201408@dachary.org>