From 33218f9966a12f8961f7d7e94307a74328acf928 Mon Sep 17 00:00:00 2001 From: Satbir Singh <34478047+satbirchhikara@users.noreply.github.com> Date: Thu, 16 Aug 2018 17:20:56 +0530 Subject: [PATCH] [TA2330] API to store snapshot IO num when taking snapshot, to retrieve snapshot dataset and IO number from given snapname (#98) Signed-off-by: satbir --- include/mgmt_conn.h | 6 ++++ lib/libzpool/uzfs_rebuilding.c | 1 - lib/libzrepl/mgmt_conn.c | 61 +++++++++++++++++++++++++++++++ tests/cbtest/gtest/test_uzfs.cc | 64 +++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 1 deletion(-) diff --git a/include/mgmt_conn.h b/include/mgmt_conn.h index 46778f2be6d5..917e4d76506d 100644 --- a/include/mgmt_conn.h +++ b/include/mgmt_conn.h @@ -105,6 +105,12 @@ void zinfo_destroy_cb(zvol_info_t *zinfo); void uzfs_zvol_mgmt_thread(void *arg); int finish_async_tasks(void); +int uzfs_zvol_create_snapshot_update_zap(zvol_info_t *zinfo, + char *snapname, uint64_t snapshot_io_num); + +int uzfs_zvol_get_snap_dataset_with_io(zvol_info_t *zinfo, + char *snapname, uint64_t *snapshot_io_num, zvol_state_t **snap_zv); + #ifdef __cplusplus } #endif diff --git a/lib/libzpool/uzfs_rebuilding.c b/lib/libzpool/uzfs_rebuilding.c index c6872172e788..8404e3685093 100644 --- a/lib/libzpool/uzfs_rebuilding.c +++ b/lib/libzpool/uzfs_rebuilding.c @@ -356,7 +356,6 @@ uzfs_zvol_create_snaprebuild_clone(zvol_state_t *zv, if (ret != 0) { LOG_ERR("Failed to get info about %s@%s", zv->zv_name, REBUILD_SNAPSHOT_SNAPNAME); - strfree(snapname); return (ret); } diff --git a/lib/libzrepl/mgmt_conn.c b/lib/libzrepl/mgmt_conn.c index 8110ea9c3565..c3a161b35751 100644 --- a/lib/libzrepl/mgmt_conn.c +++ b/lib/libzrepl/mgmt_conn.c @@ -598,6 +598,67 @@ finish_async_tasks(void) return (rc); } +/* + * Take a snapshot and update snapshot IO to ZAP. + */ +int +uzfs_zvol_create_snapshot_update_zap(zvol_info_t *zinfo, + char *snapname, uint64_t snapshot_io_num) +{ + int ret = 0; + + if (uzfs_zvol_get_status(zinfo->zv) != ZVOL_STATUS_HEALTHY) { + return (ret = -1); + } + + if (zinfo->running_ionum > snapshot_io_num -1) + return (ret = -1); + + mutex_enter(&zvol_list_mutex); + + uzfs_zvol_store_last_committed_io_no(zinfo->zv, + snapshot_io_num -1); + zinfo->checkpointed_ionum = snapshot_io_num -1; + zinfo->checkpointed_time = time(NULL); + + mutex_exit(&zvol_list_mutex); + ret = dmu_objset_snapshot_one(zinfo->name, snapname); + return (ret); +} + +/* + * For a given snap name, get snap dataset and IO number stored in ZAP + * Input: zinfo, snap + * Output: snapshot_io_num, snap_zv + */ +int +uzfs_zvol_get_snap_dataset_with_io(zvol_info_t *zinfo, + char *snapname, uint64_t *snapshot_io_num, zvol_state_t **snap_zv) +{ + int ret = 0; + + char *longsnap = kmem_asprintf("%s@%s", + strchr(zinfo->name, '/') + 1, snapname); + ret = uzfs_open_dataset(zinfo->zv->zv_spa, longsnap, snap_zv); + if (ret != 0) { + LOG_ERR("Failed to get info about %s", longsnap); + strfree(longsnap); + return (ret); + } + + strfree(longsnap); + ret = uzfs_hold_dataset(*snap_zv); + if (ret != 0) { + LOG_ERR("Failed to hold snapshot: %d", ret); + uzfs_close_dataset(*snap_zv); + *snap_zv = NULL; + return (ret); + } + + (*snapshot_io_num) = uzfs_zvol_get_last_committed_io_no(*snap_zv); + return (ret); +} + /* * Perform the command (in async context). * diff --git a/tests/cbtest/gtest/test_uzfs.cc b/tests/cbtest/gtest/test_uzfs.cc index f90195b8ec2e..d86427e258fc 100644 --- a/tests/cbtest/gtest/test_uzfs.cc +++ b/tests/cbtest/gtest/test_uzfs.cc @@ -1317,3 +1317,67 @@ TEST(SnapRebuild, CloneReCreateFailure) { EXPECT_EQ(0, uzfs_zvol_destroy_snaprebuild_clone(zinfo->zv, snap_zv)); } + +uint64_t snapshot_io_num = 1000; +char *snapname = (char *)"hello_snap"; + +/* Snap create failure */ +TEST(SnapCreate, SnapCreateFailureHigherIO) { + + /* + * By default volume state is marked downgraded + * so updation of ZAP attribute would fail + */ + uzfs_zvol_set_rebuild_status(zinfo->zv, ZVOL_REBUILDING_INIT); + uzfs_zvol_set_status(zinfo->zv, ZVOL_STATUS_DEGRADED); + + zinfo->running_ionum = snapshot_io_num + 1; + /* Create snapshot */ + EXPECT_EQ(-1, uzfs_zvol_create_snapshot_update_zap(zinfo, + snapname, snapshot_io_num)); +} + +/* Snap create failure */ +TEST(SnapCreate, SnapCreateFailure) { + + /* + * By default volume state is marked downgraded + * so updation of ZAP attribute would fail + */ + uzfs_zvol_set_rebuild_status(zinfo->zv, ZVOL_REBUILDING_INIT); + uzfs_zvol_set_status(zinfo->zv, ZVOL_STATUS_DEGRADED); + + zinfo->running_ionum = snapshot_io_num -1; + /* Create snapshot */ + EXPECT_EQ(-1, uzfs_zvol_create_snapshot_update_zap(zinfo, + snapname, snapshot_io_num)); +} + +/* Snap create success */ +TEST(SnapCreate, SnapCreateSuccess) { + + /* + * Set volume state to healthy so that we can + * upsate ZAP attribute and take snapshot + */ + uzfs_zvol_set_rebuild_status(zinfo->zv, ZVOL_REBUILDING_DONE); + uzfs_zvol_set_status(zinfo->zv, ZVOL_STATUS_HEALTHY); + + zinfo->running_ionum = snapshot_io_num -1; + /* Create snapshot */ + EXPECT_EQ(0, uzfs_zvol_create_snapshot_update_zap(zinfo, + snapname, snapshot_io_num)); +} + +/* Retrieve Snap dataset and IO number */ +TEST(SnapCreate, SnapRetrieve) { + + uint64_t io = 0; + zvol_state_t *snap_zv = NULL; + + /* Create snapshot */ + EXPECT_EQ(0, uzfs_zvol_get_snap_dataset_with_io(zinfo, + snapname, &io, &snap_zv)); + + EXPECT_EQ(snapshot_io_num -1, io); +}