Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(readonly): Adding test cases for uzfs pool readonly support #289

Merged
merged 9 commits into from
Feb 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ typedef enum {
ZPOOL_PROP_TNAME,
ZPOOL_PROP_MAXDNODESIZE,
ZPOOL_PROP_MULTIHOST,
#ifdef _UZFS
ZPOOL_PROP_UZFS_READONLY,
mynktl marked this conversation as resolved.
Show resolved Hide resolved
#endif
ZPOOL_NUM_PROPS
} zpool_prop_t;

Expand Down
3 changes: 3 additions & 0 deletions include/sys/spa_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ struct spa {
taskq_t *spa_prefetch_taskq; /* Taskq for prefetch threads */
uint64_t spa_multihost; /* multihost aware (mmp) */
mmp_thread_t spa_mmp; /* multihost mmp thread */
#ifdef _UZFS

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we hadn't touched spa till now.. may be we never got that need.. can we also explore different way? if not possible, this is fine

boolean_t readonly; /* pool is readonly or not */
#endif

/*
* spa_refcount & spa_config_lock must be the last elements
Expand Down
5 changes: 5 additions & 0 deletions module/zcommon/zpool_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ zpool_prop_init(void)
PROP_DEFAULT, ZFS_TYPE_POOL, "<file> | none", "CACHEFILE");
zprop_register_string(ZPOOL_PROP_COMMENT, "comment", NULL,
PROP_DEFAULT, ZFS_TYPE_POOL, "<comment-string>", "COMMENT");
#ifdef _UZFS
zprop_register_string(ZPOOL_PROP_UZFS_READONLY, "io.openebs:readonly",
"", PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "ZPOOL_READONLY");
#endif


/* readonly number properties */
zprop_register_number(ZPOOL_PROP_SIZE, "size", 0, PROP_READONLY,
Expand Down
71 changes: 71 additions & 0 deletions module/zfs/spa.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
#include <sys/zvol.h>
#ifdef _UZFS
#include <uzfs_mgmt.h>
#include <uzfs_prop.h>
#endif
#ifdef _KERNEL
#include <sys/fm/protocol.h>
Expand Down Expand Up @@ -635,7 +636,17 @@ spa_prop_validate(spa_t *spa, nvlist_t *props)
intval != 0 && intval < ZIO_DEDUPDITTO_MIN)
error = SET_ERROR(EINVAL);
break;
#ifdef _UZFS
case ZPOOL_PROP_UZFS_READONLY:
if ((error = nvpair_value_string(elem, &strval)) != 0)
break;

if (strcmp(strval, "on") != 0 &&
strcmp(strval, "off") != 0) {
error = SET_ERROR(EINVAL);
}
mynktl marked this conversation as resolved.
Show resolved Hide resolved
break;
#endif
default:
break;
}
Expand Down Expand Up @@ -688,6 +699,10 @@ spa_prop_set(spa_t *spa, nvlist_t *nvp)
int error;
nvpair_t *elem = NULL;
boolean_t need_sync = B_FALSE;
#ifdef _UZFS
char *val;
boolean_t update_rdonly = B_FALSE;
#endif

if ((error = spa_prop_validate(spa, nvp)) != 0)
return (error);
Expand Down Expand Up @@ -729,6 +744,34 @@ spa_prop_set(spa_t *spa, nvlist_t *nvp)
continue;
}

#ifdef _UZFS
if (prop == ZPOOL_PROP_UZFS_READONLY) {
VERIFY(nvpair_value_string(elem, &val) == 0);
if (strcmp(val, "on") == 0) {
if (!spa->readonly) {
update_rdonly = B_TRUE;
spa->readonly = B_TRUE;
}
} else if (strcmp(val, "off") == 0) {
if (spa->readonly) {
update_rdonly = B_TRUE;
spa->readonly = B_FALSE;
}
} else {
return (EINVAL);
}
if (update_rdonly) {
fprintf(stderr, "Updating readonly for %s "
"to %s\n", spa->spa_name, val);
dmu_objset_find(spa->spa_name,
uzfs_zpool_rdonly_cb, val,
DS_FIND_CHILDREN);
need_sync = B_TRUE;
}
continue;
}
mynktl marked this conversation as resolved.
Show resolved Hide resolved
#endif

need_sync = B_TRUE;
break;
}
Expand Down Expand Up @@ -2141,6 +2184,31 @@ spa_load_verify(spa_t *spa)
return (verify_ok ? 0 : EIO);
}

#ifdef _UZFS
static void
uzfs_get_readonly_prop(spa_t *spa)
{
char val[4]; // max strlen("off")
int err;

err = zap_lookup(spa->spa_meta_objset, spa->spa_pool_props_object,
zpool_prop_to_name(ZPOOL_PROP_UZFS_READONLY), 1,
sizeof (val), &val);
if (err) {
// ignore error if value doesn't exist
return;
}

if (strcmp(val, "on") == 0) {
spa->readonly = B_TRUE;
} else if (strcmp(val, "off") == 0) {
spa->readonly = B_FALSE;
}
fprintf(stderr, "pool %s imported with readonly:%s\n",
spa->spa_name, val);
}
#endif

/*
* Find a value in the pool props object.
*/
Expand Down Expand Up @@ -3094,6 +3162,9 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
spa_prop_find(spa, ZPOOL_PROP_MULTIHOST, &spa->spa_multihost);
spa_prop_find(spa, ZPOOL_PROP_DEDUPDITTO,
&spa->spa_dedup_ditto);
#ifdef _UZFS
uzfs_get_readonly_prop(spa);
#endif

spa->spa_autoreplace = (autoreplace != 0);
}
Expand Down
2 changes: 2 additions & 0 deletions module/zfs/zvol.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ uzfs_ioc_stats(zfs_cmd_t *zc, nvlist_t *nvl)

fnvlist_add_string(innvl, "status",
status_to_str(zv));
fnvlist_add_string(innvl, "readOnly",
IS_ZVOL_READONLY(zv->main_zv) ? "on" : "off");

fnvlist_add_string(innvl, "rebuildStatus",
rebuild_status_to_str(
Expand Down
12 changes: 12 additions & 0 deletions tests/cstor/gtest/gtest_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,18 @@ void GtestUtils::TestPool::pExport() {
execCmd("zpool", std::string("export ") + m_name);
}

bool GtestUtils::TestPool::isReadOnly() {
std::string output;
output = execCmd("zpool", std::string("get -Hp -ovalue io.openebs:readonly ") + m_name);
if (output.compare("on") == 0)
return true;
if (output.compare("off") == 0)
return false;

throw std::system_error(EINVAL, std::system_category(),
"Invalid readonly value:" + output);
}

void GtestUtils::TestPool::createZvol(std::string name, std::string arg /*= ""*/) {
execCmd("zfs",
std::string("create -sV ") + std::to_string(ZVOL_SIZE) +
Expand Down
Loading