Skip to content

Repository files navigation

liberasurecode

liberasurecode is an Erasure Code API library written in C with pluggable Erasure Code backends.


Highlights

  • Unified Erasure Coding interface for common storage workloads.

  • Pluggable Erasure Code backends - As of v1.0, liberasurecode supports the following backends:

    • 'Jerasure' - Erasure Coding library that supports Reed-Solomon, Cauchy backends [1]
    • 'ISA-L' - Intel Storage Acceleration Library - SIMD accelerated Erasure Coding backends [2]
    • 'SHSS' - NTT Lab Japan's hybrid Erasure Coding backend [4]
    • 'Flat XOR HD' - built-in to liberasurecode, based on [3]
    • 'NULL' template backend implemented to help future backend writers
  • True 'plugin' architecture - liberasurecode uses Dynamically Loaded (DL) libraries to realize a true 'plugin' architecture. This also allows one to build liberasurecode indepdendent of the Erasure Code backend libraries.

  • Cross-platform - liberasurecode is known to work on Linux (Fedora/Debian flavors), Solaris, BSD and Darwin/Mac OS X.

  • Community support - Developed alongside Erasure Code authority Kevin Greenan, liberasurecode is an actively maintained open-source project with growing community involvement (Openstack Swift, Ceph, PyECLib).


License

liberasurecode is distributed under the terms of the BSD license.


Active Users


liberasurecode API Definition

/* liberasurecode frontend API functions *//** * Create a liberasurecode instance and return a descriptor  * for use with EC operations (encode, decode, reconstruct) * * @param id - one of the supported backends as * defined by ec_backend_id_t * @param ec_args - arguments to the EC backend * arguments common to all backends * k - number of data fragments * m - number of parity fragments * w - word size, in bits * hd - hamming distance (=m for Reed-Solomon) * ct - fragment checksum type (stored with the fragment metadata) * backend-specific arguments * null_args - arguments for the null backend * flat_xor_hd, jerasure do not require any special args *  * @return liberasurecode instance descriptor (int > 0) */intliberasurecode_instance_create(constec_backend_id_tid,
structec_args*args);
/** * Close a liberasurecode instance * * @param desc - liberasurecode descriptor to close * * @return 0 on success, otherwise non-zero error code */intliberasurecode_instance_destroy(intdesc);
/** * Erasure encode a data buffer * * @param desc - liberasurecode descriptor/handle * from liberasurecode_instance_create() * @param orig_data - data to encode * @param orig_data_size - length of data to encode * @param encoded_data - pointer to _output_ array (char **) of k data * fragments (char *), allocated by the callee * @param encoded_parity - pointer to _output_ array (char **) of m parity * fragments (char *), allocated by the callee * @param fragment_len - pointer to _output_ length of each fragment, assuming * all fragments are the same length * * @return 0 on success, -error code otherwise */intliberasurecode_encode(intdesc,
constchar*orig_data, uint64_torig_data_size, /* input */char***encoded_data, char***encoded_parity, /* output */uint64_t*fragment_len); /* output *//** * Cleanup structures allocated by librasurecode_encode * * The caller has no context, so cannot safely free memory * allocated by liberasurecode, so it must pass the * deallocation responsibility back to liberasurecode. * * @param desc - liberasurecode descriptor/handle * from liberasurecode_instance_create() * @param encoded_data - (char **) array of k data * fragments (char *), allocated by liberasurecode_encode * @param encoded_parity - (char **) array of m parity * fragments (char *), allocated by liberasurecode_encode * * @return 0 in success; -error otherwise */intliberasurecode_encode_cleanup(intdesc, char**encoded_data,
char**encoded_parity);
/** * Reconstruct original data from a set of k encoded fragments * * @param desc - liberasurecode descriptor/handle * from liberasurecode_instance_create() * @param fragments - erasure encoded fragments (> = k) * @param num_fragments - number of fragments being passed in * @param fragment_len - length of each fragment (assume they are the same) * @param force_metadata_checks - force fragment metadata checks (default: 0) * @param out_data - _output_ pointer to decoded data * @param out_data_len - _output_ length of decoded output * (both output data pointers are allocated by liberasurecode, * caller invokes liberasurecode_decode_clean() after it has * read decoded data in 'out_data') * * @return 0 on success, -error code otherwise */intliberasurecode_decode(intdesc,
char**available_fragments, /* input */intnum_fragments, uint64_tfragment_len, /* input */intforce_metadata_checks, /* input */char**out_data, uint64_t*out_data_len); /* output *//** * Cleanup structures allocated by librasurecode_decode * * The caller has no context, so cannot safely free memory * allocated by liberasurecode, so it must pass the * deallocation responsibility back to liberasurecode. * * @param desc - liberasurecode descriptor/handle * from liberasurecode_instance_create() * @param data - (char *) buffer of data decoded by librasurecode_decode * * @return 0 on success; -error otherwise */intliberasurecode_decode_cleanup(intdesc, char*data);
/** * Reconstruct a missing fragment from a subset of available fragments * * @param desc - liberasurecode descriptor/handle  * from liberasurecode_instance_create() * @param available_fragments - erasure encoded fragments * @param num_fragments - number of fragments being passed in * @param fragment_len - size in bytes of the fragments * @param destination_idx - missing idx to reconstruct * @param out_fragment - output of reconstruct * * @return 0 on success, -error code otherwise */intliberasurecode_reconstruct_fragment(intdesc,
char**available_fragments, /* input */intnum_fragments, uint64_tfragment_len, /* input */intdestination_idx, /* input */char*out_fragment); /* output *//** * Return a list of lists with valid rebuild indexes given * a list of missing indexes. * * @desc: liberasurecode instance descriptor (obtained with * liberasurecode_instance_create) * @fragments_to_reconstruct list of indexes to reconstruct * @fragments_to_exclude list of indexes to exclude from  * reconstruction equation * @fragments_needed list of fragments needed to reconstruct * fragments in fragments_to_reconstruct * * @return 0 on success, non-zero on error */intliberasurecode_fragments_needed(intdesc,
int*fragments_to_reconstruct, int*fragments_to_exclude,
int*fragments_needed);

