1 /*
2  * <Copyright>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice, this
11  * list of conditions and the following disclaimer in the documentation and/or
12  * other materials provided with the distribution.  THIS SOFTWARE IS PROVIDED BY
13  * THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
14  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
17  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
20  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
21  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * liberasurecode backend API definition
25  *
26  * vi: set noai tw=79 ts=4 sw=4:
27  */
28 
29 #ifndef _ERASURECODE_BACKEND_H_
30 #define _ERASURECODE_BACKEND_H_
31 
32 #include "list.h"
33 #include "erasurecode.h"
34 #include "erasurecode_stdinc.h"
35 
36 /* ~=*=~===~=*=~==~=*=~==~=*=~=  backend infrastructure =~=*=~==~=*=~==~=*=~ */
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 #if defined (__GNUC__) && __GNUC__ > 3
43 #define dl_restrict __restrict
44 #else
45 #define dl_restrict
46 #endif
47 
48 /* ==~=*=~===~=*=~==~=*=~==~=*=~= EC backend args =~==~=*=~==~=*=~===~=*=~== */
49 
50 /* Arguments passed to the backend */
51 #define MAX_PRIV_ARGS 4
52 struct ec_backend_args {
53     struct ec_args uargs;           /* common args passed in by the user */
54     void *pargs[MAX_PRIV_ARGS];     /* used for private backend args */
55 };
56 
57 /* =~===~=*=~==~=*=~==~=*=~=  backend stub definitions =~=*=~==~=*=~==~=*=~= */
58 
59 #define INIT            init
60 #define EXIT            exit
61 #define ENCODE          encode
62 #define DECODE          decode
63 #define FRAGSNEEDED     fragments_needed
64 #define RECONSTRUCT     reconstruct
65 #define ELEMENTSIZE     element_size
66 #define ISCOMPATIBLEWITH    is_compatible_with
67 
68 #define FN_NAME(s)      str(s)
69 #define str(s)          #s
70 
71 /* EC backend stubs - implemented per backend */
72 struct ec_backend_op_stubs {
73     /** Backend register/init, unregister/cleanup routines **/
74 
75     /* Private backend init routine */
76     void * (*INIT)(struct ec_backend_args *args, void *sohandle);
77 
78     /* Private backend cleanup routine */
79     int (*EXIT)(void *);
80 
81     /* Backend stub declarations */
82     int (*ENCODE)(void *desc,
83             char **data, char **parity, int blocksize);
84     int (*DECODE)(void *desc,
85             char **data, char **parity, int *missing_idxs, int blocksize);
86     int (*FRAGSNEEDED)(void *desc,
87             int *missing_idxs, int * fragments_to_exclude, int *fragments_needed);
88     int (*RECONSTRUCT)(void *desc,
89             char **data, char **parity, int *missing_idxs, int destination_idx,
90             int blocksize);
91     int (*ELEMENTSIZE)(void *desc);
92 
93     bool (*ISCOMPATIBLEWITH) (uint32_t version);
94 };
95 
96 /* ==~=*=~==~=*=~==~=*=~= backend struct definitions =~=*=~==~=*=~==~=*==~== */
97 
98 struct ec_backend_desc {
99     void *backend_desc;                             /* EC backend private descriptor */
100     void *backend_sohandle;                         /* EC backend shared lib handle */
101 };
102 
103 #define MAX_LEN     64
104 /* EC backend common attributes */
105 struct ec_backend_common {
106     ec_backend_id_t             id;                 /* EC backend type */
107     char                        name[MAX_LEN];      /* EC backend common name */
108     const char                  *soname;            /* EC backend shared library path */
109     char                        soversion[MAX_LEN]; /* EC backend shared library version */
110 
111     struct ec_backend_op_stubs  *ops;               /* EC backend stubs */
112     size_t                      backend_metadata_size;
113                                                     /* EC backend custom metadata size -
114                                                      * backend_metadata_size bytes are added to
115                                                      * the fragment size when allocating
116                                                      * data/parity fragment buffers */
117     uint32_t                    ec_backend_version; /* The revision number of this back
118                                                      * end. Is used to determine whether
119                                                      * a specific instance of this backend
120                                                      * accepts fragments generated by
121                                                      * another version */
122 };
123 
124 /* EC backend definition */
125 typedef struct ec_backend {
126     struct ec_backend_common    common;             /* EC backend common attributes */
127     struct ec_backend_args      args;               /* EC backend instance data (private) */
128 
129     int                         idesc;              /* liberasurecode instance handle */
130     struct ec_backend_desc      desc;               /* EC backend instance handle */
131 
132     SLIST_ENTRY(ec_backend)     link;
133 } *ec_backend_t;
134 
135 /* ~=*=~==~=*=~==~=*=~==~=*= frontend <-> backend API =*=~==~=*=~==~=*=~==~= */
136 
137 /* Register a backend instance with liberasurecode */
138 int liberasurecode_backend_instance_register(ec_backend_t instance);
139 
140 /* Unregister a backend instance */
141 int liberasurecode_backend_instance_unregister(ec_backend_t instance);
142 
143 
144 /* Generic dlopen/dlclose routines */
145 void* liberasurecode_backend_open(ec_backend_t instance);
146 int liberasurecode_backend_close(ec_backend_t instance);
147 
148 
149 /* Backend query interface */
150 
151 /* Name to ID mapping for EC backend */
152 ec_backend_id_t liberasurecode_backend_lookup_id(const char *name);
153 
154 /* Get EC backend by name */
155 ec_backend_t liberasurecode_backend_lookup_by_name(const char *name);
156 
157 /**
158  * Look up a backend instance by descriptor
159  *
160  * Returns pointer to a registered liberasurecode instance
161  * The caller must hold active_instances_rwlock
162  */
163 ec_backend_t liberasurecode_backend_instance_get_by_desc(int desc);
164 
165 /* =~=*=~==~=*=~==~=*=~==~=*=~===~=*=~==~=*=~===~=*=~==~=*=~===~=*=~==~=*=~= */
166 
167 #ifdef __cplusplus
168 }
169 #endif
170 
171 #endif  // _ERASURECODE_BACKEND_H_
172 
173