mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-27 03:19:35 +03:00
OpenZFS 9424 - ztest failure: "unprotected error in call to Lua API (Invalid value type 'function' for key 'error')"
Ztest failed with the following crash. ::status debugging core file of ztest (64-bit) from clone-dc-slave-280-bc7947b1.dcenter file: /usr/bin/amd64/ztest initial argv: /usr/bin/amd64/ztest threading model: raw lwps status: process terminated by SIGABRT (Abort), pid=2150 uid=1025 code=-1 panic message: failure for thread 0xfffffd7fff112a40, thread-id 1: unprotected error in call to Lua API (Invalid value type 'function' for key 'error') ::stack libc.so.1`_lwp_kill+0xa() libc.so.1`_assfail+0x182(fffffd7fffdfe8d0, 0, 0) libc.so.1`assfail+0x19(fffffd7fffdfe8d0, 0, 0) libzpool.so.1`vpanic+0x3d(fffffd7ffaa58c20, fffffd7fffdfeb00) 0xfffffd7ffaa28146() 0xfffffd7ffaa0a109() libzpool.so.1`luaD_throw+0x86(3011a48, 2) 0xfffffd7ffa9350d3() 0xfffffd7ffa93e3f1() libzpool.so.1`zcp_lua_to_nvlist+0x33(3011a48, 1, 2686470, fffffd7ffaa2e2c3) libzpool.so.1`zcp_convert_return_values+0xa4(3011a48, 2686470, fffffd7ffaa2e2c3, fffffd7fffdfedd0) libzpool.so.1`zcp_pool_error+0x59(fffffd7fffdfedd0, 1e0f450) libzpool.so.1`zcp_eval+0x6f8(1e0f450, fffffd7ffaa483f8, 1, 0, 6400000, 1d33b30) libzpool.so.1`dsl_destroy_snapshots_nvl+0x12c(2786b60, 0, 484750) libzpool.so.1`dsl_destroy_snapshot+0x4f(fffffd7fffdfef70, 0) ztest_dsl_dataset_cleanup+0xea(fffffd7fffdff4c0, 1) ztest_dataset_destroy+0x53(1) ztest_run+0x59f(fffffd7fff0e0498) main+0x7ff(1, fffffd7fffdffa88) _start+0x6c() The problem is that zcp_convert_return_values() assumes that there's exactly one value on the stack, but that isn't always true. It ends up putting the wrong thing on the stack which is then consumed by zcp_convert_return values, which either adds the wrong message to the nvlist, or blows up. The fix is to make sure that callers of zcp_convert_return_values() clear the stack before pushing their error message, and zcp_convert_return_values() should VERIFY that the stack is the expected size. Authored by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: Sebastien Roy <sebastien.roy@delphix.com> Reviewed by: Paul Dagnelie <pcd@delphix.com> Reviewed by: Don Brady <don.brady@delphix.com> Ported-by: Brian Behlendorf <behlendorf1@llnl.gov> Approved by: Robert Mustacchi <rm@joyent.com> OpenZFS-issue: https://www.illumos.org/issues/9424 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/eb7e57429 Closes #7696
This commit is contained in:
parent
e2cc448b60
commit
2dca37d8dc
@ -429,7 +429,7 @@ zcp_lua_to_nvlist_impl(lua_State *state, int index, nvlist_t *nvl,
|
|||||||
/*
|
/*
|
||||||
* Convert a lua value to an nvpair, adding it to an nvlist with the given key.
|
* Convert a lua value to an nvpair, adding it to an nvlist with the given key.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
zcp_lua_to_nvlist(lua_State *state, int index, nvlist_t *nvl, const char *key)
|
zcp_lua_to_nvlist(lua_State *state, int index, nvlist_t *nvl, const char *key)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -441,7 +441,7 @@ zcp_lua_to_nvlist(lua_State *state, int index, nvlist_t *nvl, const char *key)
|
|||||||
(void) lua_error(state);
|
(void) lua_error(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
zcp_lua_to_nvlist_helper(lua_State *state)
|
zcp_lua_to_nvlist_helper(lua_State *state)
|
||||||
{
|
{
|
||||||
nvlist_t *nv = (nvlist_t *)lua_touserdata(state, 2);
|
nvlist_t *nv = (nvlist_t *)lua_touserdata(state, 2);
|
||||||
@ -450,11 +450,12 @@ zcp_lua_to_nvlist_helper(lua_State *state)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
zcp_convert_return_values(lua_State *state, nvlist_t *nvl,
|
zcp_convert_return_values(lua_State *state, nvlist_t *nvl,
|
||||||
const char *key, zcp_eval_arg_t *evalargs)
|
const char *key, zcp_eval_arg_t *evalargs)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
VERIFY3U(1, ==, lua_gettop(state));
|
||||||
lua_pushcfunction(state, zcp_lua_to_nvlist_helper);
|
lua_pushcfunction(state, zcp_lua_to_nvlist_helper);
|
||||||
lua_pushlightuserdata(state, (char *)key);
|
lua_pushlightuserdata(state, (char *)key);
|
||||||
lua_pushlightuserdata(state, nvl);
|
lua_pushlightuserdata(state, nvl);
|
||||||
@ -900,6 +901,7 @@ zcp_eval_impl(dmu_tx_t *tx, boolean_t sync, zcp_eval_arg_t *evalargs)
|
|||||||
ZCP_RET_RETURN, evalargs);
|
ZCP_RET_RETURN, evalargs);
|
||||||
} else if (return_count > 1) {
|
} else if (return_count > 1) {
|
||||||
evalargs->ea_result = SET_ERROR(ECHRNG);
|
evalargs->ea_result = SET_ERROR(ECHRNG);
|
||||||
|
lua_settop(state, 0);
|
||||||
(void) lua_pushfstring(state, "Multiple return "
|
(void) lua_pushfstring(state, "Multiple return "
|
||||||
"values not supported");
|
"values not supported");
|
||||||
zcp_convert_return_values(state, evalargs->ea_outnvl,
|
zcp_convert_return_values(state, evalargs->ea_outnvl,
|
||||||
@ -967,6 +969,7 @@ static void
|
|||||||
zcp_pool_error(zcp_eval_arg_t *evalargs, const char *poolname)
|
zcp_pool_error(zcp_eval_arg_t *evalargs, const char *poolname)
|
||||||
{
|
{
|
||||||
evalargs->ea_result = SET_ERROR(ECHRNG);
|
evalargs->ea_result = SET_ERROR(ECHRNG);
|
||||||
|
lua_settop(evalargs->ea_state, 0);
|
||||||
(void) lua_pushfstring(evalargs->ea_state, "Could not open pool: %s",
|
(void) lua_pushfstring(evalargs->ea_state, "Could not open pool: %s",
|
||||||
poolname);
|
poolname);
|
||||||
zcp_convert_return_values(evalargs->ea_state, evalargs->ea_outnvl,
|
zcp_convert_return_values(evalargs->ea_state, evalargs->ea_outnvl,
|
||||||
|
Loading…
Reference in New Issue
Block a user