From patchwork Fri Aug 14 01:06:45 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Verma, Vishal L" X-Patchwork-Id: 7011681 Return-Path: X-Original-To: patchwork-linux-nvdimm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7DBC59F434 for ; Fri, 14 Aug 2015 01:06:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3320E207C2 for ; Fri, 14 Aug 2015 01:06:57 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8DF1A207BF for ; Fri, 14 Aug 2015 01:06:55 +0000 (UTC) Received: from ml01.vlan14.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 59792182B0B; Thu, 13 Aug 2015 18:06:55 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by ml01.01.org (Postfix) with ESMTP id BFE0C182B04 for ; Thu, 13 Aug 2015 18:06:53 -0700 (PDT) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP; 13 Aug 2015 18:06:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,674,1432623600"; d="scan'208";a="541587696" Received: from omniknight.lm.intel.com ([10.232.112.76]) by FMSMGA003.fm.intel.com with ESMTP; 13 Aug 2015 18:06:53 -0700 From: Vishal Verma To: linux-nvdimm@lists.01.org Subject: [ndctl PATCH] ndctl: add a unit test for parent_uuid verification Date: Thu, 13 Aug 2015 19:06:45 -0600 Message-Id: <1439514405-21705-1-git-send-email-vishal.l.verma@intel.com> X-Mailer: git-send-email 2.4.3 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP BTT autodetect should correctly check for the UUID of the parent namespace, and enable the BTT accordingly. This unit test checks for both cases, when a BTT should be correctly autodetected and enabled (matching parent_uuid), and when it shouldn't have been enabled (updated parent_uuid for the namespace). Signed-off-by: Vishal Verma --- Makefile.am | 9 +- builtin-test.c | 6 ++ lib/test-parent-uuid.c | 282 +++++++++++++++++++++++++++++++++++++++++++++++++ test-parent-uuid.h | 4 + 4 files changed, 298 insertions(+), 3 deletions(-) create mode 100644 lib/test-parent-uuid.c create mode 100644 test-parent-uuid.h diff --git a/Makefile.am b/Makefile.am index 070192f..c4fa423 100644 --- a/Makefile.am +++ b/Makefile.am @@ -60,7 +60,7 @@ ndctl_SOURCES = ndctl.c \ util/wrapper.c if ENABLE_TEST -ndctl_SOURCES += lib/test-libndctl.c lib/test-dpa-alloc.c +ndctl_SOURCES += lib/test-libndctl.c lib/test-dpa-alloc.c lib/test-parent-uuid.c endif if ENABLE_DESTRUCTIVE @@ -99,8 +99,8 @@ pkgconfig_DATA = lib/libndctl.pc EXTRA_DIST += lib/libndctl.pc.in CLEANFILES += lib/libndctl.pc -TESTS = lib/test-libndctl lib/test-dpa-alloc -check_PROGRAMS = lib/test-libndctl lib/test-dpa-alloc +TESTS = lib/test-libndctl lib/test-dpa-alloc lib/test-parent-uuid +check_PROGRAMS = lib/test-libndctl lib/test-dpa-alloc lib/test-parent-uuid if ENABLE_DESTRUCTIVE TESTS += lib/test-blk-ns lib/test-pmem-ns @@ -118,3 +118,6 @@ lib_test_pmem_ns_LDADD = lib/libndctl.la -lkmod lib_test_dpa_alloc_SOURCES = lib/test-dpa-alloc.c lib_test_dpa_alloc_LDADD = lib/libndctl.la -luuid -lkmod + +lib_test_parent_uuid_SOURCES = lib/test-parent-uuid.c +lib_test_parent_uuid_LDADD = lib/libndctl.la -luuid -lkmod diff --git a/builtin-test.c b/builtin-test.c index b739924..73a24e0 100644 --- a/builtin-test.c +++ b/builtin-test.c @@ -2,6 +2,7 @@ #include #include #include +#include #include int cmd_test(int argc, const char **argv) @@ -32,5 +33,10 @@ int cmd_test(int argc, const char **argv) rc = test_dpa_alloc(loglevel); fprintf(stderr, "test-dpa-alloc: %s\n", rc ? "FAIL" : "PASS"); + if (rc) + return rc; + + rc = test_parent_uuid(loglevel); + fprintf(stderr, "test-parent-uuid: %s\n", rc ? "FAIL" : "PASS"); return rc; } diff --git a/lib/test-parent-uuid.c b/lib/test-parent-uuid.c new file mode 100644 index 0000000..46e0060 --- /dev/null +++ b/lib/test-parent-uuid.c @@ -0,0 +1,282 @@ +/* + * blk_namespaces: tests functionality of multiple block namespaces + * + * Copyright (c) 2015, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_NDCTL_H +#include +#else +#include +#endif + + +static const char *NFIT_TEST_MODULE = "nfit_test"; +static const char *PROVIDER = "nfit_test.0"; + +static struct ndctl_bus *get_bus_by_provider(struct ndctl_ctx *ctx, + const char *provider) +{ + struct ndctl_bus *bus; + + ndctl_bus_foreach(ctx, bus) + if (strcmp(provider, ndctl_bus_get_provider(bus)) == 0) + return bus; + + return NULL; +} + +static struct ndctl_btt *get_idle_btt(struct ndctl_region *region) +{ + struct ndctl_btt *btt; + + ndctl_btt_foreach(region, btt) + if (!ndctl_btt_is_enabled(btt) + && !ndctl_btt_is_configured(btt)) + return btt; + return NULL; +} + +static struct ndctl_namespace *create_blk_namespace(int region_fraction, + struct ndctl_region *region, unsigned long long req_size, + uuid_t uuid) +{ + struct ndctl_namespace *ndns, *seed_ns = NULL; + unsigned long long size; + + ndctl_namespace_foreach(region, ndns) + if (ndctl_namespace_get_size(ndns) == 0) { + seed_ns = ndns; + break; + } + + if (!seed_ns) + return NULL; + + size = ndctl_region_get_size(region)/region_fraction; + if (req_size) + size = req_size; + + if (ndctl_namespace_set_uuid(seed_ns, uuid) < 0) + return NULL; + + if (ndctl_namespace_set_size(seed_ns, size) < 0) + return NULL; + + if (ndctl_namespace_set_sector_size(seed_ns, 512) < 0) + return NULL; + + if (ndctl_namespace_enable(seed_ns) < 0) + return NULL; + + return seed_ns; +} + +static int disable_blk_namespace(struct ndctl_namespace *ndns) +{ + if (ndctl_namespace_disable(ndns) < 0) + return -ENODEV; + + if (ndctl_namespace_delete(ndns) < 0) + return -ENODEV; + + return 0; +} + +static struct ndctl_btt *check_valid_btt(struct ndctl_region *region, + struct ndctl_namespace *ndns, uuid_t btt_uuid) +{ + struct ndctl_btt *btt = NULL; + ndctl_btt_foreach(region, btt) { + struct ndctl_namespace *btt_ndns; + uuid_t uu; + + ndctl_btt_get_uuid(btt, uu); + if (uuid_compare(uu, btt_uuid) != 0) + continue; + if (!ndctl_btt_is_enabled(btt)) + continue; + btt_ndns = ndctl_btt_get_namespace(btt); + if (strcmp(ndctl_namespace_get_devname(btt_ndns), + ndctl_namespace_get_devname(ndns)) != 0) + continue; + return btt; + } + return NULL; +} + + +static int do_test(struct ndctl_ctx *ctx) +{ + int rc; + struct ndctl_bus *bus; + struct ndctl_btt *btt, *found = NULL; + struct ndctl_region *region, *blk_region; + struct ndctl_namespace *ndns; + unsigned long long ns_size = 18874368; + uuid_t uuid = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16}; + uuid_t btt_uuid; + + bus = get_bus_by_provider(ctx, PROVIDER); + if (!bus) { + fprintf(stderr, "failed to find NFIT-provider: %s\n", PROVIDER); + rc = -ENODEV; + goto err_nobus; + } + + ndctl_region_foreach(bus, region) + if (ndctl_region_get_nstype(region) == ND_DEVICE_NAMESPACE_BLK) { + blk_region = region; + break; + } + + if (!blk_region) { + fprintf(stderr, "failed to find block region\n"); + rc = -ENODEV; + goto err_cleanup; + } + + /* create a blk namespace */ + ndns = create_blk_namespace(1, blk_region, ns_size, uuid); + if (!ndns) { + fprintf(stderr, "failed to create block namespace\n"); + goto err_cleanup; + } + + /* create a btt for this namespace */ + uuid_generate(btt_uuid); + btt = get_idle_btt(region); + if (!btt) + return -ENXIO; + + ndctl_btt_set_uuid(btt, btt_uuid); + ndctl_btt_set_sector_size(btt, 512); + ndctl_btt_set_namespace(btt, ndns); + ndctl_namespace_disable(ndns); + rc = ndctl_btt_enable(btt); + if (rc) { + fprintf(stderr, "failed to create btt 0\n"); + goto err_cleanup; + } + + /* disable the btt */ + ndctl_btt_delete(btt); + + /* re-create the namespace - this should auto-enable the btt */ + disable_blk_namespace(ndns); + ndns = create_blk_namespace(1, blk_region, ns_size, uuid); + if (!ndns) { + fprintf(stderr, "failed to re-create block namespace\n"); + goto err_cleanup; + } + + /* Verify btt was auto-created */ + found = check_valid_btt(blk_region, ndns, btt_uuid); + if (!found) { + rc = -ENXIO; + goto err_cleanup; + } + btt = found; + + /*disable the btt and namespace again */ + ndctl_btt_delete(btt); + disable_blk_namespace(ndns); + + /* recreate the namespace with a different uuid */ + uuid_generate(uuid); + ndns = create_blk_namespace(1, blk_region, ns_size, uuid); + if (!ndns) { + fprintf(stderr, "failed to re-create block namespace\n"); + goto err_cleanup; + } + + /* make sure there is no btt on this namespace */ + found = check_valid_btt(blk_region, ndns, btt_uuid); + if (found) { + fprintf(stderr, "found a stale btt\n"); + rc = -ENXIO; + goto err_cleanup; + } + +err_cleanup: + ndctl_btt_foreach(blk_region, btt) + ndctl_btt_delete(btt); + + ndctl_namespace_foreach(blk_region, ndns) + if (ndctl_namespace_get_size(ndns) != 0) + disable_blk_namespace(ndns); + ndctl_region_foreach(bus, region) + ndctl_region_disable_invalidate(region); + + + err_nobus: + ndctl_unref(ctx); + return rc; +} + +int test_parent_uuid(int loglevel) +{ + struct ndctl_ctx *ctx; + struct kmod_module *mod; + struct kmod_ctx *kmod_ctx; + int err, result = EXIT_FAILURE; + + err = ndctl_new(&ctx); + if (err < 0) + exit(EXIT_FAILURE); + + ndctl_set_log_priority(ctx, loglevel); + + kmod_ctx = kmod_new(NULL, NULL); + if (!kmod_ctx) + goto err_kmod; + + err = kmod_module_new_from_name(kmod_ctx, NFIT_TEST_MODULE, &mod); + if (err < 0) + goto err_module; + + err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, + NULL, NULL, NULL, NULL); + if (err < 0) + goto err_module; + + err = do_test(ctx); + if (err == 0) + result = EXIT_SUCCESS; + kmod_module_remove_module(mod, 0); + +err_module: + kmod_unref(kmod_ctx); +err_kmod: + ndctl_unref(ctx); + return result; +} + +int __attribute__((weak)) main(int argc, char *argv[]) +{ + return test_parent_uuid(LOG_DEBUG); +} diff --git a/test-parent-uuid.h b/test-parent-uuid.h new file mode 100644 index 0000000..57a5ff7 --- /dev/null +++ b/test-parent-uuid.h @@ -0,0 +1,4 @@ +#ifndef __TEST_PARENT_UUID__ +#define __TEST_PARENT_UUID__ +int test_parent_uuid(int loglevel); +#endif