Beispiel #1
0
/*
 * Get a list of all visble properties and their values for a given dataset.
 * Returned on the stack as a Lua table.
 */
static int
zcp_system_props_list(lua_State *state)
{
	int error;
	char errbuf[128];
	const char *dataset_name;
	dsl_pool_t *dp = zcp_run_info(state)->zri_pool;
	zcp_list_info_t *libinfo = &zcp_system_props_list_info;
	zcp_parse_args(state, libinfo->name, libinfo->pargs, libinfo->kwargs);
	dataset_name = lua_tostring(state, 1);
	nvlist_t *nv = fnvlist_alloc();

	dsl_dataset_t *ds = zcp_dataset_hold(state, dp, dataset_name, FTAG);
	if (ds == NULL)
		return (1); /* not reached; zcp_dataset_hold() longjmp'd */

	/* Get the names of all valid properties for this dataset */
	zcp_dataset_props(ds, nv);
	dsl_dataset_rele(ds, FTAG);

	/* push list as lua table */
	error = zcp_nvlist_to_lua(state, nv, errbuf, sizeof (errbuf));
	nvlist_free(nv);
	if (error != 0) {
		return (luaL_error(state,
		    "Error returning nvlist: %s", errbuf));
	}
	return (1);
}
Beispiel #2
0
static int
zcp_synctask_wrapper(lua_State *state)
{
	int err;
	zcp_cleanup_handler_t *zch;
	int num_ret = 1;
	nvlist_t *err_details = fnvlist_alloc();

	/*
	 * Make sure err_details is properly freed, even if a fatal error is
	 * thrown during the synctask.
	 */
	zch = zcp_register_cleanup(state,
	    (zcp_cleanup_t *)&fnvlist_free, err_details);

	zcp_synctask_info_t *info = lua_touserdata(state, lua_upvalueindex(1));
	boolean_t sync = lua_toboolean(state, lua_upvalueindex(2));

	zcp_run_info_t *ri = zcp_run_info(state);
	dsl_pool_t *dp = ri->zri_pool;

	/* MOS space is triple-dittoed, so we multiply by 3. */
	uint64_t funcspace = (info->blocks_modified << DST_AVG_BLKSHIFT) * 3;

	zcp_parse_args(state, info->name, info->pargs, info->kwargs);

	err = 0;
	if (info->space_check != ZFS_SPACE_CHECK_NONE && funcspace > 0) {
		uint64_t quota = dsl_pool_adjustedsize(dp,
		    info->space_check == ZFS_SPACE_CHECK_RESERVED) -
		    metaslab_class_get_deferred(spa_normal_class(dp->dp_spa));
		uint64_t used = dsl_dir_phys(dp->dp_root_dir)->dd_used_bytes +
		    ri->zri_space_used;

		if (used + funcspace > quota) {
			err = SET_ERROR(ENOSPC);
		}
	}

	if (err == 0) {
		err = info->func(state, sync, err_details);
	}

	if (err == 0) {
		ri->zri_space_used += funcspace;
	}

	lua_pushnumber(state, (lua_Number)err);
	if (fnvlist_num_pairs(err_details) > 0) {
		(void) zcp_nvlist_to_lua(state, err_details, NULL, 0);
		num_ret++;
	}

	zcp_deregister_cleanup(state, zch);
	fnvlist_free(err_details);

	return (num_ret);
}
Beispiel #3
0
/*
 * Push a Lua object representing the value of "pair" onto the stack.
 *
 * Only understands boolean_value, string, int64, nvlist,
 * string_array, and int64_array type values.  For other
 * types, returns EINVAL, fills in errbuf, and pushes nothing.
 */
static int
zcp_nvpair_value_to_lua(lua_State *state, nvpair_t *pair,
    char *errbuf, int errbuf_len)
{
	int err = 0;

	if (pair == NULL) {
		lua_pushnil(state);
		return (0);
	}

	switch (nvpair_type(pair)) {
	case DATA_TYPE_BOOLEAN_VALUE:
		(void) lua_pushboolean(state,
		    fnvpair_value_boolean_value(pair));
		break;
	case DATA_TYPE_STRING:
		(void) lua_pushstring(state, fnvpair_value_string(pair));
		break;
	case DATA_TYPE_INT64:
		(void) lua_pushinteger(state, fnvpair_value_int64(pair));
		break;
	case DATA_TYPE_NVLIST:
		err = zcp_nvlist_to_lua(state,
		    fnvpair_value_nvlist(pair), errbuf, errbuf_len);
		break;
	case DATA_TYPE_STRING_ARRAY: {
		char **strarr;
		uint_t nelem;
		(void) nvpair_value_string_array(pair, &strarr, &nelem);
		lua_newtable(state);
		for (int i = 0; i < nelem; i++) {
			(void) lua_pushinteger(state, i + 1);
			(void) lua_pushstring(state, strarr[i]);
			(void) lua_settable(state, -3);
		}
		break;
	}
	case DATA_TYPE_UINT64_ARRAY: {
		uint64_t *intarr;
		uint_t nelem;
		(void) nvpair_value_uint64_array(pair, &intarr, &nelem);
		lua_newtable(state);
		for (int i = 0; i < nelem; i++) {
			(void) lua_pushinteger(state, i + 1);
			(void) lua_pushinteger(state, intarr[i]);
			(void) lua_settable(state, -3);
		}
		break;
	}
	case DATA_TYPE_INT64_ARRAY: {
		int64_t *intarr;
		uint_t nelem;
		(void) nvpair_value_int64_array(pair, &intarr, &nelem);
		lua_newtable(state);
		for (int i = 0; i < nelem; i++) {
			(void) lua_pushinteger(state, i + 1);
			(void) lua_pushinteger(state, intarr[i]);
			(void) lua_settable(state, -3);
		}
		break;
	}
	default: {
		if (errbuf != NULL) {
			(void) snprintf(errbuf, errbuf_len,
			    "Unhandled nvpair type %d for key '%s'",
			    nvpair_type(pair), nvpair_name(pair));
		}
		return (EINVAL);
	}
	}
	return (err);
}