forked from fohr/libcastle
-
Notifications
You must be signed in to change notification settings - Fork 0
/
castle.h
717 lines (647 loc) · 41.4 KB
/
castle.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
#ifndef __CASTLE_FRONT_H__
#define __CASTLE_FRONT_H__
#include <inttypes.h>
#include <stdio.h>
#include "castle_public.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CASTLE_NODE "/dev/castle-fs/control"
#ifdef SWIG
#define ONLY_INLINE
#elif defined __GNUC_STDC_INLINE__
#define ONLY_INLINE extern __inline__ __attribute__((__gnu_inline__))
#else
#define ONLY_INLINE extern __inline__
#endif
//#define TRACE
#ifdef TRACE
extern volatile unsigned long ops_counter;
extern volatile unsigned long selects_counter;
extern volatile unsigned long ioctls_counter;
#endif
/* deref the char buffer from a castle_buffer* */
#define CASTLE_BUF_GET(x) ((x)?(*(char**)(x)):(char*)NULL)
struct castle_front_connection;
struct s_castle_buffer
{
/* buf must be first member for CASTLE_BUF_GET macro */
char* buf;
const size_t buflen;
};
/* Type names are all over the place - create a consistent set of typedefs for the public API */
typedef struct castle_front_connection castle_connection;
typedef struct s_castle_buffer castle_buffer;
typedef c_vl_bkey_t castle_key;
typedef castle_request_t castle_request;
typedef castle_response_t castle_response;
typedef castle_interface_token_t castle_token;
typedef c_collection_id_t castle_collection;
typedef c_slave_uuid_t castle_slave_uuid;
typedef c_ver_t castle_version;
typedef c_da_t castle_da;
typedef c_env_var_t castle_env_var_id;
typedef void (*castle_callback) (castle_connection *connection,
castle_response *response, void *userdata);
struct castle_blocking_call
{
int completed;
int err;
uint64_t length;
castle_token token;
castle_user_timestamp_t user_timestamp; /**< See comments in castle_response_t. */
castle_resp_flags_t flags; /**< See comments in castle_response_t. */
};
int castle_shared_buffer_create (castle_connection *conn,
char **buffer,
unsigned long size) __attribute__((warn_unused_result));
int castle_shared_buffer_destroy (castle_connection *conn,
char *buffer,
unsigned long size);
int castle_shared_buffer_allocate (castle_connection *conn,
castle_buffer **buffer_out, unsigned long size) __attribute__((warn_unused_result));
int castle_shared_buffer_release (castle_connection *conn, castle_buffer* buffer);
int castle_connect (castle_connection **conn) __attribute__((warn_unused_result));
void castle_disconnect (castle_connection *conn);
void castle_free (castle_connection *conn);
int castle_fd (castle_connection *conn);
void castle_request_send (castle_connection *conn,
castle_request *req,
castle_callback *callbacks,
void **userdatas,
int reqs_count);
int castle_request_send_batch (castle_connection *conn,
castle_request *req,
castle_callback callback,
void *userdata,
int reqs_count);
int castle_request_do_blocking (castle_connection *conn,
castle_request *req,
struct castle_blocking_call *blocking_call);
int castle_request_do_blocking_multi(castle_connection *conn,
castle_request *req,
struct castle_blocking_call *blocking_call,
int count);
int castle_print_key(FILE *f, castle_key *key);
int castle_print_request(FILE *f, castle_request *req, int print_values);
int castle_print_response(FILE *f, castle_response *resp, int print_values);
extern void castle_replace_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, char *value, uint32_t value_len, uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_replace_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, char *value, uint32_t value_len, uint8_t flags) {
req->tag = CASTLE_RING_REPLACE;
req->flags = flags;
req->replace.collection_id = collection;
req->replace.key_ptr = key;
req->replace.key_len = key_len;
req->replace.value_ptr = value;
req->replace.value_len = value_len;
}
extern void castle_timestamped_replace_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, char *value, uint32_t value_len, castle_user_timestamp_t user_timestamp, uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_timestamped_replace_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, char *value, uint32_t value_len, castle_user_timestamp_t user_timestamp, uint8_t flags) {
req->tag = CASTLE_RING_TIMESTAMPED_REPLACE;
req->flags = flags;
req->timestamped_replace.collection_id = collection;
req->timestamped_replace.key_ptr = key;
req->timestamped_replace.key_len = key_len;
req->timestamped_replace.value_ptr = value;
req->timestamped_replace.value_len = value_len;
req->timestamped_replace.user_timestamp = user_timestamp;
}
extern void castle_counter_set_replace_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, char *value, uint32_t value_len, uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_counter_set_replace_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, char *value, uint32_t value_len, uint8_t flags) {
req->tag = CASTLE_RING_COUNTER_REPLACE;
req->flags = flags;
req->counter_replace.collection_id = collection;
req->counter_replace.key_ptr = key;
req->counter_replace.key_len = key_len;
req->counter_replace.value_ptr = value;
req->counter_replace.value_len = value_len;
req->counter_replace.add = CASTLE_COUNTER_TYPE_SET;
}
extern void castle_counter_add_replace_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, char *value, uint32_t value_len, uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_counter_add_replace_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, char *value, uint32_t value_len, uint8_t flags) {
req->tag = CASTLE_RING_COUNTER_REPLACE;
req->flags = flags;
req->counter_replace.collection_id = collection;
req->counter_replace.key_ptr = key;
req->counter_replace.key_len = key_len;
req->counter_replace.value_ptr = value;
req->counter_replace.value_len = value_len;
req->counter_replace.add = CASTLE_COUNTER_TYPE_ADD;
}
extern void castle_remove_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_remove_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, uint8_t flags) {
req->tag = CASTLE_RING_REMOVE;
req->flags = flags;
req->replace.collection_id = collection;
req->replace.key_ptr = key;
req->replace.key_len = key_len;
}
extern void castle_timestamped_remove_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, castle_user_timestamp_t user_timestamp, uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_timestamped_remove_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, castle_user_timestamp_t user_timestamp, uint8_t flags) {
req->tag = CASTLE_RING_TIMESTAMPED_REMOVE;
req->flags = flags;
req->timestamped_replace.collection_id = collection;
req->timestamped_replace.key_ptr = key;
req->timestamped_replace.key_len = key_len;
req->timestamped_replace.user_timestamp = user_timestamp;
}
/* CASTLE_BACK_GET */
extern void castle_get_prepare(castle_request *req,
castle_collection collection,
castle_key *key,
uint32_t key_len,
char *buffer,
uint32_t buffer_len,
uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_get_prepare(castle_request *req,
castle_collection collection,
castle_key *key,
uint32_t key_len,
char *buffer,
uint32_t buffer_len,
uint8_t flags)
{
req->tag = CASTLE_RING_GET;
req->flags = flags;
req->get.collection_id = collection;
req->get.key_ptr = key;
req->get.key_len = key_len;
req->get.value_ptr = buffer;
req->get.value_len = buffer_len;
}
/* CASTLE_BACK_ITER_START */
extern void castle_iter_start_prepare(castle_request *req,
castle_collection collection,
castle_key *start_key,
uint32_t start_key_len,
castle_key *end_key,
uint32_t end_key_len,
char *buffer,
uint32_t buffer_len,
uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_iter_start_prepare(castle_request *req,
castle_collection collection,
castle_key *start_key,
uint32_t start_key_len,
castle_key *end_key,
uint32_t end_key_len,
char *buffer,
uint32_t buffer_len,
uint8_t flags)
{
req->tag = CASTLE_RING_ITER_START;
req->flags = flags;
req->iter_start.collection_id = collection;
req->iter_start.start_key_ptr = start_key;
req->iter_start.start_key_len = start_key_len;
req->iter_start.end_key_ptr = end_key;
req->iter_start.end_key_len = end_key_len;
req->iter_start.buffer_ptr = buffer;
req->iter_start.buffer_len = buffer_len;
}
/* CASTLE_BACK_ITER_NEXT */
extern void castle_iter_next_prepare(castle_request *req,
castle_token token,
char *buffer,
uint32_t buffer_len,
uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_iter_next_prepare(castle_request *req,
castle_token token,
char *buffer,
uint32_t buffer_len,
uint8_t flags)
{
req->tag = CASTLE_RING_ITER_NEXT;
req->flags = flags;
req->iter_next.token = token;
req->iter_next.buffer_ptr = buffer;
req->iter_next.buffer_len = buffer_len;
}
/* CASTLE_BACK_ITER_FINISH */
extern void castle_iter_finish_prepare(castle_request *req,
castle_token token,
uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_iter_finish_prepare(castle_request *req,
castle_token token,
uint8_t flags) {
req->tag = CASTLE_RING_ITER_FINISH;
req->flags = flags;
req->iter_finish.token = token;
}
/* CASTLE_BACK_STREAM_IN_START */
extern void castle_stream_in_start_prepare(castle_request *req,
castle_collection collection,
uint64_t entries_count,
uint32_t medium_object_chunks,
uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_stream_in_start_prepare(castle_request *req,
castle_collection collection,
uint64_t entries_count,
uint32_t medium_object_chunks,
uint8_t flags)
{
req->tag = CASTLE_RING_STREAM_IN_START;
req->flags = flags;
req->stream_in_start.collection_id = collection;
req->stream_in_start.entries_count = entries_count;
req->stream_in_start.medium_object_chunks = medium_object_chunks;
}
/* CASTLE_BACK_ITER_NEXT */
extern void castle_stream_in_next_prepare(castle_request *req,
castle_token token,
char *buffer,
uint32_t buffer_len,
uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_stream_in_next_prepare(castle_request *req,
castle_token token,
char *buffer,
uint32_t buffer_len,
uint8_t flags)
{
req->tag = CASTLE_RING_STREAM_IN_NEXT;
req->flags = flags;
req->stream_in_next.token = token;
req->stream_in_next.buffer_ptr = buffer;
req->stream_in_next.buffer_len = buffer_len;
}
/* CASTLE_BACK_STREAM_IN_FINISH */
extern void castle_stream_in_finish_prepare(castle_request *req,
castle_token token,
uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_stream_in_finish_prepare(castle_request *req,
castle_token token,
uint8_t flags) {
req->tag = CASTLE_RING_STREAM_IN_FINISH;
req->flags = flags;
req->stream_in_finish.token = token;
req->stream_in_finish.abort = 0;
}
extern void castle_stream_in_abort_prepare(castle_request *req,
castle_token token,
uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_stream_in_abort_prepare(castle_request *req,
castle_token token,
uint8_t flags) {
req->tag = CASTLE_RING_STREAM_IN_FINISH;
req->flags = flags;
req->stream_in_finish.token = token;
req->stream_in_finish.abort = 1;
}
extern void castle_big_put_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, uint64_t value_len, uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_big_put_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, uint64_t value_len, uint8_t flags) {
req->tag = CASTLE_RING_BIG_PUT;
req->flags = flags;
req->big_put.collection_id = collection;
req->big_put.key_ptr = key;
req->big_put.key_len = key_len;
req->big_put.value_len = value_len;
}
extern void castle_timestamped_big_put_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, uint64_t value_len, castle_user_timestamp_t user_timestamp, uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_timestamped_big_put_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, uint64_t value_len, castle_user_timestamp_t user_timestamp, uint8_t flags) {
req->tag = CASTLE_RING_TIMESTAMPED_BIG_PUT;
req->flags = flags;
req->timestamped_big_put.collection_id = collection;
req->timestamped_big_put.key_ptr = key;
req->timestamped_big_put.key_len = key_len;
req->timestamped_big_put.value_len = value_len;
req->timestamped_big_put.user_timestamp = user_timestamp;
}
extern void castle_put_chunk_prepare(castle_request *req, castle_token token, char *buffer, uint32_t buffer_len, uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_put_chunk_prepare(castle_request *req, castle_token token, char *buffer, uint32_t buffer_len, uint8_t flags) {
req->tag = CASTLE_RING_PUT_CHUNK;
req->flags = flags;
req->put_chunk.token = token;
req->put_chunk.buffer_ptr = buffer;
req->put_chunk.buffer_len = buffer_len;
}
extern void castle_big_get_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_big_get_prepare(castle_request *req, castle_collection collection, castle_key *key, uint32_t key_len, uint8_t flags) {
req->tag = CASTLE_RING_BIG_GET;
req->flags = flags;
req->big_get.collection_id = collection;
req->big_get.key_ptr = key;
req->big_get.key_len = key_len;
}
extern void castle_get_chunk_prepare(castle_request *req, castle_token token, char *buffer, uint32_t buffer_len, uint8_t flags) __attribute__((always_inline));
ONLY_INLINE void castle_get_chunk_prepare(castle_request *req, castle_token token, char *buffer, uint32_t buffer_len, uint8_t flags) {
req->tag = CASTLE_RING_GET_CHUNK;
req->flags = flags;
req->get_chunk.token = token;
req->get_chunk.buffer_ptr = buffer;
req->get_chunk.buffer_len = buffer_len;
}
/* Assembles a castle_key at the given location, where buf_len is the
* number of bytes allocated, and dims/key_lens/keys are the
* parameters of the key. Returns zero on success, or the number of
* bytes needed to build the key if it won't fit in buf_len bytes.
*
* When invoked with key == NULL, buf_len == 0, or keys == NULL, only
* returns the necessary size
*
* When invoked with key_lens == NULL, uses strlen() to compute the lengths
*/
uint32_t castle_build_key(castle_key *key, size_t buf_len, int dims, const int *key_lens, const uint8_t * const*keys, const uint8_t *key_flags);
/* Variation on the theme, always returns the number of bytes needed. Success is when that value is <= buf_len. Mostly just here because java-castle wants it */
uint32_t castle_build_key_len(castle_key *key, size_t buf_len, int dims, const int *key_lens, const uint8_t * const*keys, const uint8_t *key_flags);
/* Returns the number of bytes needed for a key with these parameters */
uint32_t castle_key_bytes_needed(int dims, const int *key_lens, const uint8_t * const*keys, const uint8_t *key_flags) __attribute__((pure));
/* Convenience functions - some of these incur copies */
#if 0
/* Call as castle_alloca_key("foo") or castle_alloca_key("foo", "bar"). Likely to compile down to nothing. Only really useful when calling the convenience functions */
#define castle_alloca_key(...) ({ \
const char *ks[] = { __VA_ARGS__ }; \
uint32_t nr_dims = sizeof(ks) / sizeof(const char *); \
castle_key *bkey; \
\
key_len = castle_key_bytes_needed(nr_dims, NULL, (uint8_t **)ks, NULL); \
bkey = alloca(key_len); \
\
assert(castle_build_key(bkey, key_len, nr_dims, NULL, (uint8_t **)ks, NULL) != 0); \
bkey; })
#endif
castle_key *castle_malloc_key(int dims, const int *key_lens, const uint8_t * const*keys, const uint8_t *key_flags) __attribute__((malloc));
#define castle_key_length(_key) ( !(_key) ? 0 : ( (_key)->length + 4 ) )
extern uint32_t castle_key_dims(const castle_key *key) __attribute__((always_inline));
ONLY_INLINE uint32_t castle_key_dims(const castle_key *key) {
return key->nr_dims;
}
extern uint32_t castle_key_elem_len(const castle_key *key, int elem) __attribute__((always_inline));
ONLY_INLINE uint32_t castle_key_elem_len(const castle_key *key, int elem) {
return castle_object_btree_key_dim_length(key, (uint32_t)elem);
}
extern const uint8_t *castle_key_elem_data(const castle_key *key, int elem) __attribute__((always_inline));
ONLY_INLINE const uint8_t *castle_key_elem_data(const castle_key *key, int elem) {
return (uint8_t *)castle_object_btree_key_dim_get(key, (uint32_t)elem);
}
extern uint8_t castle_key_elem_flags(const castle_key *key, int elem) __attribute__((always_inline));
ONLY_INLINE uint8_t castle_key_elem_flags(const castle_key *key, int elem) {
return castle_object_btree_key_dim_flags_get(key, (uint32_t)elem);
}
int castle_key_copy (castle_key *key, void *buf, uint32_t key_len);
int castle_get (castle_connection *conn,
castle_collection collection,
castle_key *key,
char **value_out, uint32_t *value_len_out) __attribute__((warn_unused_result));
int castle_replace (castle_connection *conn,
castle_collection collection,
castle_key *key,
char *val, uint32_t val_len);
int castle_timestamped_replace(castle_connection *conn,
castle_collection collection,
castle_key *key,
char *val, uint32_t val_len,
castle_user_timestamp_t u_ts);
int castle_remove (castle_connection *conn,
castle_collection collection,
castle_key *key);
int castle_timestamped_remove(castle_connection *conn,
castle_collection collection,
castle_key *key,
castle_user_timestamp_t u_ts);
int castle_iter_start (castle_connection *conn,
castle_collection collection,
castle_key *start_key,
castle_key *end_key,
castle_token *token_out,
struct castle_key_value_list **kvs,
uint32_t buf_size,
int *more) __attribute__((warn_unused_result));
int castle_iter_next (castle_connection *conn,
castle_token token,
struct castle_key_value_list **kvs,
uint32_t buf_size,
int *more) __attribute__((warn_unused_result));
int castle_iter_finish (castle_connection *conn,
castle_token token);
int castle_getslice (castle_connection *conn,
castle_collection collection,
castle_key *start_key,
castle_key *end_key,
struct castle_key_value_list **kvs_out,
uint32_t limit) __attribute__((warn_unused_result));
void castle_kvs_free (struct castle_key_value_list *kvs_out);
int castle_big_put (castle_connection *conn,
castle_collection collection,
castle_key *key,
uint64_t val_length,
castle_token *token_out);
int castle_put_chunk (castle_connection *conn,
castle_token token,
char *value, uint32_t value_len);
int castle_big_get (castle_connection *conn,
castle_collection collection,
castle_key *key,
castle_token *token_out, uint64_t *value_len_out) __attribute__((warn_unused_result));
int castle_get_chunk (castle_connection *conn,
castle_token token,
char **value_out, uint32_t *value_len_out) __attribute__((warn_unused_result));
/* Control functions - ioctls */
#define C_TYPE_uint8 uint8_t
#define C_TYPE_uint32 uint32_t
#define C_TYPE_uint64 uint64_t
#define C_TYPE_slave_uuid castle_slave_uuid
#define C_TYPE_version castle_version
#define C_TYPE_size size_t
#define C_TYPE_string const char *
#define C_TYPE_collection_id castle_collection
#define C_TYPE_env_var castle_env_var_id
#define C_TYPE_int int
#define C_TYPE_int32 int32_t
#define C_TYPE_da_id_t castle_da
#define C_TYPE_merge_id_t c_merge_id_t
#define C_TYPE_thread_id_t c_thread_id_t
#define C_TYPE_work_id_t c_work_id_t
#define C_TYPE_work_size_t c_work_size_t
#define C_TYPE_pid pid_t
#define C_TYPE_c_da_opts_t c_da_opts_t
#define C_TYPE_c_state_t int
#define CASTLE_IOCTL_0IN_0OUT(_id, _name) \
int castle_##_id (castle_connection *conn);
#define CASTLE_IOCTL_0IN_1OUT(_id, _name, _ret_1_t, _ret) \
int castle_##_id (castle_connection *conn, C_TYPE_##_ret_1_t * _ret);
#define CASTLE_IOCTL_1IN_0OUT(_id, _name, _arg_1_t, _arg_1) \
int castle_##_id (castle_connection *conn, C_TYPE_##_arg_1_t _arg_1);
#define CASTLE_IOCTL_1IN_1OUT(_id, _name, _arg_1_t, _arg_1, _ret_1_t, _ret) \
int castle_##_id (castle_connection *conn, C_TYPE_##_arg_1_t _arg_1, \
C_TYPE_##_ret_1_t * _ret);
#define CASTLE_IOCTL_2IN_0OUT(_id, _name, _arg_1_t, _arg_1, _arg_2_t, _arg_2) \
int castle_##_id (castle_connection *conn, \
C_TYPE_##_arg_1_t _arg_1, C_TYPE_##_arg_2_t _arg_2); \
#define CASTLE_IOCTL_2IN_1OUT(_id, _name, _arg_1_t, _arg_1, _arg_2_t, _arg_2, _ret_1_t, _ret) \
int castle_##_id (castle_connection *conn, \
C_TYPE_##_arg_1_t _arg_1, C_TYPE_##_arg_2_t _arg_2, C_TYPE_##_ret_1_t * _ret);\
#define CASTLE_IOCTL_3IN_1OUT(_id, _name, \
_arg_1_t, _arg_1, _arg_2_t, _arg_2, _arg_3_t, _arg_3, \
_ret_1_t, _ret) \
int castle_##_id (castle_connection *conn, \
C_TYPE_##_arg_1_t _arg_1, C_TYPE_##_arg_2_t _arg_2, C_TYPE_##_arg_3_t _arg_3, \
C_TYPE_##_ret_1_t * _ret);
#define CASTLE_IOCTLS \
CASTLE_IOCTL_1IN_1OUT( \
claim, \
CASTLE_CTRL_CLAIM, \
uint32, dev, slave_uuid, id) \
CASTLE_IOCTL_1IN_1OUT( \
attach, \
CASTLE_CTRL_ATTACH, \
version, version, uint32, dev) \
CASTLE_IOCTL_1IN_0OUT( \
detach, \
CASTLE_CTRL_DETACH, \
uint32, dev) \
CASTLE_IOCTL_1IN_1OUT( \
snapshot, \
CASTLE_CTRL_SNAPSHOT, \
uint32, dev, version, version) \
CASTLE_IOCTL_3IN_1OUT( \
collection_attach, \
CASTLE_CTRL_COLLECTION_ATTACH, \
version, version, string, name, size, name_length, collection_id, collection) \
CASTLE_IOCTL_2IN_0OUT( \
collection_reattach, \
CASTLE_CTRL_COLLECTION_REATTACH, \
collection_id, collection, version, new_version) \
CASTLE_IOCTL_1IN_0OUT( \
collection_detach, \
CASTLE_CTRL_COLLECTION_DETACH, \
collection_id, collection) \
CASTLE_IOCTL_1IN_1OUT( \
collection_snapshot, \
CASTLE_CTRL_COLLECTION_SNAPSHOT, \
collection_id, collection, version, version) \
CASTLE_IOCTL_1IN_1OUT( \
create, \
CASTLE_CTRL_CREATE, \
uint64, size, version, id) \
CASTLE_IOCTL_2IN_1OUT( \
create_with_opts, \
CASTLE_CTRL_CREATE_WITH_OPTS, \
uint64, size, c_da_opts_t, opts, version, id) \
CASTLE_IOCTL_1IN_1OUT( \
clone, \
CASTLE_CTRL_CLONE, \
version, version, version, clone) \
CASTLE_IOCTL_1IN_0OUT( \
delete_version, \
CASTLE_CTRL_DELETE_VERSION, \
version, version) \
CASTLE_IOCTL_0IN_0OUT( \
init, \
CASTLE_CTRL_INIT) \
CASTLE_IOCTL_2IN_0OUT( \
fault, \
CASTLE_CTRL_FAULT, \
uint32, fault_id, uint32, fault_arg) \
CASTLE_IOCTL_2IN_0OUT( \
slave_evacuate, \
CASTLE_CTRL_SLAVE_EVACUATE, \
slave_uuid, id, uint32, force) \
CASTLE_IOCTL_1IN_0OUT( \
slave_scan, \
CASTLE_CTRL_SLAVE_SCAN, \
uint32, id) \
CASTLE_IOCTL_1IN_0OUT( \
thread_priority, \
CASTLE_CTRL_THREAD_PRIORITY, \
uint32, nice_value) \
CASTLE_IOCTL_1IN_0OUT( \
destroy_vertree, \
CASTLE_CTRL_DESTROY_VERTREE, \
da_id_t, vertree_id) \
CASTLE_IOCTL_0IN_1OUT( \
merge_thread_create, \
CASTLE_CTRL_MERGE_THREAD_CREATE, \
thread_id_t, thread_id) \
CASTLE_IOCTL_1IN_0OUT( \
merge_thread_destroy, \
CASTLE_CTRL_MERGE_THREAD_DESTROY, \
thread_id_t, thread_id) \
CASTLE_IOCTL_2IN_1OUT( \
merge_do_work, \
CASTLE_CTRL_MERGE_DO_WORK, \
merge_id_t, merge_id, work_size_t, work_size, work_id_t, work_id) \
CASTLE_IOCTL_1IN_0OUT( \
merge_stop, \
CASTLE_CTRL_MERGE_STOP, \
merge_id_t, merge_id) \
CASTLE_IOCTL_2IN_0OUT( \
merge_thread_attach, \
CASTLE_CTRL_MERGE_THREAD_ATTACH, \
merge_id_t, merge_id, thread_id_t, thread_id) \
CASTLE_IOCTL_2IN_0OUT( \
insert_rate_set, \
CASTLE_CTRL_INSERT_RATE_SET, \
da_id_t, vertree_id, uint32, insert_rate) \
CASTLE_IOCTL_2IN_0OUT( \
read_rate_set, \
CASTLE_CTRL_READ_RATE_SET, \
da_id_t, vertree_id, uint32, read_rate) \
CASTLE_IOCTL_0IN_0OUT( \
ctrl_prog_register, \
CASTLE_CTRL_PROG_REGISTER) \
CASTLE_IOCTL_1IN_1OUT( \
ctrl_prog_deregister, \
CASTLE_CTRL_PROG_DEREGISTER, \
uint8, shutdown, pid, pid) \
CASTLE_IOCTL_0IN_0OUT( \
ctrl_prog_heartbeat, \
CASTLE_CTRL_PROG_HEARTBEAT) \
CASTLE_IOCTL_2IN_0OUT( \
vertree_tdp_set, \
CASTLE_CTRL_VERTREE_TDP_SET, \
da_id_t, vertree_id, uint64, seconds) \
CASTLE_IOCTL_0IN_1OUT( \
state_query, \
CASTLE_CTRL_STATE_QUERY, \
c_state_t, state)
#define PRIVATE_CASTLE_IOCTLS \
CASTLE_IOCTL_3IN_1OUT( \
environment_set, \
CASTLE_CTRL_ENVIRONMENT_SET, \
env_var, var_id, string, var_str, size, var_len, int, ret) \
CASTLE_IOCTL_2IN_0OUT( \
trace_setup, \
CASTLE_CTRL_TRACE_SETUP, \
string, dir_str, size, dir_len) \
CASTLE_IOCTL_0IN_0OUT( \
trace_start, \
CASTLE_CTRL_TRACE_START) \
CASTLE_IOCTL_0IN_0OUT( \
trace_stop, \
CASTLE_CTRL_TRACE_STOP) \
CASTLE_IOCTL_0IN_0OUT( \
trace_teardown, \
CASTLE_CTRL_TRACE_TEARDOWN) \
CASTLE_IOCTLS
PRIVATE_CASTLE_IOCTLS
#undef CASTLE_IOCTL_0IN_0OUT
#undef CASTLE_IOCTL_1IN_0OUT
#undef CASTLE_IOCTL_0IN_1OUT
#undef CASTLE_IOCTL_1IN_1OUT
#undef CASTLE_IOCTL_2IN_0OUT
#undef CASTLE_IOCTL_2IN_1OUT
#undef CASTLE_IOCTL_3IN_1OUT
int castle_merge_start(struct castle_front_connection *conn, c_merge_cfg_t merge_cfg,
c_merge_id_t *merge_id);
uint32_t castle_device_to_devno(const char *filename);
const char *castle_devno_to_device(uint32_t devno);
/* Convenience methods which don't use the hated device number */
int castle_claim_dev(castle_connection *conn, const char *filename, castle_slave_uuid *id_out);
int castle_attach_dev(castle_connection *conn, castle_version version, const char **filename_out) __attribute__((warn_unused_result));
int castle_detach_dev(castle_connection *conn, const char *filename);
int castle_snapshot_dev(castle_connection *conn, const char *filename, castle_version *version_out);
uint32_t castle_max_buffer_size(void);
/* Shared buffer pool */
typedef struct s_castle_shared_pool castle_shared_pool;
int castle_shared_pool_create(castle_connection* conn, size_t nsizes, size_t* sizes, size_t* quantities, castle_shared_pool** pool_out);
int castle_shared_pool_destroy(castle_shared_pool* pool);
int castle_shared_pool_lease(castle_shared_pool* pool, castle_buffer** buffer_out, unsigned long size);
int castle_shared_pool_release(castle_shared_pool* pool, castle_buffer* buffer, unsigned long size);
/* Collection utils */
int castle_collection_find(const char* name, castle_collection* collection_out);
extern const char *castle_error_strings[CASTLE_ERROR_MAX_NUM+1];
const char *castle_error_code_to_str(int);
#ifdef __cplusplus
}
#endif
#endif /* __CASTLE_FRONT_H__ */