1*b2d2f356SSara Hartse-- 2*b2d2f356SSara Hartse-- This file and its contents are supplied under the terms of the 3*b2d2f356SSara Hartse-- Common Development and Distribution License ("CDDL"), version 1.0. 4*b2d2f356SSara Hartse-- You may only use this file in accordance with the terms of version 5*b2d2f356SSara Hartse-- 1.0 of the CDDL. 6*b2d2f356SSara Hartse-- 7*b2d2f356SSara Hartse-- A full copy of the text of the CDDL should have accompanied this 8*b2d2f356SSara Hartse-- source. A copy of the CDDL is also available via the Internet at 9*b2d2f356SSara Hartse-- http://www.illumos.org/license/CDDL. 10*b2d2f356SSara Hartse-- 11*b2d2f356SSara Hartse 12*b2d2f356SSara Hartse-- 13*b2d2f356SSara Hartse-- Copyright (c) 2017 by Delphix. All rights reserved. 14*b2d2f356SSara Hartse-- Copyright 2020 Joyent, Inc. 15*b2d2f356SSara Hartse-- 16*b2d2f356SSara Hartse 17*b2d2f356SSara Hartsearg = ... 18*b2d2f356SSara Hartsefs = arg["argv"][1] 19*b2d2f356SSara Hartse 20*b2d2f356SSara Hartse-- values from zfs.h 21*b2d2f356SSara Hartsemaxname = 256 -- ZAP_MAXNAMELEN 22*b2d2f356SSara Hartsemaxvalue = 8192 -- ZAP_MAXVALUELEN 23*b2d2f356SSara Hartse 24*b2d2f356SSara Hartsepos_props = {} 25*b2d2f356SSara Hartseneg_props = {} 26*b2d2f356SSara Hartse 27*b2d2f356SSara Hartse-- In lua, strings are immutable, so to avoid a bunch of copies, we 28*b2d2f356SSara Hartse-- build the value in a table and use concat (which appears to be the 29*b2d2f356SSara Hartse-- recommended method for such things). 30*b2d2f356SSara Hartselargeprop = {} 31*b2d2f356SSara Hartsefor i = 0,maxvalue,8 32*b2d2f356SSara Hartsedo 33*b2d2f356SSara Hartse table.insert(largeprop, "aaaaaaaa") 34*b2d2f356SSara Hartseend 35*b2d2f356SSara Hartse-- add an extra character so we spill over the limit 36*b2d2f356SSara Hartsetable.insert(largeprop, "b") 37*b2d2f356SSara Hartse 38*b2d2f356SSara Hartselargepropv = table.concat(largeprop) 39*b2d2f356SSara Hartse 40*b2d2f356SSara Hartselargepropname = { "b:" } 41*b2d2f356SSara Hartsefor i = 0,maxname,8 42*b2d2f356SSara Hartsedo 43*b2d2f356SSara Hartse table.insert(largepropname, "aaaaaaaa") 44*b2d2f356SSara Hartseend 45*b2d2f356SSara Hartselargepropnamev = table.concat(largepropname) 46*b2d2f356SSara Hartse 47*b2d2f356SSara Hartsepos_props["a:prop"] = {"hello"} 48*b2d2f356SSara Hartse 49*b2d2f356SSara Hartse-- For neg_props, an optional expected error value can be added after the 50*b2d2f356SSara Hartse-- property value as seen below. 51*b2d2f356SSara Hartseneg_props["notaproperty"] = {"hello", EINVAL} 52*b2d2f356SSara Hartseneg_props["a:very.long.property.value"] = { largepropv, E2BIG } 53*b2d2f356SSara Hartseneg_props[largepropnamev] = {"greetings", ENAMETOOLONG } 54*b2d2f356SSara Hartse 55*b2d2f356SSara Hartse-- non-user properties aren't currently supported 56*b2d2f356SSara Hartse-- Even if they were, the argument must be a string due to requirements of 57*b2d2f356SSara Hartse-- the ZCP api. 58*b2d2f356SSara Hartseneg_props["mountpoint"] = {"/foo/bar"} 59*b2d2f356SSara Hartseneg_props["copies"] = { "2" } 60*b2d2f356SSara Hartse 61*b2d2f356SSara Hartse-- read-only properties should never succeed 62*b2d2f356SSara Hartseneg_props["guid"] = { "12345" } 63*b2d2f356SSara Hartse 64*b2d2f356SSara Hartseset_fail = {} 65*b2d2f356SSara Hartseval_fail = {} 66*b2d2f356SSara Hartse 67*b2d2f356SSara Hartse-- Test properties that should work 68*b2d2f356SSara Hartsefor prop, values in pairs(pos_props) do 69*b2d2f356SSara Hartse for i, val in ipairs(values) do 70*b2d2f356SSara Hartse old_val, src = zfs.get_prop(fs, prop) 71*b2d2f356SSara Hartse 72*b2d2f356SSara Hartse -- Attempt to set the property to the specified value 73*b2d2f356SSara Hartse err = zfs.sync.set_prop(fs, prop, val) 74*b2d2f356SSara Hartse 75*b2d2f356SSara Hartse if (err ~= 0) then 76*b2d2f356SSara Hartse set_fail[prop] = err -- tuple of prop, val that resulted in error 77*b2d2f356SSara Hartse else 78*b2d2f356SSara Hartse -- use get_prop to check that the set took effect 79*b2d2f356SSara Hartse new_val, src = zfs.get_prop(fs, prop) 80*b2d2f356SSara Hartse if (tostring(new_val) ~= tostring(val)) then 81*b2d2f356SSara Hartse val_fail[prop] = new_val 82*b2d2f356SSara Hartse end 83*b2d2f356SSara Hartse 84*b2d2f356SSara Hartse -- We modified the prop, restore old value (if one existed) 85*b2d2f356SSara Hartse if (old_val ~= nil) then 86*b2d2f356SSara Hartse err = zfs.sync.set_prop(fs, prop, old_val) 87*b2d2f356SSara Hartse if (err ~= 0) then return err end 88*b2d2f356SSara Hartse else 89*b2d2f356SSara Hartse -- Didn't have an old value, delete (inherit) instead 90*b2d2f356SSara Hartse err = zfs.sync.inherit(fs, prop) 91*b2d2f356SSara Hartse if (err ~= 0) then return err end 92*b2d2f356SSara Hartse end 93*b2d2f356SSara Hartse end 94*b2d2f356SSara Hartse end 95*b2d2f356SSara Hartseend 96*b2d2f356SSara Hartse 97*b2d2f356SSara Hartse-- Test properties that should fail 98*b2d2f356SSara Hartsefor prop, expected in pairs(neg_props) do 99*b2d2f356SSara Hartse exp_val = expected[1] 100*b2d2f356SSara Hartse exp_err = expected[2] 101*b2d2f356SSara Hartse 102*b2d2f356SSara Hartse -- Attempt to set the property to the specified value 103*b2d2f356SSara Hartse err = zfs.sync.set_prop(fs, prop, exp_val) 104*b2d2f356SSara Hartse if (err == 0 or (exp_err ~= nil and err ~= exp_err)) then 105*b2d2f356SSara Hartse set_fail[prop] = err -- tuple of prop, val that resulted in error 106*b2d2f356SSara Hartse end 107*b2d2f356SSara Hartseend 108*b2d2f356SSara Hartse 109*b2d2f356SSara Hartsereturn {set_fail, val_fail} 110