2 * 2008+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #ifndef __DNET_PACKET_H
17 #define __DNET_PACKET_H
21 #include <arpa/inet.h>
27 #include <elliptics/typedefs.h>
28 #include <elliptics/core.h>
37 DNET_CMD_LOOKUP
= 1, /* Lookup address by ID and per-object info: size, permissions and so on*/
38 DNET_CMD_REVERSE_LOOKUP
, /* Lookup ID by address */
39 DNET_CMD_JOIN
, /* Join the network - force remote nodes to update
40 * their route tables to include given node with given
44 DNET_CMD_READ
, /* IO commands. They have to follow by the
45 * IO attribute which will have offset and size
48 DNET_CMD_LIST
, /* List all objects for given node ID */
49 DNET_CMD_EXEC
, /* Execute given command on the remote node */
50 DNET_CMD_ROUTE_LIST
, /* Receive route table from given node */
51 DNET_CMD_STAT
, /* Gather remote VM, LA and FS statistics */
52 DNET_CMD_NOTIFY
, /* Notify when object in question was modified */
53 DNET_CMD_DEL
, /* Remove given object from the storage */
54 DNET_CMD_STAT_COUNT
, /* Gather remote per-cmd statistics */
55 DNET_CMD_STATUS
, /* Change elliptics node status */
56 DNET_CMD_READ_RANGE
, /* Read range of objects */
57 DNET_CMD_DEL_RANGE
, /* Remove range of objects */
58 DNET_CMD_AUTH
, /* Authentification cookie check */
59 DNET_CMD_BULK_READ
, /* Read a number of ids at one time */
61 DNET_CMD_UNKNOWN
, /* This slot is allocated for statistics gathered for unknown commands */
66 DNET_CNTR_LA1
= __DNET_CMD_MAX
*2, /* Load average for 1 min */
67 DNET_CNTR_LA5
, /* Load average for 5 min */
68 DNET_CNTR_LA15
, /* Load average for 15 min */
69 DNET_CNTR_BSIZE
, /* Block size */
70 DNET_CNTR_FRSIZE
, /* Fragment size */
71 DNET_CNTR_BLOCKS
, /* Filesystem size in frsize units */
72 DNET_CNTR_BFREE
, /* # free blocks */
73 DNET_CNTR_BAVAIL
, /* # free blocks for non-root */
74 DNET_CNTR_FILES
, /* # inodes */
75 DNET_CNTR_FFREE
, /* # free inodes */
76 DNET_CNTR_FAVAIL
, /* # free inodes for non-root */
77 DNET_CNTR_FSID
, /* File system ID */
78 DNET_CNTR_VM_ACTIVE
, /* Active memory */
79 DNET_CNTR_VM_INACTIVE
, /* Inactive memory */
80 DNET_CNTR_VM_TOTAL
, /* Total memory */
81 DNET_CNTR_VM_FREE
, /* Free memory */
82 DNET_CNTR_VM_CACHED
, /* Used for cache */
83 DNET_CNTR_VM_BUFFERS
, /* Used for buffers */
84 DNET_CNTR_NODE_FILES
, /* # files in meta */
85 DNET_CNTR_NODE_LAST_MERGE
, /* Result of the last merge */
86 DNET_CNTR_NODE_CHECK_COPY
, /* Result of the last check copies */
87 DNET_CNTR_DBR_NOREC
, /* Kyoto Cabinet DB read error KCENOREC */
88 DNET_CNTR_DBR_SYSTEM
, /* Kyoto Cabinet DB read error KCESYSTEM */
89 DNET_CNTR_DBR_ERROR
, /* Kyoto Cabinet DB read error */
90 DNET_CNTR_DBW_SYSTEM
, /* Kyoto Cabinet DB write error KCESYSTEM */
91 DNET_CNTR_DBW_ERROR
, /* Kyoto Cabinet DB write error */
92 DNET_CNTR_UNKNOWN
, /* This slot is allocated for statistics gathered for unknown counters */
97 * Transaction ID direction bit.
98 * When set, data is a reply for the given transaction.
100 #define DNET_TRANS_REPLY 0x8000000000000000ULL
107 * When set, node will generate a reply when transaction
108 * is completed and put completion status into cmd.status
111 #define DNET_FLAGS_NEED_ACK (1<<0)
113 /* There will be more commands with the same parameters (transaction number and id) */
114 #define DNET_FLAGS_MORE (1<<1)
116 /* Transaction is about to be destroyed */
117 #define DNET_FLAGS_DESTROY (1<<2)
119 /* Do not forward requst to antoher node even if given ID does not belong to our range */
120 #define DNET_FLAGS_DIRECT (1<<3)
122 /* Do not locks operations - must be set for script callers or recursive operations */
123 #define DNET_FLAGS_NOLOCK (1<<4)
126 uint8_t id
[DNET_ID_SIZE
];
129 } __attribute__ ((packed
));
132 uint8_t id
[DNET_ID_SIZE
];
133 } __attribute__ ((packed
));
135 static inline void dnet_convert_raw_id(struct dnet_raw_id
*id
__attribute__ ((unused
)))
139 static inline void dnet_setup_id(struct dnet_id
*id
, unsigned int group_id
, unsigned char *raw
)
141 memcpy(id
->id
, raw
, DNET_ID_SIZE
);
142 id
->group_id
= group_id
;
153 } __attribute__ ((packed
));
155 /* kernel (pohmelfs) provides own defines for byteorder changes */
157 #ifdef WORDS_BIGENDIAN
159 #define dnet_bswap16(x) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
161 #define dnet_bswap32(x) \
162 ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
163 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
165 #define dnet_bswap64(x) \
166 ((((x) & 0xff00000000000000ull) >> 56) \
167 | (((x) & 0x00ff000000000000ull) >> 40) \
168 | (((x) & 0x0000ff0000000000ull) >> 24) \
169 | (((x) & 0x000000ff00000000ull) >> 8) \
170 | (((x) & 0x00000000ff000000ull) << 8) \
171 | (((x) & 0x0000000000ff0000ull) << 24) \
172 | (((x) & 0x000000000000ff00ull) << 40) \
173 | (((x) & 0x00000000000000ffull) << 56))
175 #define dnet_bswap16(x) (x)
176 #define dnet_bswap32(x) (x)
177 #define dnet_bswap64(x) (x)
181 static inline void dnet_convert_id(struct dnet_id
*id
)
183 id
->group_id
= dnet_bswap32(id
->group_id
);
184 id
->type
= dnet_bswap32(id
->type
);
187 static inline void dnet_convert_cmd(struct dnet_cmd
*cmd
)
189 dnet_convert_id(&cmd
->id
);
190 cmd
->flags
= dnet_bswap32(cmd
->flags
);
191 cmd
->status
= dnet_bswap32(cmd
->status
);
192 cmd
->size
= dnet_bswap64(cmd
->size
);
193 cmd
->trans
= dnet_bswap64(cmd
->trans
);
196 /* Completely remove object history and metadata */
197 #define DNET_ATTR_DELETE_HISTORY (1<<0)
199 /* What type of counters to fetch */
200 #define DNET_ATTR_CNTR_GLOBAL (1<<0)
202 /* Bulk request for checking files */
203 #define DNET_ATTR_BULK_CHECK (1<<0)
205 /* Fill ctime/mtime from metadata when processing DNET_CMD_LOOKUP */
206 #define DNET_ATTR_META_TIMES (1<<1)
208 /* Do not verify checksum */
209 #define DNET_ATTR_NOCSUM (1<<2)
212 * ascending sort data before returning range request to user
214 #define DNET_ATTR_SORT (1<<3)
217 * This flag will force its parent CMD not to lock operation
218 * Flag will be propagated to cmd->flags
220 #define DNET_ATTR_NOLOCK (1<<4)
228 } __attribute__ ((packed
));
230 static inline void dnet_convert_attr(struct dnet_attr
*a
)
232 a
->size
= dnet_bswap64(a
->size
);
233 a
->cmd
= dnet_bswap32(a
->cmd
);
234 a
->flags
= dnet_bswap32(a
->flags
);
237 #define DNET_ADDR_SIZE 28
241 uint8_t addr
[DNET_ADDR_SIZE
];
243 } __attribute__ ((packed
));
250 } __attribute__ ((packed
));
252 static inline void dnet_convert_list(struct dnet_list
*l
)
254 dnet_convert_id(&l
->id
);
255 l
->size
= dnet_bswap32(l
->size
);
258 struct dnet_addr_attr
263 struct dnet_addr addr
;
264 } __attribute__ ((packed
));
266 static inline void dnet_convert_addr_attr(struct dnet_addr_attr
*a
)
268 a
->addr
.addr_len
= dnet_bswap32(a
->addr
.addr_len
);
269 a
->proto
= dnet_bswap32(a
->proto
);
270 a
->sock_type
= dnet_bswap16(a
->sock_type
);
271 a
->family
= dnet_bswap16(a
->family
);
278 struct dnet_addr_attr addr
;
279 } __attribute__ ((packed
));
281 static inline void dnet_convert_addr_cmd(struct dnet_addr_cmd
*l
)
283 dnet_convert_cmd(&l
->cmd
);
284 dnet_convert_attr(&l
->a
);
285 dnet_convert_addr_attr(&l
->addr
);
288 /* Do not update history for given transaction */
289 #define DNET_IO_FLAGS_SKIP_SENDING (1<<0)
291 /* Append given data at the end of the object */
292 #define DNET_IO_FLAGS_APPEND (1<<1)
294 #define DNET_IO_FLAGS_COMPRESS (1<<2)
296 /* Metada IO request */
297 #define DNET_IO_FLAGS_META (1<<3)
299 /* eblob prepare/commit phase */
300 #define DNET_IO_FLAGS_PREPARE (1<<4)
301 #define DNET_IO_FLAGS_COMMIT (1<<5)
303 /* Object was removed */
304 #define DNET_IO_FLAGS_REMOVED (1<<6)
307 #define DNET_IO_FLAGS_OVERWRITE (1<<7)
309 /* Do not checksum data */
310 #define DNET_IO_FLAGS_NOCSUM (1<<8)
313 * this flag is used when we want backend not to perform any additional actions
314 * except than write data at given offset. This is no-op in filesystem backend,
315 * but eblob one should disable prepare/commit operations.
317 #define DNET_IO_FLAGS_PLAIN_WRITE (1<<9)
319 /* Do not really send data in range request.
320 * Send only statistics instead.
322 * -- we do not care if it matches above DNET_IO_FLAGS_PLAIN_WRITE,
323 * since using plain write and nodata (read) is useless anyway
325 #define DNET_IO_FLAGS_NODATA (1<<9)
329 uint8_t parent
[DNET_ID_SIZE
];
330 uint8_t id
[DNET_ID_SIZE
];
333 * used in range request as start and number for LIMIT(start, num)
335 * write prepare request uses @num is used as a placeholder
336 * for number of bytes to reserve on disk
343 } __attribute__ ((packed
));
345 static inline void dnet_convert_io_attr(struct dnet_io_attr
*a
)
347 a
->start
= dnet_bswap64(a
->start
);
348 a
->num
= dnet_bswap64(a
->num
);
350 a
->flags
= dnet_bswap32(a
->flags
);
351 a
->offset
= dnet_bswap64(a
->offset
);
352 a
->size
= dnet_bswap64(a
->size
);
355 struct dnet_history_entry
357 uint8_t id
[DNET_ID_SIZE
];
360 uint64_t tsec
, tnsec
;
363 } __attribute__ ((packed
));
366 * Helper structure and set of functions to map history file and perform basic checks.
368 struct dnet_history_map
370 struct dnet_history_entry
*ent
;
376 static inline void dnet_convert_history_entry(struct dnet_history_entry
*a
)
378 a
->flags
= dnet_bswap32(a
->flags
);
379 a
->offset
= dnet_bswap64(a
->offset
);
380 a
->size
= dnet_bswap64(a
->size
);
381 a
->tsec
= dnet_bswap64(a
->tsec
);
382 a
->tnsec
= dnet_bswap64(a
->tnsec
);
385 static inline void dnet_setup_history_entry(struct dnet_history_entry
*e
,
386 unsigned char *id
, uint64_t size
, uint64_t offset
,
387 struct timespec
*ts
, uint32_t flags
)
392 gettimeofday(&tv
, NULL
);
395 e
->tnsec
= tv
.tv_usec
* 1000;
397 e
->tsec
= ts
->tv_sec
;
398 e
->tnsec
= ts
->tv_nsec
;
401 memcpy(e
->id
, id
, DNET_ID_SIZE
);
408 dnet_convert_history_entry(e
);
413 /* Load average from the target system multiplied by 100 */
416 uint16_t namemax
; /* maximum filename length */
418 uint64_t bsize
; /* Block size */
419 uint64_t frsize
; /* Fragment size */
420 uint64_t blocks
; /* Filesystem size in frsize units */
421 uint64_t bfree
; /* # free blocks */
422 uint64_t bavail
; /* # free blocks for non-root */
423 uint64_t files
; /* # inodes */
424 uint64_t ffree
; /* # free inodes */
425 uint64_t favail
; /* # free inodes for non-root */
426 uint64_t fsid
; /* file system ID */
427 uint64_t flag
; /* mount flags */
430 * VM counters in KB (1024) units.
431 * On FreeBSD vm_buffers is used for wire counter.
434 uint64_t vm_inactive
;
441 * Per node IO statistics will live here.
442 * Reserved for future use.
444 uint64_t reserved
[32];
447 static inline void dnet_convert_stat(struct dnet_stat
*st
)
452 st
->la
[i
] = dnet_bswap16(st
->la
[i
]);
454 st
->bsize
= dnet_bswap64(st
->bsize
);
455 st
->frsize
= dnet_bswap64(st
->frsize
);
456 st
->blocks
= dnet_bswap64(st
->blocks
);
457 st
->bfree
= dnet_bswap64(st
->bfree
);
458 st
->bavail
= dnet_bswap64(st
->bavail
);
459 st
->files
= dnet_bswap64(st
->files
);
460 st
->ffree
= dnet_bswap64(st
->ffree
);
461 st
->favail
= dnet_bswap64(st
->favail
);
462 st
->fsid
= dnet_bswap64(st
->fsid
);
463 st
->namemax
= dnet_bswap16(st
->namemax
);
465 st
->vm_active
= dnet_bswap64(st
->vm_active
);
466 st
->vm_inactive
= dnet_bswap64(st
->vm_inactive
);
467 st
->vm_total
= dnet_bswap64(st
->vm_total
);
468 st
->vm_free
= dnet_bswap64(st
->vm_free
);
469 st
->vm_buffers
= dnet_bswap64(st
->vm_buffers
);
470 st
->vm_cached
= dnet_bswap64(st
->vm_cached
);
473 struct dnet_io_notification
475 struct dnet_addr_attr addr
;
476 struct dnet_io_attr io
;
479 static inline void dnet_convert_io_notification(struct dnet_io_notification
*n
)
481 dnet_convert_addr_attr(&n
->addr
);
482 dnet_convert_io_attr(&n
->io
);
485 struct dnet_stat_count
491 static inline void dnet_convert_stat_count(struct dnet_stat_count
*st
, int num
)
495 for (i
=0; i
<num
; ++i
) {
496 st
[i
].count
= dnet_bswap64(st
[i
].count
);
497 st
[i
].err
= dnet_bswap64(st
[i
].err
);
501 struct dnet_addr_stat
503 struct dnet_addr addr
;
506 struct dnet_stat_count count
[0];
507 } __attribute__ ((packed
));
509 static inline void dnet_convert_addr_stat(struct dnet_addr_stat
*st
, int num
)
511 st
->addr
.addr_len
= dnet_bswap32(st
->addr
.addr_len
);
512 st
->num
= dnet_bswap32(st
->num
);
515 st
->cmd_num
= dnet_bswap32(st
->cmd_num
);
517 dnet_convert_stat_count(st
->count
, num
);
520 static inline void dnet_stat_inc(struct dnet_stat_count
*st
, int cmd
, int err
)
522 if (cmd
>= __DNET_CMD_MAX
)
523 cmd
= DNET_CMD_UNKNOWN
;
532 uint64_t tsec
, tnsec
;
535 static inline void dnet_convert_time(struct dnet_time
*tm
)
537 tm
->tsec
= dnet_bswap64(tm
->tsec
);
538 tm
->tnsec
= dnet_bswap64(tm
->tnsec
);
541 static inline void dnet_current_time(struct dnet_time
*t
)
545 gettimeofday(&tv
, NULL
);
548 t
->tnsec
= tv
.tv_usec
* 1000;
551 struct dnet_file_info
{
552 int flen
; /* filename length, which goes after this structure */
553 unsigned char checksum
[DNET_CSUM_SIZE
];
571 uint64_t offset
; /* offset within eblob */
573 struct dnet_time atime
;
574 struct dnet_time ctime
;
575 struct dnet_time mtime
;
578 static inline void dnet_convert_file_info(struct dnet_file_info
*info
)
580 info
->flen
= dnet_bswap32(info
->flen
);
581 info
->nlink
= dnet_bswap32(info
->nlink
);
583 info
->mode
= dnet_bswap64(info
->mode
);
584 info
->dev
= dnet_bswap64(info
->dev
);
585 info
->ino
= dnet_bswap64(info
->ino
);
586 info
->uid
= dnet_bswap64(info
->uid
);
587 info
->gid
= dnet_bswap64(info
->gid
);
588 info
->blksize
= dnet_bswap64(info
->blksize
);
589 info
->blocks
= dnet_bswap64(info
->blocks
);
590 info
->rdev
= dnet_bswap64(info
->rdev
);
591 info
->size
= dnet_bswap64(info
->size
);
592 info
->offset
= dnet_bswap64(info
->offset
);
594 dnet_convert_time(&info
->atime
);
595 dnet_convert_time(&info
->ctime
);
596 dnet_convert_time(&info
->mtime
);
599 static inline void dnet_info_from_stat(struct dnet_file_info
*info
, struct stat
*st
)
601 info
->nlink
= st
->st_nlink
;
602 info
->mode
= st
->st_mode
;
603 info
->dev
= st
->st_dev
;
604 info
->ino
= st
->st_ino
;
605 info
->uid
= st
->st_uid
;
606 info
->gid
= st
->st_gid
;
607 info
->blksize
= st
->st_blksize
;
608 info
->blocks
= st
->st_blocks
;
609 info
->rdev
= st
->st_rdev
;
610 info
->size
= st
->st_size
;
613 info
->atime
.tsec
= st
->st_atime
;
614 info
->ctime
.tsec
= st
->st_ctime
;
615 info
->mtime
.tsec
= st
->st_mtime
;
617 info
->atime
.tnsec
= 0;
618 info
->ctime
.tnsec
= 0;
619 info
->mtime
.tnsec
= 0;
622 /* Elliptics node status - if set, status will be changed */
623 #define DNET_ATTR_STATUS_CHANGE (1<<0)
625 /* Elliptics node should exit */
626 #define DNET_STATUS_EXIT (1<<0)
628 /* Ellipitcs node goes ro/rw */
629 #define DNET_STATUS_RO (1<<1)
631 struct dnet_node_status
{
633 int status_flags
; /* DNET_STATUS_EXIT, DNET_STATUS_RO should be specified here */
637 static inline void dnet_convert_node_status(struct dnet_node_status
*st
)
639 st
->nflags
= dnet_bswap32(st
->nflags
);
640 st
->status_flags
= dnet_bswap32(st
->status_flags
);
641 st
->log_mask
= dnet_bswap32(st
->log_mask
);
644 #define DNET_AUTH_COOKIE_SIZE 32
647 char cookie
[DNET_AUTH_COOKIE_SIZE
];
652 static inline void dnet_convert_auth(struct dnet_auth
*a
)
654 a
->flags
= dnet_bswap64(a
->flags
);
657 enum dnet_meta_types
{
658 DNET_META_PARENT_OBJECT
= 1, /* parent object name */
659 DNET_META_GROUPS
, /* this object has copies in given groups */
660 DNET_META_CHECK_STATUS
, /* last checking status: timestamp and so on */
661 DNET_META_NAMESPACE
, /* namespace where given object lives */
662 DNET_META_UPDATE
, /* last update information (timestamp, flags) */
663 DNET_META_CHECKSUM
, /* checksum (sha512) of the whole data object calculated on server */
674 } __attribute__ ((packed
));
676 static inline void dnet_convert_meta(struct dnet_meta
*m
)
678 m
->type
= dnet_bswap32(m
->type
);
679 m
->size
= dnet_bswap32(m
->size
);
680 m
->common
= dnet_bswap64(m
->common
);
683 struct dnet_meta_update
{
688 uint64_t reserved
[4];
689 } __attribute__((packed
));
691 static inline void dnet_convert_meta_update(struct dnet_meta_update
*m
)
693 dnet_convert_time(&m
->tm
);
694 m
->flags
= dnet_bswap64(m
->flags
);
697 struct dnet_meta_check_status
{
701 uint64_t reserved
[4];
702 } __attribute__ ((packed
));
704 static inline void dnet_convert_meta_check_status(struct dnet_meta_check_status
*c
)
706 c
->status
= dnet_bswap32(c
->status
);
707 dnet_convert_time(&c
->tm
);
710 struct dnet_meta_checksum
{
711 uint8_t checksum
[DNET_CSUM_SIZE
];
713 } __attribute__ ((packed
));
715 static inline void dnet_convert_meta_checksum(struct dnet_meta_checksum
*c
)
717 dnet_convert_time(&c
->tm
);
721 uint64_t data_size
; /* size of text data in @data - located after even string */
722 uint64_t binary_size
; /* size of binary data in @data - located after text data */
724 int event_size
; /* size of the event string - it is located first in @data */
725 int status
; /* processing status - negative errno code or zero on success */
726 int key
; /* meta-key - used to map header to particular worker, see pool::worker_process() */
729 } __attribute__ ((packed
));
731 static inline void dnet_convert_sph(struct sph
*e
)
733 e
->data_size
= dnet_bswap64(e
->data_size
);
734 e
->binary_size
= dnet_bswap64(e
->binary_size
);
735 e
->flags
= dnet_bswap64(e
->flags
);
736 e
->event_size
= dnet_bswap32(e
->event_size
);
737 e
->status
= dnet_bswap32(e
->status
);
738 e
->key
= dnet_bswap32(e
->key
);
741 struct srw_init_ctl
{
742 char *binary
; /* path to srw_worker binary - it is used to spawn script workers */
743 char *log
; /* srw log path - initialized to the same config string as for 'log' by default */
744 char *pipe
; /* pipe base - elliptics will talk to workers via @pipe.c2w and @pipe.w2c */
745 char *init
; /* path to initialization object */
746 char *config
; /* path to config object */
747 void *priv
; /* opaque private data */
748 int pad
; /* srw worker type */
749 int num
; /* number of workers */
750 } __attribute__ ((packed
));
752 struct srw_load_ctl
{
753 int len
; /* length of the binary-object-name string */
754 int wnum
; /* number of workers for this binary */
756 } __attribute__ ((packed
));
758 static inline void srw_convert_load_ctl(struct srw_load_ctl
*ctl
)
760 ctl
->len
= dnet_bswap32(ctl
->len
);
761 ctl
->wnum
= dnet_bswap32(ctl
->wnum
);
768 #endif /* __DNET_PACKET_H */