2 * Lua Bindings for RADOS Object Class
9 #include "include/types.h"
10 #include "objclass/objclass.h"
11 #include "json_spirit/json_spirit.h"
13 #include "cls_lua_ops.h"
19 * Jump point for recovering from Lua panic.
21 static jmp_buf cls_lua_panic_jump
;
26 static int cls_lua_atpanic(lua_State
*lua
)
28 CLS_ERR("error: Lua panic: %s", lua_tostring(lua
, -1));
29 longjmp(cls_lua_panic_jump
, 1);
39 * Input parameter encoding.
47 struct clslua_err error
;
51 cls_method_context_t
*hctx
;
52 bufferlist
*inbl
; // raw cls input
53 bufferlist
*outbl
; // raw cls output
55 string script
; // lua script
56 string handler
; // lua handler
57 bufferlist input
; // lua handler input
60 /* Lua registry key for method context */
61 static char clslua_hctx_reg_key
;
64 * Grabs the full method handler context
66 static clslua_hctx
*__clslua_get_hctx(lua_State
*L
)
68 /* lookup registry value */
69 lua_pushlightuserdata(L
, &clslua_hctx_reg_key
);
70 lua_gettable(L
, LUA_REGISTRYINDEX
);
72 /* check cls_lua assumptions */
73 assert(!lua_isnil(L
, -1));
74 assert(lua_type(L
, -1) == LUA_TLIGHTUSERDATA
);
76 /* cast and cleanup stack */
77 clslua_hctx
*hctx
= (struct clslua_hctx
*)lua_touserdata(L
, -1);
84 * Get the method context out of the registry. This is called at the beginning
85 * of each clx_cxx_* wrapper, and must be set before there is any chance a Lua
86 * script calling a 'cls' module function that requires it.
88 static cls_method_context_t
clslua_get_hctx(lua_State
*L
)
90 struct clslua_hctx
*hctx
= __clslua_get_hctx(L
);
95 * Returns a reference to cls_lua error state from registry.
97 struct clslua_err
*clslua_checkerr(lua_State
*L
)
99 struct clslua_hctx
*hctx
= __clslua_get_hctx(L
);
100 struct clslua_err
*err
= &hctx
->error
;
105 /* Registry key for real `pcall` function */
106 static char clslua_pcall_reg_key
;
109 * Wrap Lua pcall to check for errors thrown by cls_lua (e.g. I/O errors or
110 * bufferlist decoding errors). The global error is cleared before returning
113 static int clslua_pcall(lua_State
*L
)
115 int nargs
= lua_gettop(L
);
116 lua_pushlightuserdata(L
, &clslua_pcall_reg_key
);
117 lua_gettable(L
, LUA_REGISTRYINDEX
);
119 lua_call(L
, nargs
, LUA_MULTRET
);
120 struct clslua_err
*err
= clslua_checkerr(L
);
124 lua_pushinteger(L
, err
->ret
);
127 return lua_gettop(L
);
134 static int clslua_log(lua_State
*L
)
136 int nargs
= lua_gettop(L
);
141 int loglevel
= LOG_LEVEL_DEFAULT
;
142 bool custom_ll
= false;
144 /* check if first arg can be a log level */
145 if (nargs
> 1 && lua_isnumber(L
, 1)) {
146 int ll
= (int)lua_tonumber(L
, 1);
153 /* check space for args and seperators (" ") */
154 int nelems
= ((nargs
- (custom_ll
? 1 : 0)) * 2) - 1;
155 luaL_checkstack(L
, nelems
, "rados.log(..)");
157 for (int i
= custom_ll
? 2 : 1; i
<= nargs
; i
++) {
158 const char *part
= lua_tostring(L
, i
);
160 if (lua_type(L
, i
) == LUA_TBOOLEAN
)
161 part
= lua_toboolean(L
, i
) ? "true" : "false";
163 part
= luaL_typename(L
, i
);
165 lua_pushstring(L
, part
);
167 lua_pushstring(L
, " ");
170 /* join string parts and send to Ceph/reply log */
171 lua_concat(L
, nelems
);
172 CLS_LOG(loglevel
, "%s", lua_tostring(L
, -1));
174 /* concat leaves result at top of stack */
178 static char clslua_registered_handle_reg_key
;
181 * Register a function to be used as a handler target
183 static int clslua_register(lua_State
*L
)
185 luaL_checktype(L
, 1, LUA_TFUNCTION
);
187 /* get table of registered handlers */
188 lua_pushlightuserdata(L
, &clslua_registered_handle_reg_key
);
189 lua_gettable(L
, LUA_REGISTRYINDEX
);
190 assert(lua_type(L
, -1) == LUA_TTABLE
);
192 /* lookup function argument */
196 if (lua_isnil(L
, -1)) {
201 lua_pushstring(L
, "Cannot register handler more than once");
209 * Check if a function is registered as a handler
211 static void clslua_check_registered_handler(lua_State
*L
)
213 luaL_checktype(L
, -1, LUA_TFUNCTION
);
215 /* get table of registered handlers */
216 lua_pushlightuserdata(L
, &clslua_registered_handle_reg_key
);
217 lua_gettable(L
, LUA_REGISTRYINDEX
);
218 assert(lua_type(L
, -1) == LUA_TTABLE
);
220 /* lookup function argument */
221 lua_pushvalue(L
, -2);
224 if (!lua_rawequal(L
, -1, -3)) {
225 lua_pushstring(L
, "Handler is not registered");
233 * Handle result of a cls_cxx_* call. If @ok is non-zero then we return with
234 * the number of Lua return arguments on the stack. Otherwise we save error
235 * information in the registry and throw a Lua error.
237 static int clslua_opresult(lua_State
*L
, int ok
, int ret
, int nargs
,
238 bool error_on_stack
= false)
240 struct clslua_err
*err
= clslua_checkerr(L
);
244 CLS_ERR("error: cls_lua state machine: unexpected error");
248 /* everything is cherry */
252 /* set error in registry */
256 /* push error message */
258 lua_pushfstring(L
, "%s", strerror(-ret
));
266 static int clslua_create(lua_State
*lua
)
268 cls_method_context_t hctx
= clslua_get_hctx(lua
);
269 int exclusive
= lua_toboolean(lua
, 1);
271 int ret
= cls_cxx_create(hctx
, exclusive
);
272 return clslua_opresult(lua
, (ret
== 0), ret
, 0);
278 static int clslua_remove(lua_State
*lua
)
280 cls_method_context_t hctx
= clslua_get_hctx(lua
);
282 int ret
= cls_cxx_remove(hctx
);
283 return clslua_opresult(lua
, (ret
== 0), ret
, 0);
289 static int clslua_stat(lua_State
*L
)
291 cls_method_context_t hctx
= clslua_get_hctx(L
);
295 int ret
= cls_cxx_stat(hctx
, &size
, &mtime
);
297 lua_pushinteger(L
, size
);
298 lua_pushinteger(L
, mtime
);
300 return clslua_opresult(L
, (ret
== 0), ret
, 2);
306 static int clslua_read(lua_State
*L
)
308 cls_method_context_t hctx
= clslua_get_hctx(L
);
309 int offset
= luaL_checkinteger(L
, 1);
310 int length
= luaL_checkinteger(L
, 2);
311 bufferlist
*bl
= clslua_pushbufferlist(L
, NULL
);
312 int ret
= cls_cxx_read(hctx
, offset
, length
, bl
);
313 return clslua_opresult(L
, (ret
>= 0), ret
, 1);
319 static int clslua_write(lua_State
*L
)
321 cls_method_context_t hctx
= clslua_get_hctx(L
);
322 int offset
= luaL_checkinteger(L
, 1);
323 int length
= luaL_checkinteger(L
, 2);
324 bufferlist
*bl
= clslua_checkbufferlist(L
, 3);
325 int ret
= cls_cxx_write(hctx
, offset
, length
, bl
);
326 return clslua_opresult(L
, (ret
== 0), ret
, 0);
332 static int clslua_write_full(lua_State
*L
)
334 cls_method_context_t hctx
= clslua_get_hctx(L
);
335 bufferlist
*bl
= clslua_checkbufferlist(L
, 1);
336 int ret
= cls_cxx_write_full(hctx
, bl
);
337 return clslua_opresult(L
, (ret
== 0), ret
, 0);
343 static int clslua_getxattr(lua_State
*L
)
345 cls_method_context_t hctx
= clslua_get_hctx(L
);
346 const char *name
= luaL_checkstring(L
, 1);
347 bufferlist
*bl
= clslua_pushbufferlist(L
, NULL
);
348 int ret
= cls_cxx_getxattr(hctx
, name
, bl
);
349 return clslua_opresult(L
, (ret
>= 0), ret
, 1);
355 static int clslua_getxattrs(lua_State
*L
)
357 cls_method_context_t hctx
= clslua_get_hctx(L
);
359 map
<string
, bufferlist
> attrs
;
360 int ret
= cls_cxx_getxattrs(hctx
, &attrs
);
362 return clslua_opresult(L
, 0, ret
, 0);
364 lua_createtable(L
, 0, attrs
.size());
366 for (auto it
= attrs
.cbegin(); it
!= attrs
.cend(); it
++) {
367 lua_pushstring(L
, it
->first
.c_str());
368 bufferlist
*bl
= clslua_pushbufferlist(L
, NULL
);
369 *bl
= it
->second
; // xfer ownership... will be GC'd
373 return clslua_opresult(L
, 1, ret
, 1);
379 static int clslua_setxattr(lua_State
*L
)
381 cls_method_context_t hctx
= clslua_get_hctx(L
);
382 const char *name
= luaL_checkstring(L
, 1);
383 bufferlist
*bl
= clslua_checkbufferlist(L
, 2);
384 int ret
= cls_cxx_setxattr(hctx
, name
, bl
);
385 return clslua_opresult(L
, (ret
== 0), ret
, 1);
389 * cls_cxx_map_get_val
391 static int clslua_map_get_val(lua_State
*L
)
393 cls_method_context_t hctx
= clslua_get_hctx(L
);
394 const char *key
= luaL_checkstring(L
, 1);
395 bufferlist
*bl
= clslua_pushbufferlist(L
, NULL
);
396 int ret
= cls_cxx_map_get_val(hctx
, key
, bl
);
397 return clslua_opresult(L
, (ret
== 0), ret
, 1);
401 * cls_cxx_map_set_val
403 static int clslua_map_set_val(lua_State
*L
)
405 cls_method_context_t hctx
= clslua_get_hctx(L
);
406 const char *key
= luaL_checkstring(L
, 1);
407 bufferlist
*val
= clslua_checkbufferlist(L
, 2);
408 int ret
= cls_cxx_map_set_val(hctx
, key
, val
);
409 return clslua_opresult(L
, (ret
== 0), ret
, 0);
415 static int clslua_map_clear(lua_State
*L
)
417 cls_method_context_t hctx
= clslua_get_hctx(L
);
418 int ret
= cls_cxx_map_clear(hctx
);
419 return clslua_opresult(L
, (ret
== 0), ret
, 0);
423 * cls_cxx_map_get_keys
425 static int clslua_map_get_keys(lua_State
*L
)
427 cls_method_context_t hctx
= clslua_get_hctx(L
);
428 const char *start_after
= luaL_checkstring(L
, 1);
429 int max_to_get
= luaL_checkinteger(L
, 2);
431 std::set
<string
> keys
;
432 int ret
= cls_cxx_map_get_keys(hctx
, start_after
, max_to_get
, &keys
);
434 return clslua_opresult(L
, 0, ret
, 0);
436 lua_createtable(L
, 0, keys
.size());
438 for (auto it
= keys
.cbegin(); it
!= keys
.cend(); it
++) {
439 const std::string
& key
= *it
;
440 lua_pushstring(L
, key
.c_str());
441 lua_pushboolean(L
, 1);
445 return clslua_opresult(L
, 1, ret
, 1);
449 * cls_cxx_map_get_vals
451 static int clslua_map_get_vals(lua_State
*L
)
453 cls_method_context_t hctx
= clslua_get_hctx(L
);
454 const char *start_after
= luaL_checkstring(L
, 1);
455 const char *filter_prefix
= luaL_checkstring(L
, 2);
456 int max_to_get
= luaL_checkinteger(L
, 3);
458 map
<string
, bufferlist
> kvpairs
;
459 int ret
= cls_cxx_map_get_vals(hctx
, start_after
, filter_prefix
,
460 max_to_get
, &kvpairs
);
462 return clslua_opresult(L
, 0, ret
, 0);
464 lua_createtable(L
, 0, kvpairs
.size());
466 for (auto it
= kvpairs
.cbegin(); it
!= kvpairs
.cend(); it
++) {
467 lua_pushstring(L
, it
->first
.c_str());
468 bufferlist
*bl
= clslua_pushbufferlist(L
, NULL
);
469 *bl
= it
->second
; // xfer ownership... will be GC'd
473 return clslua_opresult(L
, 1, ret
, 1);
477 * cls_cxx_map_read_header
479 static int clslua_map_read_header(lua_State
*L
)
481 cls_method_context_t hctx
= clslua_get_hctx(L
);
482 bufferlist
*bl
= clslua_pushbufferlist(L
, NULL
);
483 int ret
= cls_cxx_map_read_header(hctx
, bl
);
484 return clslua_opresult(L
, (ret
>= 0), ret
, 1);
488 * cls_cxx_map_write_header
490 static int clslua_map_write_header(lua_State
*L
)
492 cls_method_context_t hctx
= clslua_get_hctx(L
);
493 bufferlist
*bl
= clslua_checkbufferlist(L
, 1);
494 int ret
= cls_cxx_map_write_header(hctx
, bl
);
495 return clslua_opresult(L
, (ret
== 0), ret
, 0);
499 * cls_cxx_map_set_vals
501 static int clslua_map_set_vals(lua_State
*L
)
503 cls_method_context_t hctx
= clslua_get_hctx(L
);
504 luaL_checktype(L
, 1, LUA_TTABLE
);
506 map
<string
, bufferlist
> kvpairs
;
508 for (lua_pushnil(L
); lua_next(L
, 1); lua_pop(L
, 1)) {
510 * In the case of a numeric key a copy is made on the stack because
511 * converting to a string would otherwise manipulate the original key and
512 * cause problems for iteration.
515 int type_code
= lua_type(L
, -2);
518 key
.assign(lua_tolstring(L
, -2, NULL
));
522 lua_pushvalue(L
, -2);
523 key
.assign(lua_tolstring(L
, -1, NULL
));
528 lua_pushfstring(L
, "map_set_vals: invalid key type (%s)",
529 lua_typename(L
, type_code
));
530 return clslua_opresult(L
, 0, -EINVAL
, 0, true);
534 type_code
= lua_type(L
, -1);
539 const char *data
= lua_tolstring(L
, -1, &len
);
540 val
.append(data
, len
);
545 lua_pushfstring(L
, "map_set_vals: invalid val type (%s) for key (%s)",
546 lua_typename(L
, type_code
), key
.c_str());
547 return clslua_opresult(L
, 0, -EINVAL
, 0, true);
553 int ret
= cls_cxx_map_set_vals(hctx
, &kvpairs
);
555 return clslua_opresult(L
, (ret
== 0), ret
, 0);
559 * cls_cxx_map_remove_key
561 static int clslua_map_remove_key(lua_State
*L
)
563 cls_method_context_t hctx
= clslua_get_hctx(L
);
564 const char *key
= luaL_checkstring(L
, 1);
565 int ret
= cls_cxx_map_remove_key(hctx
, key
);
566 return clslua_opresult(L
, (ret
== 0), ret
, 0);
570 * cls_current_version
572 static int clslua_current_version(lua_State
*L
)
574 cls_method_context_t hctx
= clslua_get_hctx(L
);
575 uint64_t version
= cls_current_version(hctx
);
576 lua_pushinteger(L
, version
);
577 return clslua_opresult(L
, 1, 0, 1);
581 * cls_current_subop_num
583 static int clslua_current_subop_num(lua_State
*L
)
585 cls_method_context_t hctx
= clslua_get_hctx(L
);
586 int num
= cls_current_subop_num(hctx
);
587 lua_pushinteger(L
, num
);
588 return clslua_opresult(L
, 1, 0, 1);
592 * cls_current_subop_version
594 static int clslua_current_subop_version(lua_State
*L
)
596 cls_method_context_t hctx
= clslua_get_hctx(L
);
598 cls_cxx_subop_version(hctx
, &s
);
599 lua_pushstring(L
, s
.c_str());
600 return clslua_opresult(L
, 1, 0, 1);
604 * Functions registered in the 'cls' module.
606 static const luaL_Reg clslua_lib
[] = {
608 {"register", clslua_register
},
612 {"create", clslua_create
},
613 {"remove", clslua_remove
},
614 {"stat", clslua_stat
},
615 {"read", clslua_read
},
616 {"write", clslua_write
},
617 {"write_full", clslua_write_full
},
620 {"getxattr", clslua_getxattr
},
621 {"getxattrs", clslua_getxattrs
},
622 {"setxattr", clslua_setxattr
},
625 {"map_clear", clslua_map_clear
},
626 {"map_get_keys", clslua_map_get_keys
},
627 {"map_get_vals", clslua_map_get_vals
},
628 {"map_read_header", clslua_map_read_header
},
629 {"map_write_header", clslua_map_write_header
},
630 {"map_get_val", clslua_map_get_val
},
631 {"map_set_val", clslua_map_set_val
},
632 {"map_set_vals", clslua_map_set_vals
},
633 {"map_remove_key", clslua_map_remove_key
},
636 {"current_version", clslua_current_version
},
637 {"current_subop_num", clslua_current_subop_num
},
638 {"current_subop_version", clslua_current_subop_version
},
644 * Set int const in table at top of stack
646 #define SET_INT_CONST(var) do { \
647 lua_pushinteger(L, var); \
648 lua_setfield(L, -2, #var); \
654 static int luaopen_objclass(lua_State
*L
)
659 * Register cls functions (cls.log, etc...)
661 luaL_setfuncs(L
, clslua_lib
, 0);
664 * Register generic errno values under 'cls'
666 SET_INT_CONST(EPERM
);
667 SET_INT_CONST(ENOENT
);
668 SET_INT_CONST(ESRCH
);
669 SET_INT_CONST(EINTR
);
671 SET_INT_CONST(ENXIO
);
672 SET_INT_CONST(E2BIG
);
673 SET_INT_CONST(ENOEXEC
);
674 SET_INT_CONST(EBADF
);
675 SET_INT_CONST(ECHILD
);
676 SET_INT_CONST(EAGAIN
);
677 SET_INT_CONST(ENOMEM
);
678 SET_INT_CONST(EACCES
);
679 SET_INT_CONST(EFAULT
);
680 SET_INT_CONST(EBUSY
);
681 SET_INT_CONST(EEXIST
);
682 SET_INT_CONST(EXDEV
);
683 SET_INT_CONST(ENODEV
);
684 SET_INT_CONST(ENOTDIR
);
685 SET_INT_CONST(EISDIR
);
686 SET_INT_CONST(EINVAL
);
687 SET_INT_CONST(ENFILE
);
688 SET_INT_CONST(EMFILE
);
689 SET_INT_CONST(ENOTTY
);
690 SET_INT_CONST(EFBIG
);
691 SET_INT_CONST(ENOSPC
);
692 SET_INT_CONST(ESPIPE
);
693 SET_INT_CONST(EROFS
);
694 SET_INT_CONST(EMLINK
);
695 SET_INT_CONST(EPIPE
);
697 SET_INT_CONST(ERANGE
);
703 * Setup the execution environment. Our sandbox currently is not
704 * sophisticated. With a new Lua state per-request we don't need to work about
705 * users stepping on each other, but we do rip out access to the local file
706 * system. All this will change when/if we decide to use some shared Lua
707 * states, most likely for performance reasons.
709 static void clslua_setup_env(lua_State
*L
)
711 luaL_requiref(L
, "_G", luaopen_base
, 1);
715 * Wrap `pcall` to intercept errors. First save a reference to the default
716 * Lua `pcall` function, and then replace `pcall` with our version.
718 lua_pushlightuserdata(L
, &clslua_pcall_reg_key
);
719 lua_getglobal(L
, "pcall");
720 lua_settable(L
, LUA_REGISTRYINDEX
);
722 lua_pushcfunction(L
, clslua_pcall
);
723 lua_setglobal(L
, "pcall");
727 lua_setglobal(L
, "loadfile");
731 lua_setglobal(L
, "dofile");
733 /* not integrated into our error handling */
735 lua_setglobal(L
, "xpcall");
737 luaL_requiref(L
, LUA_TABLIBNAME
, luaopen_table
, 1);
740 luaL_requiref(L
, LUA_STRLIBNAME
, luaopen_string
, 1);
743 luaL_requiref(L
, LUA_MATHLIBNAME
, luaopen_math
, 1);
746 luaL_requiref(L
, "objclass", luaopen_objclass
, 1);
749 luaL_requiref(L
, "bufferlist", luaopen_bufferlist
, 1);
758 * "input": "..." # optional
761 static int unpack_json_command(lua_State
*L
, struct clslua_hctx
*ctx
,
762 std::string
& script
, std::string
& handler
, std::string
& input
,
765 std::string
json_input(ctx
->inbl
->c_str());
766 json_spirit::mValue value
;
768 if (!json_spirit::read(json_input
, value
)) {
769 CLS_ERR("error: unparseable JSON");
774 if (value
.type() != json_spirit::obj_type
) {
775 CLS_ERR("error: input not a JSON object");
779 json_spirit::mObject obj
= value
.get_obj();
782 std::map
<std::string
, json_spirit::mValue
>::const_iterator it
= obj
.find("script");
783 if (it
== obj
.end()) {
784 CLS_ERR("error: 'script' field found in JSON object");
789 if (it
->second
.type() != json_spirit::str_type
) {
790 CLS_ERR("error: script is not a string");
794 script
= it
->second
.get_str();
796 // grab the target function/handler name
797 it
= obj
.find("handler");
798 if (it
== obj
.end()) {
799 CLS_ERR("error: no target handler found in JSON object");
804 if (it
->second
.type() != json_spirit::str_type
) {
805 CLS_ERR("error: target handler is not a string");
809 handler
= it
->second
.get_str();
811 // grab the input (optional)
812 it
= obj
.find("input");
813 if (it
!= obj
.end()) {
814 if (it
->second
.type() != json_spirit::str_type
) {
815 CLS_ERR("error: handler input is not a string");
819 input
= it
->second
.get_str();
820 *input_len
= input
.size();
827 * Runs the script, and calls handler.
829 static int clslua_eval(lua_State
*L
)
831 struct clslua_hctx
*ctx
= __clslua_get_hctx(L
);
832 ctx
->ret
= -EIO
; /* assume failure */
835 * Load modules, errno value constants, and other environment goodies. Must
836 * be done before loading/compiling the chunk.
841 * Deserialize the input that contains the script, the name of the handler
842 * to call, and the handler input.
844 switch (ctx
->in_enc
) {
847 std::string input_str
;
848 size_t input_str_len
= 0;
850 // if there is an error decoding json then ctx->ret will be set and we
851 // return normally from this function.
852 if (unpack_json_command(L
, ctx
, ctx
->script
, ctx
->handler
, input_str
,
856 bufferptr
bp(input_str
.c_str(), input_str_len
);
857 ctx
->input
.push_back(bp
);
866 bufferlist::iterator it
= ctx
->inbl
->begin();
868 } catch (const buffer::error
&err
) {
869 CLS_ERR("error: could not decode ceph encoded input");
874 ctx
->script
.swap(op
.script
);
875 ctx
->handler
.swap(op
.handler
);
876 ctx
->input
= op
.input
;
881 CLS_ERR("error: unknown encoding type");
888 * Create table to hold registered (valid) handlers.
890 * Must be done before running the script for the first time because the
891 * script will immediately try to register one or more handlers using
892 * cls.register(function), which depends on this table.
894 lua_pushlightuserdata(L
, &clslua_registered_handle_reg_key
);
896 lua_settable(L
, LUA_REGISTRYINDEX
);
898 /* load and compile chunk */
899 if (luaL_loadstring(L
, ctx
->script
.c_str()))
905 /* no error, but nothing left to do */
906 if (!ctx
->handler
.size()) {
907 CLS_LOG(10, "no handler name provided");
908 ctx
->ret
= 0; /* success */
912 lua_getglobal(L
, ctx
->handler
.c_str());
913 if (lua_type(L
, -1) != LUA_TFUNCTION
) {
914 CLS_ERR("error: unknown handler or not function: %s", ctx
->handler
.c_str());
915 ctx
->ret
= -EOPNOTSUPP
;
919 /* throw error if function is not registered */
920 clslua_check_registered_handler(L
);
922 /* setup the input/output bufferlists */
923 clslua_pushbufferlist(L
, &ctx
->input
);
924 clslua_pushbufferlist(L
, ctx
->outbl
);
927 * Call the target Lua object class handler. If the call is successful then
928 * we will examine the return value here and store it in the context. Errors
929 * that occur are handled in the top-level eval() function.
931 int top
= lua_gettop(L
);
932 lua_call(L
, 2, LUA_MULTRET
);
934 /* store return value in context */
935 if (!(lua_gettop(L
) + 3 - top
))
936 lua_pushinteger(L
, 0);
937 ctx
->ret
= luaL_checkinteger(L
, -1);
943 * Main handler. Proxies the Lua VM and the Lua-defined handler.
945 static int eval_generic(cls_method_context_t hctx
, bufferlist
*in
, bufferlist
*out
,
946 InputEncoding in_enc
)
948 struct clslua_hctx ctx
;
952 /* stash context for use in Lua VM */
957 ctx
.error
.error
= false;
959 /* build lua vm state */
962 CLS_ERR("error creating new Lua state");
966 /* panic handler for unhandled errors */
967 lua_atpanic(L
, &cls_lua_atpanic
);
969 if (setjmp(cls_lua_panic_jump
) == 0) {
972 * Stash the handler context in the register. It contains the objclass
973 * method context, global error state, and the command and reply structs.
975 lua_pushlightuserdata(L
, &clslua_hctx_reg_key
);
976 lua_pushlightuserdata(L
, &ctx
);
977 lua_settable(L
, LUA_REGISTRYINDEX
);
979 /* Process the input and run the script */
980 lua_pushcfunction(L
, clslua_eval
);
981 ret
= lua_pcall(L
, 0, 0, 0);
983 /* Encountered an error? */
985 struct clslua_err
*err
= clslua_checkerr(L
);
987 CLS_ERR("error: cls_lua state machine: unexpected error");
991 /* Error origin a cls_cxx_* method? */
993 ret
= err
->ret
; /* cls_cxx_* return value */
995 /* Errors always abort. Fix up ret and log error */
997 CLS_ERR("error: unexpected handler return value");
1002 ret
= -EIO
; /* Generic error code */
1004 CLS_ERR("error: %s", lua_tostring(L
, -1));
1008 * No Lua error encountered while running the script, but the handler
1009 * may still have returned an error code (e.g. an errno value).
1015 CLS_ERR("error: recovering from Lua panic");
1025 static int eval_json(cls_method_context_t hctx
, bufferlist
*in
, bufferlist
*out
)
1027 return eval_generic(hctx
, in
, out
, JSON_ENC
);
1030 static int eval_bufferlist(cls_method_context_t hctx
, bufferlist
*in
, bufferlist
*out
)
1032 return eval_generic(hctx
, in
, out
, BUFFERLIST_ENC
);
1037 CLS_LOG(20, "Loaded lua class!");
1039 cls_handle_t h_class
;
1040 cls_method_handle_t h_eval_json
;
1041 cls_method_handle_t h_eval_bufferlist
;
1043 cls_register("lua", &h_class
);
1045 cls_register_cxx_method(h_class
, "eval_json",
1046 CLS_METHOD_RD
| CLS_METHOD_WR
, eval_json
, &h_eval_json
);
1048 cls_register_cxx_method(h_class
, "eval_bufferlist",
1049 CLS_METHOD_RD
| CLS_METHOD_WR
, eval_bufferlist
, &h_eval_bufferlist
);