Erasure Code Fragment Checksum Types Supported

/* Checksum types supported for fragment metadata stored in each fragment */typedefenum {
CHKSUM_NONE=0, /* "none" (default) */CHKSUM_CRC32=1, /* "crc32" */CHKSUM_TYPES_MAX,
} ec_checksum_type_t;

Erasure Code Fragment Checksum API

struct __attribute__((__packed__))
fragment_metadata
{
uint32_tidx; /* 4 */uint32_tsize; /* 4 */uint32_tfrag_backend_metadata_size; /* 4 */uint64_torig_data_size; /* 8 */uint8_tchksum_type; /* 1 */uint32_tchksum[LIBERASURECODE_MAX_CHECKSUM_LEN]; /* 32 */uint8_tchksum_mismatch; /* 1 */uint8_tbackend_id; /* 1 */uint32_tbackend_version; /* 4 */
} fragment_metadata_t;
#defineFRAGSIZE_2_BLOCKSIZE(fragment_size) \
(fragment_size - sizeof(fragment_header_t))
/** * Get opaque metadata for a fragment. The metadata is opaque to the * client, but meaningful to the underlying library. It is used to verify * stripes in verify_stripe_metadata(). * * @param fragment - fragment data pointer * @param fragment_metadata - pointer to allocated buffer of size at least * sizeof(struct fragment_metadata) to hold fragment metadata struct * * @return 0 on success, non-zero on error *///EDL: This needs to be implementedintliberasurecode_get_fragment_metadata(char*fragment,
fragment_metadata_t*fragment_metadata);
/*** Verify that the specified pointer points to a well formed fragment that can* be processed by both this instance of liberasurecode and the specified* backend.** @param desc - liberasurecode descriptor/handle* from liberasurecode_instance_create()* @param fragment - fragment to verify** @return 1 if fragment validation fails, 0 otherwise.*/intis_invalid_fragment(intdesc, char*fragment);
/** * Verify a subset of fragments generated by encode() * * @param desc - liberasurecode descriptor/handle * from liberasurecode_instance_create() * @param fragments - fragments part of the EC stripe to verify * @param num_fragments - number of fragments part of the EC stripe * * @return 1 if stripe checksum verification is successful, 0 otherwise */intliberasurecode_verify_stripe_metadata(intdesc,
char**fragments, intnum_fragments);
/* ==~=*=~===~=*=~==~=*=~== liberasurecode Helpers ==~*==~=*=~==~=~=*=~==~= *//** * This computes the aligned size of a buffer passed into  * the encode function. The encode function must pad fragments * to be algined with the word size (w) and the last fragment also * needs to be aligned. This computes the sum of the algined fragment * sizes for a given buffer to encode. * * @param desc - liberasurecode descriptor/handle * from liberasurecode_instance_create() * @param data_len - original data length in bytes * * @return aligned length, or -error code on error */intliberasurecode_get_aligned_data_size(intdesc, uint64_tdata_len);
/** * This will return the minimum encode size, which is the minimum * buffer size that can be encoded. *  * @param desc - liberasurecode descriptor/handle * from liberasurecode_instance_create() * * @return minimum data length length, or -error code on error */intliberasurecode_get_minimum_encode_size(intdesc);
/** * This will return the fragment size, which is each fragment data * length the backend will allocate when encoding. * * @param desc - liberasurecode descriptor/handle * from liberasurecode_instance_create() * @param data_len - original data length in bytes * * @return fragment size - sizeof(fragment_header) + size * + frag_backend_metadata_size */intliberasurecode_get_fragment_size(intdesc, intdata_len);

