diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 391c0184a4a0..653c8eff78d6 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -56,7 +56,7 @@ set (recompiled_core_sources set (common_sources tbuf.c palloc.c util.c diagnostics.c salloc.c pickle.c coro.c stat.c log_io.c - log_io_remote.c iproto.c) + log_io_remote.c iproto.c errcode.c) if (ENABLE_TRACE) set (common_sources ${common_sources} trace.c) diff --git a/core/errcode.c b/core/errcode.c new file mode 100644 index 000000000000..442df0209c52 --- /dev/null +++ b/core/errcode.c @@ -0,0 +1,3 @@ +#include + +ERRCODE_RECORDS(error_codes, ERROR_CODES); diff --git a/core/iproto.c b/core/iproto.c index 83519646f8bb..6c462347a4c3 100644 --- a/core/iproto.c +++ b/core/iproto.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -34,8 +35,6 @@ #include const uint32_t msg_ping = 0xff00; -STRS(error_codes, ERROR_CODES); -DESC_STRS(error_codes, ERROR_CODES); static struct tbuf * iproto_parse(struct tbuf *in) @@ -76,7 +75,8 @@ iproto_interact(void *data) u32 msg_code = iproto(request)->msg_code; request->len = iproto(request)->len; request->data = iproto(request)->data; - reply->ret_code = callback(msg_code, request); + u32 err = callback(msg_code, request); + reply->ret_code = ERRCODE_VAL(error_codes, err); /* * retcode is uint32_t and included int struct iproto_header_retcode diff --git a/core/pickle.c b/core/pickle.c index 4db7e3dfd83d..df83332d8467 100644 --- a/core/pickle.c +++ b/core/pickle.c @@ -30,7 +30,7 @@ #include #include #include -#include /* for err codes */ +#include #include /* caller must ensure that there is space in target */ diff --git a/include/errcode.h b/include/errcode.h new file mode 100644 index 000000000000..eb15e3cd6d5d --- /dev/null +++ b/include/errcode.h @@ -0,0 +1,65 @@ +#ifndef TARANTOOL_ERRCODE_H +#define TARANTOOL_ERRCODE_H + +#include + +#include + +struct errcode_record { + const char *errstr; + uint32_t errval; + const char *errdesc; +}; + +#define ERRCODE_RECORD_MEMBER(s, v, d) { \ + .errstr = #s, \ + .errval = v, \ + .errdesc = #d \ +}, + +#define ERRCODE_RECORDS(enum_name, enum_members) \ + struct errcode_record enum_name##_records[enum_name##_MAX] = { \ + enum_members(ERRCODE_RECORD_MEMBER) \ + } + +#define ERRCODE_STR(enum_name, err) (enum_name##_records[err].errstr) +#define ERRCODE_VAL(enum_name, err) (enum_name##_records[err].errval) +#define ERRCODE_DESC(enum_name, err) (enum_name##_records[err].errdesc) + +#define ERROR_CODES(_) \ + _(ERR_CODE_OK, 0x00000000, "OK") \ + _(ERR_CODE_NONMASTER, 0x00000102, "Non master connection, but it should be") \ + _(ERR_CODE_ILLEGAL_PARAMS, 0x00000202, "Illegal parametrs") \ + _(ERR_CODE_BAD_UID, 0x00000302, "Uid is not from this storage range") \ + _(ERR_CODE_NODE_IS_RO, 0x00000401, "Node is marked as read-only") \ + _(ERR_CODE_NODE_IS_NOT_LOCKED, 0x00000501, "Node isn't locked") \ + _(ERR_CODE_NODE_IS_LOCKED, 0x00000601, "Node is locked") \ + _(ERR_CODE_MEMORY_ISSUE, 0x00000701, "Some memory issue") \ + _(ERR_CODE_BAD_INTEGRITY, 0x00000802, "Bad graph integrity") \ + _(ERR_CODE_UNSUPPORTED_COMMAND, 0x00000a02, "Unsupported command") \ + /* gap due to silverproxy */ \ + _(ERR_CODE_CANNOT_REGISTER, 0x00001801, "Can't register new user") \ + _(ERR_CODE_CANNOT_INIT_ALERT_ID, 0x00001a01, "Can't generate alert id") \ + _(ERR_CODE_CANNOT_DEL, 0x00001b02, "Can't del node") \ + _(ERR_CODE_USER_NOT_REGISTERED, 0x00001c02, "User isn't registered") \ + /* silversearch error codes */ \ + _(ERR_CODE_SYNTAX_ERROR, 0x00001d02, "Syntax error in query") \ + _(ERR_CODE_WRONG_FIELD, 0x00001e02, "Unknown field") \ + _(ERR_CODE_WRONG_NUMBER, 0x00001f02, "Number value is out of range") \ + _(ERR_CODE_DUPLICATE, 0x00002002, "Insert already existing object") \ + _(ERR_CODE_UNSUPPORTED_ORDER, 0x00002202, "Can not order result") \ + _(ERR_CODE_MULTIWRITE, 0x00002302, "Multiple to update/delete") \ + _(ERR_CODE_NOTHING, 0x00002400, "Nothing to do (not an error)") \ + _(ERR_CODE_UPDATE_ID, 0x00002502, "Id's update") \ + _(ERR_CODE_WRONG_VERSION, 0x00002602, "Unsupported version of protocol") \ + /* other generic error codes */ \ + _(ERR_CODE_UNKNOWN_ERROR, 0x00002702, "Unknown error") \ + _(ERR_CODE_NODE_NOT_FOUND, 0x00003102, "Node isn't found") \ + _(ERR_CODE_NODE_FOUND, 0x00003702, "Node is found") \ + _(ERR_CODE_INDEX_VIOLATION, 0x00003802, "Some index violation occur") \ + _(ERR_CODE_NO_SUCH_NAMESPACE, 0x00003902, "There is no such namespace") + +ENUM0(error_codes, ERROR_CODES); +extern struct errcode_record error_codes_records[]; + +#endif diff --git a/include/fiber.h b/include/fiber.h index 9113d06a83ee..6dd98cb70bcf 100644 --- a/include/fiber.h +++ b/include/fiber.h @@ -127,12 +127,12 @@ void raise_(int); struct msg *read_inbox(void); int fiber_bread(struct tbuf *, size_t v); -inline static void add_iov_unsafe(void *buf, size_t len) +inline static void add_iov_unsafe(const void *buf, size_t len) { struct iovec *v; assert(fiber->iov->size - fiber->iov->len >= sizeof(*v)); v = fiber->iov->data + fiber->iov->len; - v->iov_base = buf; + v->iov_base = (void *)buf; v->iov_len = len; fiber->iov->len += sizeof(*v); fiber->iov_cnt++; @@ -143,7 +143,7 @@ inline static void iov_ensure(size_t count) tbuf_ensure(fiber->iov, sizeof(struct iovec) * count); } -inline static void add_iov(void *buf, size_t len) +inline static void add_iov(const void *buf, size_t len) { iov_ensure(1); add_iov_unsafe(buf, len); diff --git a/include/iproto.h b/include/iproto.h index 4256e2c7673d..5b148b230161 100644 --- a/include/iproto.h +++ b/include/iproto.h @@ -38,40 +38,4 @@ struct iproto_interactor void iproto_interact(void *); -#define ERROR_CODES(_) \ - _(ERR_CODE_OK, 0x00000000, "ok") \ - _(ERR_CODE_NONMASTER, 0x00000102, "non master connection, but it should be") \ - _(ERR_CODE_ILLEGAL_PARAMS, 0x00000202, "illegal parametrs") \ - _(ERR_CODE_BAD_UID, 0x00000302, "uid not from this storage range") \ - _(ERR_CODE_NODE_IS_RO, 0x00000401, "node is marked as read-only") \ - _(ERR_CODE_NODE_IS_NOT_LOCKED, 0x00000501, "node isn't locked") \ - _(ERR_CODE_NODE_IS_LOCKED, 0x00000601, "node is locked") \ - _(ERR_CODE_MEMORY_ISSUE, 0x00000701, "some memory issues") \ - _(ERR_CODE_BAD_INTEGRITY, 0x00000802, "bad graph integrity") \ - _(ERR_CODE_UNSUPPORTED_COMMAND, 0x00000a02, "unsupported command") \ - /* gap due to silverproxy */ \ - _(ERR_CODE_CANNOT_REGISTER, 0x00001801, "can't register new user") \ - _(ERR_CODE_CANNOT_INIT_ALERT_ID, 0x00001a01, "can't generate alert id") \ - _(ERR_CODE_CANNOT_DEL, 0x00001b02, "can't del node") \ - _(ERR_CODE_USER_NOT_REGISTERED, 0x00001c02, "user isn't registered") \ - /* silversearch error codes */ \ - _(ERR_CODE_SYNTAX_ERROR, 0x00001d02, "syntax error in query") \ - _(ERR_CODE_WRONG_FIELD, 0x00001e02, "unknown field") \ - _(ERR_CODE_WRONG_NUMBER, 0x00001f02, "number value is out of range") \ - _(ERR_CODE_DUPLICATE, 0x00002002, "insert already existing object") \ - _(ERR_CODE_UNSUPPORTED_ORDER, 0x00002202, "can not order result") \ - _(ERR_CODE_MULTIWRITE, 0x00002302, "multiple to update/delete") \ - _(ERR_CODE_NOTHING, 0x00002400, "nothing to do (not an error)") \ - _(ERR_CODE_UPDATE_ID, 0x00002502, "id's update") \ - _(ERR_CODE_WRONG_VERSION, 0x00002602, "unsupported version of protocol") \ - /* other generic error codes */ \ - _(ERR_CODE_UNKNOWN_ERROR, 0x00002702, "unknown error") \ - _(ERR_CODE_NODE_NOT_FOUND, 0x00003102, "node isn't found") \ - _(ERR_CODE_NODE_FOUND, 0x00003702, "node is found") \ - _(ERR_CODE_INDEX_VIOLATION, 0x00003802, "some index violation occur") \ - _(ERR_CODE_NO_SUCH_NAMESPACE, 0x00003902, "there is no such namespace") - -ENUM(error_codes, ERROR_CODES); -extern char *error_codes_strs[]; -extern char *error_codes_desc_strs[]; #endif diff --git a/include/util.h b/include/util.h index 21236285b88f..a460d14053e6 100644 --- a/include/util.h +++ b/include/util.h @@ -35,14 +35,13 @@ #endif /* Macros to define enum and corresponding strings. */ -#define ENUM_MEMBER(s, v, d...) s = v, -#define ENUM_STRS_MEMBER(s, v, d...) [s] = #s, -#define ENUM_DESC_STRS_MEMBER(s, v, d...) [s] = d, +#define ENUM0_MEMBER(s, ...) s, +#define ENUM_MEMBER(s, v, ...) s = v, +#define ENUM_STRS_MEMBER(s, v, ...) [s] = #s, +#define ENUM0(enum_name, enum_members) enum enum_name {enum_members(ENUM0_MEMBER) enum_name##_MAX} #define ENUM(enum_name, enum_members) enum enum_name {enum_members(ENUM_MEMBER) enum_name##_MAX} #define STRS(enum_name, enum_members) \ char *enum_name##_strs[enum_name##_MAX + 1] = {enum_members(ENUM_STRS_MEMBER) '\0'} -#define DESC_STRS(enum_name, enum_members) \ - char *enum_name##_desc_strs[enum_name##_MAX + 1] = {enum_members(ENUM_DESC_STRS_MEMBER) '\0'} // Macros for printf functions #include diff --git a/mod/silverbox/box.c b/mod/silverbox/box.c index 24f73910b321..527c34814742 100644 --- a/mod/silverbox/box.c +++ b/mod/silverbox/box.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include diff --git a/mod/silverbox/box.h b/mod/silverbox/box.h index 2f77fcb75a87..4f5b6eef2cb7 100644 --- a/mod/silverbox/box.h +++ b/mod/silverbox/box.h @@ -118,11 +118,11 @@ enum box_mode { ENUM(messages, MESSAGES); -#define box_raise(n, err) \ - ({ \ - if (n != ERR_CODE_NODE_IS_RO) \ - say_warn("%s/%s", error_codes_strs[(n)], err); \ - raise(n, err); \ +#define box_raise(n, err) \ + ({ \ + if (n != ERR_CODE_NODE_IS_RO) \ + say_warn("%s/%s", ERRCODE_STR(error_codes, n), err); \ + raise(n, err); \ }) struct box_txn *txn_alloc(u32 flags); diff --git a/mod/silverbox/index.c b/mod/silverbox/index.c index 59cccfe09cc5..58604e587be2 100644 --- a/mod/silverbox/index.c +++ b/mod/silverbox/index.c @@ -29,8 +29,8 @@ #include #include +#include #include -#include #include #include #include diff --git a/mod/silverbox/memcached.c b/mod/silverbox/memcached.c index 6a8006e463cb..eff4af693b64 100644 --- a/mod/silverbox/memcached.c +++ b/mod/silverbox/memcached.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include #include @@ -260,8 +260,8 @@ memcached_dispatch(struct box_txn *txn) add_iov("STORED\r\n", 8); \ } else { \ add_iov("SERVER_ERROR ", 13); \ - add_iov(error_codes_desc_strs[ret_code], \ - strlen(error_codes_desc_strs[ret_code])); \ + add_iov(ERRCODE_DESC(error_codes, ret_code), \ + strlen(ERRCODE_DESC(error_codes, ret_code))); \ add_iov("\r\n", 2); \ } \ } \ @@ -1078,8 +1078,8 @@ case 12: add_iov("DELETED\r\n", 9); else { add_iov("SERVER_ERROR ", 13); - add_iov(error_codes_desc_strs[ret_code], - strlen(error_codes_desc_strs[ret_code])); + add_iov(ERRCODE_DESC(error_codes, ret_code), + strlen(ERRCODE_DESC(error_codes,ret_code))); add_iov("\r\n", 2); } } @@ -1112,8 +1112,8 @@ case 12: add_iov("DELETED\r\n", 9); else { add_iov("SERVER_ERROR ", 13); - add_iov(error_codes_desc_strs[ret_code], - strlen(error_codes_desc_strs[ret_code])); + add_iov(ERRCODE_DESC(error_codes, ret_code), + strlen(ERRCODE_DESC(error_codes,ret_code))); add_iov("\r\n", 2); } } @@ -1142,8 +1142,8 @@ case 12: add_iov("DELETED\r\n", 9); else { add_iov("SERVER_ERROR ", 13); - add_iov(error_codes_desc_strs[ret_code], - strlen(error_codes_desc_strs[ret_code])); + add_iov(ERRCODE_DESC(error_codes, ret_code), + strlen(ERRCODE_DESC(error_codes,ret_code))); add_iov("\r\n", 2); } } diff --git a/mod/silverbox/memcached.rl b/mod/silverbox/memcached.rl index 9f036ca38c09..da7400fceca7 100644 --- a/mod/silverbox/memcached.rl +++ b/mod/silverbox/memcached.rl @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include #include @@ -251,8 +251,8 @@ memcached_dispatch(struct box_txn *txn) add_iov("STORED\r\n", 8); \ } else { \ add_iov("SERVER_ERROR ", 13); \ - add_iov(error_codes_desc_strs[ret_code], \ - strlen(error_codes_desc_strs[ret_code])); \ + add_iov(ERRCODE_DESC(error_codes, ret_code), \ + strlen(ERRCODE_DESC(error_codes, ret_code))); \ add_iov("\r\n", 2); \ } \ } \ @@ -382,8 +382,8 @@ memcached_dispatch(struct box_txn *txn) add_iov("DELETED\r\n", 9); else { add_iov("SERVER_ERROR ", 13); - add_iov(error_codes_desc_strs[ret_code], - strlen(error_codes_desc_strs[ret_code])); + add_iov(ERRCODE_DESC(error_codes, ret_code), + strlen(ERRCODE_DESC(error_codes,ret_code))); add_iov("\r\n", 2); } }