Build and Install

To build the liberasurecode repository, perform the following from the top-level directory:

 $ ./autogen.sh
$ ./configure
$ make
$ make test
$ sudo make install

Code organization

 |-- include
| +-- erasurecode
| | +-- erasurecode.h --> liberasurecode frontend API header
| | +-- erasurecode_backend.h --> liberasurecode backend API header
| +-- xor_codes --> headers for the built-in XOR codes
|
|-- src
| |-- erasurecode.c --> liberasurecode API implementation
| | (frontend + backend)
| |-- backends
| | +-- null
| | +--- null.c --> 'null' erasure code backend (template backend)
| | +-- xor
| | +--- flat_xor_hd.c --> 'flat_xor_hd' erasure code backend (built-in)
| | +-- jerasure | | +-- jerasure_rs_cauchy.c --> 'jerasure_rs_vand' erasure code backend (jerasure.org)
| | +-- jerasure_rs_vand.c --> 'jerasure_rs_cauchy' erasure code backend (jerasure.org)
| | +-- isa-l
| | +-- isa_l_rs_vand.c --> 'isa_l_rs_vand' erasure code backend (Intel)
| | +-- shss
| | +-- shss.c --> 'shss' erasure code backend (NTT Labs)
| |
| |-- builtin
| | +-- xor_codes --> XOR HD code backend, built-in erasure
| | | code implementation (shared library)
| | +-- xor_code.c
| | +-- xor_hd_code.c
| |
| +-- utils
| +-- chksum --> fragment checksum utils for erasure
| +-- alg_sig.c coded fragments
| +-- crc32.c
|
|-- doc --> API Documentation
| +-- Doxyfile
| +-- html
|
|--- test --> Test routines
| +-- builtin
| | +-- xor_codes
| +-- liberasurecode_test.c
| +-- utils
|
|-- autogen.sh
|-- configure.ac
|-- Makefile.am
|-- README
|-- NEWS
|-- COPYING
|-- AUTHORS
|-- INSTALL
+-- ChangeLog

References

[1] Jerasure, C library that supports erasure coding in storage applications, http://jerasure.org

[2] Intel(R) Storage Acceleration Library (Open Source Version), https://01.org/intel%C2%AE-storage-acceleration-library-open-source-version

[3] Greenan, Kevin M et al, "Flat XOR-based erasure codes in storage systems", http://www.kaymgee.com/Kevin_Greenan/Publications_files/greenan-msst10.pdf

[4] Kota Tsuyuzaki tsuyuzaki.kota@lab.ntt.co.jp, Ryuta Kon kon.ryuta@po.ntts.co.jp, "NTT SHSS Erasure Coding backend"

About

Erasure Code API library written in C with pluggable Erasure Code backends.

Resources

Stars

5 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages